你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

请教一些做串口接收数据的处理方式

[复制链接]
电小龙 提问时间:2018-9-6 16:36 /
本帖最后由 电小龙 于 2018-9-6 16:36 编辑

在项目中经常会遇到接收一包数据,就比如0xaa,0x55,0xXX,0xXX,0x0a,0x0d。0xaa,0x55位包头,下一个为数据,再下一个为校验和,0x0a,0x0b为包尾。在串口接收中采用中断接收的方式。
我先说说我的做法:先定义一个uint8_t Buff和一个uint8_t Table[10];在接收中断函数里用HAL_UART_Receive_IT(&UART1_Handler, &Buff, 1)这个函数,每次在中断里面都判断Buff是不是0xaa,如果是则将数据存入到Table[0]中且继续接收下面的数据,都存入到Table的数组中,如果不是则继续进行判断。然后对Table进行判断,首先判断Table[0]和Table[1]分别为0xaa,0x55后,在进行判断Table[4]和Table[5]分别为0x0a,0x0d。在进行判断校验是否正确,正确后取出Table[2]的数据进行处理。
在这里面我有些疑问:如果我初始化时和接收中断里写的是HAL_UART_Receive_IT(&UART1_Handler, &Table, 6),是不是在串口接收到5个8位数据后才会进入到串口中断。如果是这样的话,使用这种方式会不会存在另一个问题,若最开始我接收到了一个8位的无效数据,如0xff,在后面再接收数据的话就会出现0xff,0xaa,0x55,0xXX,0xXX,0x0a,这样将会导致接收不到正确的数据帧。是不是还有超时的处理可以解决这问题,但是不知道该怎样加一个超时判断,当有一小段时间没有收到数据就清空缓存区。
这是我使用串口中断时的迷惑,有兴趣的可以一起讨论下,也借鉴一下各位的处理方法。
收藏 评论7 发布时间:2018-9-6 16:36

举报

7个回答
stm1024 回答时间:2018-9-6 16:40:55
建议在接收数据的时候不要做数据处理,而是忠实地接收原始字节流。
串口除了接收会产生中断,还有一个Idle中断,在接收中断中填充接收buff,然后在Idle中断中处理buff。
这样处理的话,字节的数量都不是问题(前提是没有溢出,一般buff预留大一点就行)

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

电小龙 回答时间:2018-9-6 16:45:01
stm1024 发表于 2018-9-6 16:40
建议在接收数据的时候不要做数据处理,而是忠实地接收原始字节流。
串口除了接收会产生中断,还有一个Idle ...

麻烦能告诉我一下这个Idle中断函数对应的是哪个吗?还有Idle中断是每接收一个8位的数据都会进入这个Idle中断吗?还是说如果我设置成HAL_UART_Receive_IT(&UART1_Handler, &Table, 6)就会在接收完6个字节的数据后才会进入这个idle中断、、
电小龙 回答时间:2018-9-6 16:51:03
大家都是怎么处理的啊,都来讨论下呗,感觉串口处理看起来简单,但是处理好,处理到高效还是挺有讲究的
stm1024 回答时间:2018-9-6 17:26:45
没用HAL库,使用的标准库,你可以参考一下:
  1. //Interrupt Request Handler
  2. void USART1_IRQHandler(void)
  3. {
  4.    
  5.     if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)//Got Data
  6.     {
  7.         USART1_RX_BUFFER[USART1_RX_CNT++]=USART_ReceiveData(USART1);
  8.     }
  9.     else if(USART_GetITStatus(USART1,USART_IT_IDLE)!=RESET)
  10.     {

  11.         //Clear USART_IT_RXNE Flag
  12.         USART1->DR;
  13.         //Clear USART_IT_IDLE Flag
  14.         USART1->SR;
  15.         
  16.         //Process Receive DATA Here
  17.         ////////////////////////////////////////////////
  18.         //Example,ECHO:
  19.         //printf("%s\r\n",USART1_RX_BUFFER);


  20.         ////////////////////////////////////////////////   
  21.         //Finally Clear Buffer, IF NECESSARY
  22.         memset(USART1_RX_BUFFER,0x00,USART1_RX_CNT);
  23.         USART1_RX_CNT=0;
  24.         
  25.     }   
  26. }
复制代码
电小龙 回答时间:2018-9-6 17:38:49
stm1024 发表于 2018-9-6 17:26
没用HAL库,使用的标准库,你可以参考一下:

谢谢,我也百度了,IDLE中断确实是解决这个问题的利器、、
feixiang20 回答时间:2018-9-6 22:53:11
采用串口1,配置成空闲中断IDLE模式且使能DMA接收,并同时设置接收缓冲区和初始化DMA。
看看这个帖子
https://www.stmcu.org.cn/module/forum/thread-609561-1-14.html
HAL库UART的几个常用函数讲解+中断处理过程讲解
电小龙 回答时间:2018-9-7 08:50:39
feixiang20 发表于 2018-9-6 22:53
采用串口1,配置成空闲中断IDLE模式且使能DMA接收,并同时设置接收缓冲区和初始化DMA。
看看这个帖子
http: ...

好的,谢谢

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版