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

串口DMA空闲中断接收数据,过一段时间后就无法存到数组.....

[复制链接]
any012 提问时间:2018-11-23 09:13 /
10ST金币
串口DMA空闲中断接收数据,放在数组uart1_buffer[23]里。
用stlink调试,观测uart1_buffer[],以及串口的SR,CR1寄存器。
PC通过串口助手自动向单片机发送数据,一开始时,接收正常,接收到的数据到会更新到uart1_buffer[]数组里。
然后我不不断的修改串口助手里发送的数据内容,结果过一段时间后,串口接收到的数据,却存放到了uart1_buffer[]数组的后面位置,以此放置。好像没有进入空闲中断了。在空闲中断回调函数里放断点,也没有被触发。
但是SR寄存器的IDLE标志位,确实能看到被置位了,然后又被清空了。
如果不是空闲回调函数里清除IDLE标志位的话,还能有哪些地方能清掉IDLE标志?来了新数据以后自动清掉?

翻手册看到如下介绍,应该只能软件清除IDLE标志位吧?
DLE:监测到总线空闲 (IDLE line detected)
位4
当检测到总线空闲时,该位被硬件置位。如果USART_CR1中的IDLEIE为’1’,则产生中断。由软件序列清除该位(先读USART_SR,然后读USART_DR)。
0:没有检测到空闲总线;
1:检测到空闲总线。
注意:IDLE位不会再次被置高直到RXNE位被置起(即又检测到一次空闲总线)

空闲回调函数如下:
  1. void IdleCallback(UART_HandleTypeDef *huart)
  2. {
  3.     if (huart == &huart1)
  4.     {
  5.         if (RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))
  6.         {
  7.             recvLen = huart1.RxXferCount - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);
  8.             // __HAL_UART_DISABLE_IT(&huart1, UART_IT_IDLE);
  9.             __HAL_UART_CLEAR_IDLEFLAG(&huart1);
  10.             HAL_UART_DMAStop(&huart1);
  11.             HAL_UART_Receive_DMA(&huart1, uart1_buffer, UART1_BUFF_SIZE);
  12.         }
  13.     }
  14. }
复制代码

在串口初始化时使能了IDLE中断:
  1. __HAL_UART_ENABLE_IT(&huart1, UART_IT_IDLE);
复制代码

主函数里先调用一次DMA接收:
  1. HAL_UART_Receive_DMA(&huart1, uart1_buffer, UART1_BUFF_SIZE);
复制代码

串口中断部分:
  1. void USART1_IRQHandler(void)
  2. {
  3.   /* USER CODE BEGIN USART1_IRQn 0 */
  4.     IdleCallback(&huart1);

  5.   /* USER CODE END USART1_IRQn 0 */
  6.   HAL_UART_IRQHandler(&huart1);
  7.   /* USER CODE BEGIN USART1_IRQn 1 */
  8.     // IdleCallback(&huart1);

  9.   /* USER CODE END USART1_IRQn 1 */
  10. }
复制代码
QQ图片20181123092124.png


奇怪的是,刚开始能正常接收的时候,SR寄存器的ILDE标志位是看不到闪烁的,也许是太快了。这时是可以进到空闲回调函数的断点的。
出现错误后,能看到SR寄存器的IDLE标志位闪烁,进不到回调函数的断点。

或者在空闲中断回调函数里加入断点,触发断点后,再点继续运行,如果点的晚一点的话,也会出现这种现象。



最佳答案

查看完整内容

是否有可能是填充buffer的函数,修改了buffer指针的首地址?
收藏 评论5 发布时间:2018-11-23 09:13

举报

5个回答
any012 最优答案 回答时间:2018-11-23 12:12:06
本帖最后由 any012 于 2018-11-23 12:13 编辑

已解决,用HAL_UART_AbortReceve()代替HAL_DMA_STOP();
参考:
https://www.stmcu.org.cn/module/forum/thread-606385-1-1.html
STM1024 回答时间:2018-11-23 09:13:38
是否有可能是填充buffer的函数,修改了buffer指针的首地址?

评分

参与人数 2ST金币 +5 蝴蝶豆 +2 收起 理由
any012 + 5 淡定
STMCU + 2

查看全部评分

any012 回答时间:2018-11-23 09:30:20
stm1024 发表于 2018-11-23 09:26
是否有可能是填充buffer的函数,修改了buffer指针的首地址?

直接调用 HAL_UART_Receive_DMA(&huart1, uart1_buffer, UART1_BUFF_SIZE) 这个函数,其它函数没有涉及到uart1_buffer[]这个数组。
此名已占用 回答时间:2018-11-23 11:04:44
buf内存溢出

评分

参与人数 2ST金币 +5 蝴蝶豆 +1 收起 理由
any012 + 5 淡定
STMCU + 1

查看全部评分

STM1024 回答时间:2018-11-23 11:58:05
any012 发表于 2018-11-23 09:30
直接调用 HAL_UART_Receive_DMA(&huart1, uart1_buffer, UART1_BUFF_SIZE) 这个函数,其它函数没有涉及到u ...

调试跟进去看看,这个函数的代码有没有做边界检查?

所属标签

相似问题

关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版