完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
电子发烧友论坛|
STM32的串口发送和接收都相对简单,这里自定义了一种串口协议,可以根据这串口协议扩充添加其他功能,原理大家可以查手册或其他介绍,这里直接给代码,代码里有详细注释;
1)编译器IAR8,系统win10; 2)板子:STM32F103C8T6核心板,如下: 3)下载器:ST-LINK/V2仿真下载器; 4)串口连接器用的是USB-TTL下载器,其用的是PL2303芯片,所以要下再驱动;在网上下载安装了好几种最终这个安装成功:WIN10_ PL2303_USB-to-Serial Comm Port;网盘链接 5)stm32f103源码和QT源码 6)板子上LED对应的引脚是GPIOC, GPIO_Pin_13;在IAR对应的stm32F103X模板DRIVER目录下添加:led.c,led.h,timer.c,timer.h,usart.c,usart.h文件,主要串口代码,usart.c,usart.h中,截图如下: led.h #ifndef _LED_H #define _LED_H /*包含相关的头文件*/ #include "stm32f10x.h" #include "stm32f10x_gpio.h" #include "stm32f10x_rcc.h" void led_gpio_config(void);//声明,初始化LED对应引脚 #endif led.c #include "led.h" /*LED_G 驱动 GPIO 初始化函数*/ void led_gpio_config(void) { GPIO_InitTypeDef GPIO_InitStructure; //调用GPIO结构体 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //配置RCC时钟,使得引脚使能 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_13; //设置的引脚 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; //设置引脚速度 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //设置引脚模式,推挽式输出 GPIO_Init(GPIOC, &GPIO_InitStructure); //初始化引脚 } timer.h #ifndef __TIMER_H_ #define __TIMER_H_ #include "stm32f10x_tim.h" #include "stm32f10x_rcc.h" #include "stm32f10x_it.h" #include "misc.h" extern __IO uint32_t TimingDelay; //计数变量,加要加“_IO”,不然会被编译优化 void Systick_Init(void); //初始化系统滴答 void TimingDelay_Decrement(void); //计数函数 void delay_ms(__IO uint32_t nTime);//延迟函数,设置为 US extern __IO uint32_t TimingDelay2; //计数变量2 void tim2_nvic_config(void); //初始化中断 void tim2_config(void); //初始化计数器 void delay_ms2(__IO uint32_t nTime2);//延迟函数2,设置为 US void TimingDelay_Decrement2(void); //计数函数2 #endif tiemr.c #include "timer.h" __IO uint32_t TimingDelay; //计数变量,加要加“_IO”,不然会被编译优化 __IO uint32_t TimingDelay2; //计数变量2 /*SystemCoreClock / 1000000 ------- 1us*/ /*SystemCoreClock / 100000 ------- 10us*/ /*SystemCoreClock / 10000 ------- 100us*/ /*SystemCoreClock / 1000 ------- 1ms*/ // //设置系统滴答中断延时程序// / void Systick_Init(void) { //装载系统时钟中断计数值,系统时钟累计达到72000时候溢出产生中断 if (SysTick_Config(72000)) { /* Capture error */ while (1); } } //延时计数函数,如果不是0,每个系统滴答中断周期自减 void TimingDelay_Decrement(void) { if (TimingDelay != 0x00) { TimingDelay--; } } //延迟函数,设置为 US void delay_ms(__IO uint32_t nTime) { TimingDelay = nTime;//自减初始值 while(TimingDelay != 0); } //中断事件函数,原函数在stm32f10x_it.c里面,复制到这里后要将原位置里的注释掉,不然报错 void SysTick_Handler(void) { TimingDelay_Decrement(); } // //设置定时器中断延时程序// / //配置嵌套中断控制器 NVCI void tim2_nvic_config(void) { NVIC_InitTypeDef NVIC_Init_Struct; //调用NVCI结构体 NVIC_PriorityGroupConfig(NVIC_PriorityGroup_0); //设置组优先级 NVIC_Init_Struct.NVIC_IRQChannel = TIM2_IRQn; //设置定时器 2 中断 NVIC_Init_Struct.NVIC_IRQChannelPreemptionPriority = 0; //设置抢占优先级 NVIC_Init_Struct.NVIC_IRQChannelSubPriority = 0; //设置子优先级 NVIC_Init_Struct.NVIC_IRQChannelCmd = ENABLE; //使能IRQ中断 NVIC_Init(&NVIC_Init_Struct); //初始化NVIC } //定时器初始化配置 void tim2_config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStruct; //调用定时器结构体 tim2_nvic_config(); //加载嵌套中断控制器 NVCI RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //配置RCC时钟,使得中断使能 TIM_DeInit(TIM2); //将外设 TIMx 寄存器重设为缺省值,复位寄存器 /* 定时计数计算方法如下: 发生中断时间 = (TIM_Prescaler+1)* (TIM_Period+1)/FLK 以定时 1s 为例 TIM_Period=2000-1, TIM_Prescaler=(36000-1) */ TIM_TimeBaseInitStruct.TIM_Prescaler = 36000-1; //时钟预先分频数 TIM_TimeBaseInitStruct.TIM_Period = 2-1; //自动重装载寄存器的值 TIM_TimeBaseInitStruct.TIM_CounterMode = TIM_CounterMode_Up; //计数模式,向上计数方式 TIM_TimeBaseInitStruct.TIM_ClockDivision = TIM_CKD_DIV1; //采样分频 TIM_TimeBaseInit(TIM2, &TIM_TimeBaseInitStruct); //初始化TIM2配置 TIM_ClearFlag(TIM2,TIM_FLAG_Update); //清除溢出中断标志 TIM_ITConfig(TIM2,TIM_IT_Update,ENABLE); //使能或者失能指定的 TIM 中断 TIM_Cmd(TIM2,ENABLE); //开启时钟 } //延时计数函数2,如果不是0,每个系统滴答中断周期自减 void TimingDelay_Decrement2(void) { if (TimingDelay2 != 0x00) { TimingDelay2--; } } //延迟函数,设置为 US void delay_ms2(__IO uint32_t nTime2) { TimingDelay2 = nTime2;//时钟滴答数 while(TimingDelay2 != 0); } //定时器2,中断事件函数 void TIM2_IRQHandler(void) { if(TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)//固件库函数,判断是否发生TIM2中断 { TimingDelay_Decrement2(); //调用延时计数函数 } TIM_ClearITPendingBit(TIM2,TIM_FLAG_Update);//标志位清除,固件库函数 } usart.h//关键代码 #ifndef __USART_H_ #define __USART_H_ #include "stm32f10x.h" #include "stm32f10x_rcc.h" #include "stm32f10x_gpio.h" #include "stm32f10x_usart.h" #define UNLOCK 0x00 //宏定义 串口flag,开 #define LOCK 0xff //宏定义 串口flag,关 void usart_config(void); //串口初始化函数 void rx_stack_init(void); //串口协议栈接收初始化 void tx_stack_init(void); //串口协议栈发送初始化 void rx_stack_data_deal(void);//串口接收数据处理 void tx_stack_data_deal(void);//串口发送数据处理 //串口发送协议栈 typedef struct { u8 head; //头 u8 direction; //流向 u8 data[4]; //数据 u8 tail; //尾部 } ptl_stack; //串口接收协议栈 typedef struct { u8 head; //头 u8 direction;//流向 u8 data[4]; //数据 u8 tail; //尾部 u8 data_pt; //数据位 u8 lock_flag; //接收满标志位 } ptr_stack; #endif usart.c #include "usart.h" #include "led.h" ptl_stack tx_stack; //声明串口协议栈结构体 ptr_stack rx_stack; //声明串口协议栈结构体 void usart_config(void) { /*1、打开GPIO,AFIO,USART1的时钟*/ RCC_APB2PeriphClockCmd( RCC_APB2Periph_USART1 |RCC_APB2Periph_GPIOA | RCC_APB2Periph_AFIO, ENABLE); /*2初始化相应的串口引脚*/ GPIO_InitTypeDef GPIO_InitStruct; /* 配置相应的 GPIO 口; USART1 对应的复用引脚为 PA9 和 PA10, PA9 对应的是 TXD, PA10 对应得实 RXD */ /*配置PA9为复用推挽输出*/ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_9; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); /*配置PA10为浮空输入*/ GPIO_InitStruct.GPIO_Pin = GPIO_Pin_10; GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStruct); /*3、配置串口中断*/ NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; //设置串口 1 中断 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; //抢占优先级0 NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0; //子优先级为 0 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //使能 NVIC_Init(&NVIC_InitStructure); /*4、配置串口模式*/ USART_InitTypeDef USART_InitStruct;//串口初始化结构图 USART_InitStruct.USART_BaudRate = 9600;//波特率 USART_InitStruct.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件控制流 USART_InitStruct.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;//发送和接收模式打开 USART_InitStruct.USART_WordLength = USART_WordLength_8b; //数据位8 USART_InitStruct.USART_Parity = USART_Parity_No; //n,无校验位 USART_InitStruct.USART_StopBits = USART_StopBits_1; //停止位1 USART_Init(USART1, &USART_InitStruct);//配置串口参数函数 USART_ClearFlag(USART1,USART_FLAG_TC); //清除发送完成标志位 USART_Cmd(USART1, ENABLE); //使能串口 1 USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//使能接收中断 } //初始化接收变量 void rx_stack_init(void) { u8 i; rx_stack.head = 0; rx_stack.direction = 0; for(i = 0; i <=3; i++) { rx_stack.data = 0; } rx_stack.data_pt = 0; rx_stack.tail = 0; rx_stack.lock_flag =0; //UNLOCK; // usart_config(); } //初始化发送变量 void tx_stack_init(void) { u8 i; tx_stack.head = 0xaa;//头 tx_stack.direction = 0xf0;//f0代表单片机发送电脑,f9代表电脑发送单片机 for(i = 0; i <=3; i++) { tx_stack.data = 0x00;//数据初始化 } tx_stack.tail = 0xdd;//尾部 // usart_config(); } |
|
|
|
|
|
//串口中断处理函数
void USART1_IRQHandler(void) { u8 receive_data;//接收存储变量 if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)//如果不是空 { receive_data = USART_ReceiveData(USART1); //接收单个字节的串口数据 // USART_SendData(USART1,receive_data);//将接收的发送 if(rx_stack.lock_flag == UNLOCK) //如果未锁住,则没有接收完成 { if(receive_data == 0xaa) //如果头等于aa,则接收 { rx_stack.head = receive_data; //接收头数据 } else if(receive_data == 0xf9) //方向判断 { rx_stack.direction = receive_data; //接收方向 } else if(receive_data == 0xdd) //尾部判断 { rx_stack.tail = receive_data; //接收尾部 } else { //数据处理,存储,data_pt数据指针数 rx_stack.data[rx_stack.data_pt] = receive_data; rx_stack.data_pt ++;//储存后下移动 } //如果数据接收满,且到达尾部,则锁住,不接收,待接收完毕后解锁 if((rx_stack.data_pt >= 4) && (rx_stack.tail == 0xdd)) { rx_stack.lock_flag = LOCK;//锁住数据 } } } USART_ClearITPendingBit(USART1, USART_IT_RXNE); } void rx_stack_data_deal(void)//串口接收数据解析 { for(u8 i = 0; i <=3; i++) { tx_stack.data = rx_stack.data; } tx_stack_data_deal();//发送数据 rx_stack_init(); rx_stack.lock_flag = UNLOCK;//初始化 } void tx_stack_data_deal(void)//串口发送数据处理 { u8 i; USART_SendData(USART1,tx_stack.head);//发送头 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//等待发送完成 USART_SendData(USART1, tx_stack.direction); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//等待发送完成 for(i = 0; i <= 3; i++)//遍历数据并发送 { USART_SendData(USART1, tx_stack.data); while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//等待发送完成 } USART_SendData(USART1, tx_stack.tail);//发送尾部 while(USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);//等待发送完成 } //void USART1_IRQHandler(void)//不走协议时候 //{ // u8 receive_data; // if(USART_GetITStatus(USART1,USART_IT_RXNE))// // { // receive_data= USART_ReceiveData(USART1);//接收 // USART_SendData(USART1,receive_data);//将接收的发送 // } // //} main.c #include "led.h" #include "timer.h" #include "usart.h" extern ptl_stack tx_stack;//串口发送变量声明 extern ptr_stack rx_stack;//串口接收变量声明 int main(void) { SystemInit(); //初始化系统时钟 Systick_Init(); //配置系统时钟滴答参数 led_gpio_config(); //配置GPIO tim2_config();//配置定时器 usart_config();//初始化串口 tx_stack_init();//初始化发送缓冲区 rx_stack_init();//初始化接收缓冲区 while(1) { // //调用系统滴答延时函数做LED灯的闪烁// // GPIO_SetBits(GPIOC, GPIO_Pin_13); //将PB13设置成高电平 // delay_ms(100); //调用系统滴答延时函数 // GPIO_ResetBits(GPIOC, GPIO_Pin_13); //将PB13设置成低电平 // delay_ms(100); //调用系统滴答延时函数 //调用定时器延时函数做LED灯闪烁// GPIO_SetBits(GPIOC, GPIO_Pin_13); //将PB13设置成高电平 delay_ms2(500); //调用定时器延时函数 GPIO_ResetBits(GPIOC, GPIO_Pin_13); //将PB13设置成低电平 delay_ms2(220); //调用定时器延时函数 // USART_SendData(USART1,0xff); delay_ms(100); // tx_stack.data[0]=0x01; // tx_stack.data[1]=0x02; // tx_stack.data[2]=0x03; // tx_stack.data[3]=0x04; // tx_stack_data_deal();//串口发送数据处理 if(rx_stack.lock_flag == LOCK) // 接受满 { rx_stack_data_deal();//运行协议解析函数 } } return 0; } 下面是QT上位机的源码,主要文件如下: |
|
|
|
|
|
mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include #include #include #include "usart.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); ~MainWindow(); private slots: void ReadData(); void on_pushButton_clicked(); void on_pushButton_2_clicked(); private: Ui::MainWindow *ui; QSerialPort *serial; }; #endif // MAINWINDOW_H mainwindow.cpp #include "mainwindow.h" #include "ui_mainwindow.h" #include #include #include "usart.h" #pragma execution_character_set("utf-8") extern ptl_stack tx_stack; extern ptr_stack rx_stack; MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) { ui->setupUi(this); //设置下拉菜单,波特率 ui->comboBox_2->addItem("1200"); ui->comboBox_2->addItem("2400"); ui->comboBox_2->addItem("4800"); ui->comboBox_2->addItem("9600"); ui->comboBox_2->addItem("19200"); ui->comboBox_3->addItem("8"); ui->comboBox_4->addItem("0"); ui->comboBox_5->addItem("1"); ui->comboBox_5->addItem("2"); //设置波特率下拉菜单默认显示第0项 ui->comboBox_2->setCurrentIndex(3); //查找可用的串口 foreach (const QSerialPortInfo &info,QSerialPortInfo::availablePorts()) { QSerialPort serial; serial.setPort(info); if(serial.open(QIODevice::ReadWrite)) { ui->comboBox->addItem(serial.portName()); serial.close(); } } } MainWindow::~MainWindow() { delete ui; } void MainWindow::on_pushButton_clicked() { if(ui->pushButton->text()==tr("打开串口")) { serial=new QSerialPort; serial->setPortName(ui->comboBox->currentText());//设置串口名称 serial->open(QIODevice::ReadWrite);//打开串口 //设置波特率 // serial->setBaudRate(QSerialPort::Baud4800); switch (ui->comboBox_2->currentIndex()) { case 0: serial->setBaudRate(QSerialPort::Baud1200); break; case 1: serial->setBaudRate(QSerialPort::Baud2400); break; case 2: serial->setBaudRate(QSerialPort::Baud4800); break; case 3: serial->setBaudRate(QSerialPort::Baud9600); break; case 4: serial->setBaudRate(QSerialPort::Baud19200); break; default: break; } //设置校验位 switch (ui->comboBox_4->currentIndex()) { case 0: serial->setParity(QSerialPort::NoParity); break; default: break; } //设置停止位 switch (ui->comboBox_5->currentIndex()) { case 1: serial->setStopBits(QSerialPort::OneStop);//停止位设置为1 break; case 2: serial->setStopBits(QSerialPort::TwoStop);// break; default: break; } //设置流控制 serial->setFlowControl(QSerialPort::NoFlowControl);//设置为无流控制 ui->comboBox->setEnabled(false); ui->comboBox_2->setEnabled(false); ui->comboBox_3->setEnabled(false); ui->comboBox_4->setEnabled(false); ui->comboBox_5->setEnabled(false); ui->pushButton->setText(tr("关闭串口")); } else { //关闭串口 serial->clear(); serial->close(); serial->deleteLater(); ui->comboBox->setEnabled(true); ui->comboBox_2->setEnabled(true); ui->comboBox_3->setEnabled(true); ui->comboBox_4->setEnabled(true); ui->comboBox_5->setEnabled(true); ui->pushButton->setText(tr("打开串口")); } //连接信号槽 QObject::connect(serial,&QSerialPort::readyRead,this,&MainWindow::ReadData); } //读取接收到的信息 void MainWindow::ReadData() { QByteArray buf; //二进制 buf=serial->readAll();//读取串口数据,注意,返回的并不是一帧一帧的,需要处理 if(!buf.isEmpty()) ///接收处理函数 { for(int i=0;i QByteArray buf_rx=buf.mid(i,1);//每次取i后一个字节 bool ok;//函数需要 rx_stack_data_deal((quint8)buf_rx[0]);//解析串口函数,强制转换即可quint8=unsigned char; // qDebug() <<"强制转换数据:"<<(quint8)buf_rx[0]; } } QString buffer_1;//存储 if(!buf.isEmpty())//在电脑ui中显示数据 { QString str=buf.toHex().data();//hex为16进制数 str=str.toUpper();//转换成大写 for(int i=0;i QString str_1 = str.mid (i,2);//每次取i后两个字节 buffer_1 += str_1;//转换二进制 buffer_1 += " ";//后面加空 } QString receive = ui->textEdit->toPlainText();//读取ui之前显示数据 ui->textEdit->clear(); //清空显示 receive += QString(buffer_1); //叠加 ui->textEdit->append(receive);//重新显示 buffer_1.clear(); } buf.clear();//清空 } //发送按钮槽函数 void MainWindow::on_pushButton_2_clicked() { if(ui->pushButton->text()=="关闭串口") { // serial->write(ui->lineEdit->text().toLatin1().append("/")); // //Latin1是ISO-8859-1的别名,单片机仅能识别ASCII码 // serial->write(ui->lineEdit->text().toLatin1()); // //Latin1是ISO-8859-1的别名,单片机仅能识别ASCII码 //test // QString tmp=ui->lineEdit->text().toUtf8(); // qDebug() <<"utf8: "< // // QByteArray bax; //二进制 实验 // bax[0]=0xaa; // bax[1]=0xf9; // bax[2]=0xff; // bax[3]=0x02; // bax[4]=0x03; // bax[5]=0x04; // bax[6]=0xdd; // serial->write(bax);//串口发送数据 // qDebug() <<"发送数据:"< QByteArray bax2; //二进制 tx_stack_data_deal();//调取usart.cpp函数初始化数据 //以下为数据,用append顺序不能乱,append是在末尾添加 bax2.append(tx_stack.head);//发送头 bax2.append(tx_stack.direction);//发送流向 bax2.append(tx_stack.data[0]);//发数据0 bax2.append(tx_stack.data[1]);//发数据1 bax2.append(tx_stack.data[2]);//发数据2 bax2.append(tx_stack.data[3]);//发数据3 bax2.append(tx_stack.tail);//发尾部 serial->write(bax2);//串口发送数据 qDebug() <<"发送数据16进制:"< ui->lineEdit->clear();//清空控件数据 } else { ui->pushButton_2->setEnabled(true); QMessageBox::about(NULL, "提示", "串口未打开"); } } usart.h #ifndef USART_H #define USART_H typedef unsigned char u8;//与单片机统一 #define UNLOCK 0x00 //宏定义 串口flag,开 #define LOCK 0xff //宏定义 串口flag,关 void rx_stack_init(void);//初始化接收串口函数 void tx_stack_init(void);//初始化发送串口函数 void rx_stack_data_deal(u8 receive_data);//串口接收数据处理 void tx_stack_data_deal(void);//串口接收数据处理 //串口发送协议栈 typedef struct { u8 head; //头 u8 direction;//流向 u8 data[4]; //数据 u8 tail; //尾部 } ptl_stack; //串口接收协议栈 typedef struct { u8 head;//头 u8 direction;//流向 u8 data[4];//数据 u8 tail;//尾部 u8 data_pt;//记录数据指针位 u8 lock_flag;//接收满标志位,上位机不需要中断锁住 } ptr_stack; #endif // USART_H usart.cpp #include "usart.h" #include ptl_stack tx_stack; ptr_stack rx_stack; void rx_stack_init(void) { u8 i; rx_stack.head = 0; rx_stack.direction = 0; for(i = 0; i <=3; i++) { rx_stack.data = 0; } rx_stack.data_pt = 0; rx_stack.tail = 0; rx_stack.lock_flag = UNLOCK; } void tx_stack_init(void) { u8 i; tx_stack.head = 0xaa; tx_stack.direction = 0x09; for(i = 0; i <=3; i++) { tx_stack.data = 0x00; } tx_stack.tail = 0xdd; } void rx_stack_data_deal(u8 receive_data) { if(rx_stack.lock_flag == UNLOCK) //如果未锁住,则没有接收完成 { if(receive_data == 0xaa) //如果头等于aa,则接收 { rx_stack.head = receive_data; //接收头数据 QByteArray b; qDebug() <<"我收到head:"<< rx_stack.head;//b.append(rx_stack.head).toHex();//二进制强制转换char ? } else if(receive_data == 0xf0) //方向判断f9是电脑发送到单片机,f0代表单片机发送 { rx_stack.direction = receive_data; //接收方向 QByteArray b; qDebug() <<"我收到direction:"< else if(receive_data == 0xdd) //尾部判断 { rx_stack.tail = receive_data; //接收尾部 QByteArray b; qDebug() <<"我收到tail :"<< b.setNum(rx_stack.tail,16);//二进制强制转换char ? } else { //数据处理,存储 rx_stack.data[rx_stack.data_pt] = receive_data;// QByteArray b; qDebug() <<"deal1 data:"<< b.setNum(rx_stack.data[rx_stack.data_pt], 16);//二进制强制转换char ? rx_stack.data_pt ++; } //如果数据接收满,且到达尾部,清空 if((rx_stack.data_pt >= 4) && (rx_stack.tail == 0xdd)) { rx_stack.lock_flag = LOCK;//锁住数据 tx_stack_data_deal(); } } } void tx_stack_data_deal(void)//串口发送数据处理 { ///此处可添加其他解析函数/// tx_stack.head = 0xaa;//设置头 tx_stack.direction = 0xf9; tx_stack.data[0] = 0x1a; tx_stack.data[1] = 0x2b; tx_stack.data[2] = 0x3c; tx_stack.data[3] = 0x4d; tx_stack.tail = 0xdd; rx_stack.lock_flag = UNLOCK;//锁住数据 rx_stack_init();//清空,不然数据叠加有错误 } 效果如下: |
|
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
4130 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
3221 浏览 1 评论
2747 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
2175 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
14939 浏览 2 评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
3084浏览 4评论
stm32f4下spi+dma读取数据不对是什么原因导致的?
1894浏览 3评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
2064浏览 3评论
1976浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
2165浏览 3评论
/9
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2025-12-2 00:41 , Processed in 1.298456 second(s), Total 76, Slave 59 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191

淘帖
2390