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

串口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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版