比Nappa还高级的真皮座椅?听说只在百万级豪车上使用 苯胺皮和纳帕皮是区别
2023-10-14
很多朋友对嵌入式串口调试连接,嵌入式开发之UART串口通信解析不是很了解,每日小编刚好整理了这方面的知识,今天就来带大家一探究竟。
UART串口是嵌入式开发中常见的通信方式,但是很多人还不知道串口如何使用。
今天我们重点关注串口,简单分享一下几点:
串口接收方式
处理接收到的数据
通信协议分析
串口接收方式
从串口(通信的另一端)接收数据的常见方式是:
轮询(查询)接收寄存器
中断接收数据
轮询是指按照一定的时间间隔(通常是ms,甚至us)检查接收寄存器中是否有数据。如果有数据,则处理接收到的数据。
中断,当没有收到数据时,CPU做自己的事情。当接收到数据时,UART串口控制器会响应中断,通知CPU有事情要做。
您有没有想过轮询方式的缺点?
效率低:CPU大部分时间都在做查询工作;
响应不实时:如果短时间内有多个接收到的数据,CPU正在处理一件比较耗时的事情(例如:发送数据包),没有时间去查询接收到的数据数据。此时,数据可能会丢失。 (特别是早些年串口还没有FIFO功能)
因此,无论是UART串口,还是I2C、SPI、CAN等串行通信,最常用的是中断接收,很少使用轮询。
我曾经维护旧代码(一个陷阱)。 CLI串口采用轮询模式。出现了很多数据丢失、溢出错误等问题,让我加班了几个小时。
处理接收到的数据
中断数据来了,如何处理接收到的数据?
我见过一些小项目,有些应用是直接在中断函数中完成的。例如:串口中断接收来自传感器的数据,显示数据并执行一些响应动作。
对于中断函数来说,代码可以尽可能小,耗时也可以尽可能小,不能处理太多耗时且复杂的逻辑、应用程序等。
数据到来时的中断通常通过FIFO 进行处理。
1.简单的数组接收、应用解析和处理
例如:
static uint8_t gRxCnt=0;static uint8_t gRxBuf[10];void USART1_IRQHandler(void){ //. gDgus_RxBuf[gRxCnt]=(uint8_t)USART_ReceiveData(USART1); gRxCnt++; //. }void App(void) { //. if(0 gRxCnt) { //复制接收到的数据gRxCnt=0; //解析接收到的数据并进行处理}} 2、中断函数接收到完整的一帧数据,然后进行处理
例如:
无效USART1_IRQHandler(void){ 静态uint8_t RxCnt=0; //计数值static uint8_t RxNum=0; //数量if((USART1-SR USART_FLAG_RXNE)==USART_FLAG_RXNE) { gDgus_RxBuf[RxCnt]=(uint8_t)USART_ReceiveData(USART1) ; RxCnt++; if(gDgus_RxBuf[0] !=DGUS_FRAME_HEAD1) //接收到帧头1 { RxCnt=0;返回; } if((2==RxCnt) (gDgus_RxBuf[1] !=DGUS_FRAME_HEAD2)) { RxCnt=0;返回; } if(RxCnt==3) { RxNum=gDgus_RxBuf[2] + 3; } if(( 6=RxCnt) (RxNum=RxCnt)) { RxCnt=0; OSMboxPost(EventMBox_Touch, gDgus_RxBuf); //发送消息邮箱(执行触摸操作) } }}中断函数解析完一帧数据后,可以通过标志位通知应用程序(裸机),也可以通过消息队列发送给应用程序,邮箱等(RTOS)。
3. RTOS队列和邮箱接收
例如:
void DEBUG_COM_IRQHandler(void){ 静态uint8_t 数据; if(USART_GetITStatus(DEBUG_COM, USART_IT_RXNE) !=RESET) { Data=USART_ReceiveData(DEBUG_COM);CLI_RcvDateFromISR(Data);//下面将这个函数分开}}void CLI_RcvDateFromISR(uint8_t RcvData){ static portBASE_TYPE xHigherPriorityTaskWoken=pdFALSE; if(xCLIRcvQueue !=NULL) { xQueueSendFromISR(xCLIRcvQueue, RcvData, xHigherPriorityTaskWoken); }}如果一字节数据被中断,则通过消息队列发送一字节数据。如果没有及时发出,数据也会存储在队列中。
通信协议分析
像上面的第二种,简单的通讯协议,当项目比较小时,可以直接在中断函数中处理。
但如果项目比较大、比较复杂,协议也比较复杂,那么在函数内部就不建议使用上面的第二种方法了。
1. 裸机环境
裸机情况下,建议使用第一种方法:中断数组缓存数据(FIFO),应用解析通信协议。
2.RTOS环境
对于RTOS的情况,建议使用第三种方式:消息队列、邮箱等接收数据,然后发送(通知)应用解析协议。
当然,以上只是常用的方法,具体方法需要结合自己项目的实际情况。
同时,其他通信如I2C、CAN如果有协议分析也是类似的。
比如我在使用CAN之前就实现了我跟大家分享的MavLink:
无效CAN_RX_IRQHandler(void){ 静态CanRxMsg RxMessage;静态MAVRCV_QUEUE_TypeDef MAVRcvQueue_Union; CAN_Receive(CAN1, CAN_FIFO0, RxMessage); //复制长度、数据MAVRcvQueue_Union.MAVRcvStruct.MAVLink_Len=RxMessage.DLC; memcpy(MAVRcvQueue_Union.MAVRcvStruct.MAVLink_Buf[0],RxMessage.Data[0],RxMessage.DLC); MAVLink_RcvDateFromISR(MAVRcvQueue_Union.MAVLinkRcv_Queue[0]);} 最后,以上内容仅提供思路,代码可能并不适合项目。
黄飞
以上知识分享希望能够帮助到大家!
版权声明:本站所有作品图文均由用户自行上传分享,仅供网友学习交流。若您的权利被侵害,请联系我们
推荐阅读
2023-10-14
2023-10-14
2023-10-14
2023-10-14
2023-10-14
2023-10-14
2023-10-14
2023-10-14
2023-10-14
2023-10-14
2023-10-14
栏目热点
比Nappa还高级的真皮座椅?听说只在百万级豪车上使用 苯胺皮和纳帕皮是区别
LilyGoT手表键盘C3迷你电脑套件
索泰ZBOXEdgeCI342迷你电脑正式上市
谷歌在最新的视频预告片中展示了PixelWatch的独特设计
三星与设计师Juun.J合作推出限量版可折叠产品和配件
从2023年起Fitbit设备将需要Google帐户
TOKKCAMC2+智能WiFi独立日 夜视摄像头
三星正在与全球时尚品牌JUUN.J合作
OnePlusNordWatch的颜色选项通过泄露的渲染揭示
就在第一款Nothing手机发布之前一种新的TWS芽设计浮出水面