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

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

[复制链接]
电小龙 提问时间: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管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版