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

奇怪的STM32L051串口接收卡死

[复制链接]
hjl2832 提问时间:2020-6-18 17:40 /
如题:实验现象是用CUBE配置好的代码,HAL库,修改中断函数,增加空闲中断处理不定长数据接收,在使用串口助手进行调试时发现,连续快速点击发送按钮,串口会卡死,为了确认卡死的地方,在所有异常中断中都加了LED指示,最后发现在接收数据时LED指示常亮,证明是卡死在数据接收中。为了验证,在串口助手中设置1MS自动发送,程序不会卡死。但只要在单次发送模式用手连续快速点击发送,100%卡死。怀疑串口助手有问题,换助手后一样。在出现卡死后,程序也不知道跑在哪里了,按复位能恢复;但在用STLINK进入DEBUG模式下跑代码测试,不会出现卡死现象。
中断部分处理代码如下:
  1. void LPUART1_IRQHandler(void)
  2. {
  3. //        uint8_t  RCVBUF;
  4.   /* USER CODE BEGIN LPUART1_IRQn 0 */
  5.   /* USER CODE END LPUART1_IRQn 0 */
  6. //  HAL_UART_IRQHandler(&hlpuart1);
  7.   /* USER CODE BEGIN LPUART1_IRQn 1 */
  8.   HAL_GPIO_WritePin(led1_GPIO_Port,led1_Pin,GPIO_PIN_SET);       
  9. //        HAL_UART_Receive_IT(&hlpuart1,&RCVBUF,1);
  10. //        LPUart1_RX_BUF[LPUart1_REC_Cnt++] = RCVBUF;
  11. //        if(LPUart1_REC_Cnt > LPUart1_BUF_SIZE)
  12. //                                        LPUart1_REC_Cnt =0;       
  13.        
  14. if(__HAL_UART_GET_FLAG(&hlpuart1, UART_FLAG_RXNE) != RESET)  
  15.     {
  16.                         __HAL_UART_CLEAR_FLAG(&hlpuart1, UART_FLAG_ORE | UART_FLAG_NE | UART_FLAG_PE | UART_FLAG_FE);
  17.       __HAL_UART_CLEAR_FLAG(&hlpuart1, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
  18.                         if(LPUart1_End_flage == 0)
  19.                         {
  20.                           LPUart1_RX_BUF[LPUart1_REC_Cnt] = LPUART1->ISR;   
  21.         LPUart1_RX_BUF[LPUart1_REC_Cnt] = LPUART1->RDR;   
  22.         LPUart1_REC_Cnt++;
  23.                                 if(LPUart1_REC_Cnt > LPUart1_BUF_SIZE)
  24.                                         LPUart1_REC_Cnt =0;       
  25.                         }
  26.   }
  27. else if(__HAL_UART_GET_FLAG(&hlpuart1,UART_FLAG_IDLE) == SET)
  28.     {
  29.                          __HAL_UART_CLEAR_IDLEFLAG(&hlpuart1);
  30.                         __HAL_UART_CLEAR_FLAG(&hlpuart1, UART_FLAG_ORE | UART_FLAG_NE | UART_FLAG_PE | UART_FLAG_FE);
  31.                printf("UART IT For IDEL \r\n");
  32.         LPUart1_End_flage = 1;
  33.         LPUart1_REC_SIZE = LPUart1_REC_Cnt;
  34.         LPUart1_REC_Cnt = 0;
  35.    }
  36. HAL_GPIO_WritePin(led1_GPIO_Port,led1_Pin,GPIO_PIN_RESET);       
  37.   /* USER CODE END LPUART1_IRQn 1 */
  38. }
复制代码
工程原文件如下,大家有兴趣可以测试验证。


stm32l051_stop.rar (5.19 MB, 下载次数: 3)
收藏 评论8 发布时间:2020-6-18 17:40

举报

8个回答
hjl2832 回答时间:2020-6-18 17:41:39
我在测试时串口助手发送的是128个字节
新建位图图像.jpg

评分

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

查看全部评分

wenyangzeng 回答时间:2020-6-18 20:52:07
IDLE中断需要:
读取SR寄存器的ISR和RDR方可清零状态寄存器,
temp = huart1.Instance->ISR;                 
temp = huart1.Instance->RDR;
回答时间:2020-6-18 21:33:59
怀疑时产生了串口接收溢出,看一下串口溢出标志位,当接收指定数据完成以后,需要继续开启串口接收中断。

评分

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

查看全部评分

yklstudent-1794 回答时间:2020-6-19 08:38:01
中断回调函数内就别用打印函数了
hjl2832 回答时间:2020-6-19 10:41:05
yklstudent-1794 发表于 2020-6-19 08:38
中断回调函数内就别用打印函数了

打印函数是为了确认问题位置才加上去的,实际应用当然没有,否则,打印这个的意义在哪里?包括灯的控制也是为了找问题。
mmuuss586 回答时间:2020-6-19 11:34:07
hjl2832 回答时间:2020-6-19 11:47:38
结贴,ST的M0有点扯蛋,其它厂家的芯片都是通过向中断标志写1来清的,它家的数据手册也是这样写的: 新建位图图像.jpg
而且,它的HAL库也是这样执行的:
  1. #define __HAL_UART_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->ICR = (__FLAG__))
复制代码
经过分析卡死现象,认为是接收中断中的开启的条件判断:
  1. if(LPUart1_End_flage == 0)
  2.                         {
  3.                            *******
  4. ********
  5.                         }
复制代码
影响了数据的接收,从而出现卡死,即溢出错误。因为点击过快时,主程序未能及时处理数据的话,有可能出现LPUart1_End_flage结束标志未及时复位为0,这样接收就会出现溢出错误(当然,这里的前提就是因为ST的软件清中断功能无效,毕竟我在中断中第一个事情就是软件清中断__HAL_UART_CLEAR_FLAG),但是实际上,软件清中断标志根本没用。
所以修改代码如下,将读ISR和读RDR放到条件上面,屏蔽软件清中断语句,再进行测试验证:
  1. void LPUART1_IRQHandler(void)
  2. {
  3. //        uint8_t  RCVBUF;
  4.   /* USER CODE BEGIN LPUART1_IRQn 0 */
  5.   /* USER CODE END LPUART1_IRQn 0 */
  6. //  HAL_UART_IRQHandler(&hlpuart1);
  7.   /* USER CODE BEGIN LPUART1_IRQn 1 */
  8.   HAL_GPIO_WritePin(led1_GPIO_Port,led1_Pin,GPIO_PIN_SET);       
  9. //        HAL_UART_Receive_IT(&hlpuart1,&RCVBUF,1);
  10. //        LPUart1_RX_BUF[LPUart1_REC_Cnt++] = RCVBUF;
  11. //        if(LPUart1_REC_Cnt > LPUart1_BUF_SIZE)
  12. //                                        LPUart1_REC_Cnt =0;       
  13.        
  14. if(__HAL_UART_GET_FLAG(&hlpuart1, UART_FLAG_RXNE) != RESET)  
  15.     {
  16. //                        __HAL_UART_CLEAR_FLAG(&hlpuart1, UART_FLAG_ORE | UART_FLAG_NE | UART_FLAG_PE | UART_FLAG_FE);
  17. //      __HAL_UART_CLEAR_FLAG(&hlpuart1, UART_CLEAR_OREF | UART_CLEAR_NEF | UART_CLEAR_PEF | UART_CLEAR_FEF);
  18.                          LPUart1_RX_BUF[LPUart1_REC_Cnt] = LPUART1->ISR;   
  19.        LPUart1_RX_BUF[LPUart1_REC_Cnt] = LPUART1->RDR;  
  20.                         if(LPUart1_End_flage == 0)
  21.                         {
  22.                           
  23.         LPUart1_REC_Cnt++;
  24.                                 if(LPUart1_REC_Cnt >LPUart1_BUF_SIZE)
  25.                                         LPUart1_REC_Cnt =0;       
  26.                         }
  27.   }
  28. else if(__HAL_UART_GET_FLAG(&hlpuart1,UART_FLAG_IDLE) != RESET)
  29.     {
  30.                          __HAL_UART_CLEAR_IDLEFLAG(&hlpuart1);
  31. //                        __HAL_UART_CLEAR_FLAG(&hlpuart1, UART_FLAG_ORE | UART_FLAG_NE | UART_FLAG_PE | UART_FLAG_FE);
  32.        printf("UART IT For IDEL \r\n");
  33.                                                    
  34.         LPUart1_End_flage = 1;
  35.         LPUart1_REC_SIZE = LPUart1_REC_Cnt;
  36.         LPUart1_REC_Cnt = 0;
  37.    }
  38.        
  39. HAL_GPIO_WritePin(led1_GPIO_Port,led1_Pin,GPIO_PIN_RESET);       
  40.   /* USER CODE END LPUART1_IRQn 1 */
  41. }
复制代码

神奇的现象出现了,接收不会卡死了。但因为少了包条件判断,回传数据丢包很严重,空闲中断乱来了? 新建位图图像.jpg
从这个事件看,ST的M0,软件清串口中断完全是没用的。




hjl2832 回答时间:2020-6-19 11:56:13
hjl2832 发表于 2020-6-19 11:47
结贴,ST的M0有点扯蛋,其它厂家的芯片都是通过向中断标志写1来清的,它家的数据手册也是这样写的:
而且, ...

这个清中断功能是通过读ISR和RDR寄存器实现了,反而软件写ICR寄存器无效。

所属标签

相似问题

官网相关资源

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