STM32
登录
直播中
李刚
7年用户
1317经验值
私信
关注
[问答]
使用串口空闲中断和DMA配合时会出现哪些问题呢
开启该帖子的消息推送
使用串口空闲中断和DMA配合时会出现哪些问题呢?怎样去解决这些问题呢?
回帖
(1)
简白伊
2021-12-9 15:30:41
使用串口空闲中断和DMA配合时出现的问题:
问题1.串口接收一旦溢出就会丢数据。
例如串口接收满了,稍等几秒再启动新的DMA接收函数HAL_UART_Receive_DMA时,就丢失数据了,而且是再也收不到串口数据。如果接满后马上启动就没这个问题。
看官方示例代码,停止DMA接收后似乎要DeInit后重新初始化Init和启动DMA接收
解答:
当接收DMA关闭后,此时串口还是激活的,若此时串口来数据,无法触发DMA传输,此时产生上溢错误(ORE),由于串口数据寄存器里的数据不能及时转移走,后面来的数据就进不来。一旦出现这种错误后,就不会再触发DMA请求,即使再开启DMA也不行。要恢复正常的话就只有Deinit后再重新初始化串口,或者直接将数据寄存器中的数据读走后,后面的数据才能正常进入,从而正常产生DMA请求,这个DMA请求是指硬件请求。
其实在STM32官网公众号有文章介绍了该问题,主要是先启动了串口再启动DMA就会容易引起该问题。因此为了防止该问题要不每次开DMA都清ORE寄存器;要不按规矩先开DMA再开串口,不用了先关串口再关DMA
2.接收不完全
空闲中断最大的一个问题,就是发送方的一帧数据不能被打断。不然stm32就会触发空闲中断,只接收到一帧的一部分数据。假如两个单片机通信,任意一个串口发送的过程被其他中断打断之后再回来继续发送就会导致帧被截断.
解答:
没有FIFO 无解
3.串口DMA接收不能单独停止。
例如串口同时在DMA发送和DMA接收,DMA接收到一半我要终止DMA的话,只能调用HAL_UART_DMAStop把接收DMA和串口DMA都停止。
换言之,不能单独停止DMA接收。
我理解的接收DMA和发送DMA是两个独立的操作,为什么不能单独停止?
解答:
HAL_UART_DMAStop()是同时关收发DMA,
只关闭接收的函数: HAL_UART_AbortReceive(); 该函数的两个工作内容:
1. 先关闭接收DMA,HAL_DMA_Abort(huart->hdmarx);
2. 置位RX ready状态,huart->RxState = HAL_UART_STATE_READY;
忽略了错误标志和IT标志处理,最保险的方式还是使用HAL_UART_AbortReceive()函数。
一种笨办法::直接利用stm32的RXNE和IDLE中断进行接收不定字节数据。
基本知识:
IDLE中断什么时候发生?
IDLE就是串口收到一帧数据后,发生的中断。什么是一帧数据呢?比如说给单片机一次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以叫做一包数据。
如何判断一帧数据结束,就是我们今天讨论的问题。因为很多项目中都要用到这个,因为只有接收到一帧数据以后,你才可以判断这次收了几个字节和每个字节的内容是否符合协议要求。
看了前面IDLE中断的定义,你就会明白了,一帧数据结束后,就会产生IDLE中断。
如何配置好IDLE中断?
下面我们就配置好串口IDLE中断吧。
USART_CR
Bit4是 : IDLEIE 寄存器 Bit5是: RXNEIE
对Bit4写1开启IDLE中断,对Bit5写1开启接收数据中断。(注意:不同系列的STM32,对应的寄存器位可能不同)
RXNE中断和IDLE中断的区别?
当接收到1个字节,就会产生RXNE中断,当接收到一帧数据,就会产生IDLE中断。比如给单片机一次性发送了8个字节,就会产生8次RXNE中断,1次IDLE中断。
USART_ISR 状态寄存器
Bit4是 : IDLE 寄存器 Bit5是: RXNE
这是状态寄存器,当串口接收到数据时,bit5就会自动变成1,当接收完一帧数据后,bit4就会变成1.
需要注意的是,在中断函数里面,需要把对应的位清0,否则会影响下一次数据的接收。
比如RXNE接收数据中断,只要把接收到的一个字节读出来,就会清除这个中断。
IDLE中断,如何是F0系列的单片机,需要用ICR寄存器来清除,如果是F1系列的单片机,清除方法是“先读SR寄存器,再读DR寄存器”。
串口初始化中开启两个中断:
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
中断处理函数如下:
当然你也可以先不管各种问题,调试通了再说。
中断里的
//HAL_UART_DMAStop(&huart2);
更改为:
HAL_UART_AbortReceive(&huart2);
即可修复收取数据的时候关闭了DMA导致不能发送得问题。
使用串口空闲中断和DMA配合时出现的问题:
问题1.串口接收一旦溢出就会丢数据。
例如串口接收满了,稍等几秒再启动新的DMA接收函数HAL_UART_Receive_DMA时,就丢失数据了,而且是再也收不到串口数据。如果接满后马上启动就没这个问题。
看官方示例代码,停止DMA接收后似乎要DeInit后重新初始化Init和启动DMA接收
解答:
当接收DMA关闭后,此时串口还是激活的,若此时串口来数据,无法触发DMA传输,此时产生上溢错误(ORE),由于串口数据寄存器里的数据不能及时转移走,后面来的数据就进不来。一旦出现这种错误后,就不会再触发DMA请求,即使再开启DMA也不行。要恢复正常的话就只有Deinit后再重新初始化串口,或者直接将数据寄存器中的数据读走后,后面的数据才能正常进入,从而正常产生DMA请求,这个DMA请求是指硬件请求。
其实在STM32官网公众号有文章介绍了该问题,主要是先启动了串口再启动DMA就会容易引起该问题。因此为了防止该问题要不每次开DMA都清ORE寄存器;要不按规矩先开DMA再开串口,不用了先关串口再关DMA
2.接收不完全
空闲中断最大的一个问题,就是发送方的一帧数据不能被打断。不然stm32就会触发空闲中断,只接收到一帧的一部分数据。假如两个单片机通信,任意一个串口发送的过程被其他中断打断之后再回来继续发送就会导致帧被截断.
解答:
没有FIFO 无解
3.串口DMA接收不能单独停止。
例如串口同时在DMA发送和DMA接收,DMA接收到一半我要终止DMA的话,只能调用HAL_UART_DMAStop把接收DMA和串口DMA都停止。
换言之,不能单独停止DMA接收。
我理解的接收DMA和发送DMA是两个独立的操作,为什么不能单独停止?
解答:
HAL_UART_DMAStop()是同时关收发DMA,
只关闭接收的函数: HAL_UART_AbortReceive(); 该函数的两个工作内容:
1. 先关闭接收DMA,HAL_DMA_Abort(huart->hdmarx);
2. 置位RX ready状态,huart->RxState = HAL_UART_STATE_READY;
忽略了错误标志和IT标志处理,最保险的方式还是使用HAL_UART_AbortReceive()函数。
一种笨办法::直接利用stm32的RXNE和IDLE中断进行接收不定字节数据。
基本知识:
IDLE中断什么时候发生?
IDLE就是串口收到一帧数据后,发生的中断。什么是一帧数据呢?比如说给单片机一次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以叫做一包数据。
如何判断一帧数据结束,就是我们今天讨论的问题。因为很多项目中都要用到这个,因为只有接收到一帧数据以后,你才可以判断这次收了几个字节和每个字节的内容是否符合协议要求。
看了前面IDLE中断的定义,你就会明白了,一帧数据结束后,就会产生IDLE中断。
如何配置好IDLE中断?
下面我们就配置好串口IDLE中断吧。
USART_CR
Bit4是 : IDLEIE 寄存器 Bit5是: RXNEIE
对Bit4写1开启IDLE中断,对Bit5写1开启接收数据中断。(注意:不同系列的STM32,对应的寄存器位可能不同)
RXNE中断和IDLE中断的区别?
当接收到1个字节,就会产生RXNE中断,当接收到一帧数据,就会产生IDLE中断。比如给单片机一次性发送了8个字节,就会产生8次RXNE中断,1次IDLE中断。
USART_ISR 状态寄存器
Bit4是 : IDLE 寄存器 Bit5是: RXNE
这是状态寄存器,当串口接收到数据时,bit5就会自动变成1,当接收完一帧数据后,bit4就会变成1.
需要注意的是,在中断函数里面,需要把对应的位清0,否则会影响下一次数据的接收。
比如RXNE接收数据中断,只要把接收到的一个字节读出来,就会清除这个中断。
IDLE中断,如何是F0系列的单片机,需要用ICR寄存器来清除,如果是F1系列的单片机,清除方法是“先读SR寄存器,再读DR寄存器”。
串口初始化中开启两个中断:
USART_ITConfig(USART1, USART_IT_IDLE, ENABLE);
USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
中断处理函数如下:
当然你也可以先不管各种问题,调试通了再说。
中断里的
//HAL_UART_DMAStop(&huart2);
更改为:
HAL_UART_AbortReceive(&huart2);
即可修复收取数据的时候关闭了DMA导致不能发送得问题。
举报
更多回帖
rotate(-90deg);
回复
相关问答
CH32V208
串口
支持
空闲
中断
不?可以
配合
DMA
接收不定长数据不?
2023-03-30
553
CH32F103C8使用
串口
DMA
出现
接收粘包或者接收不全现象如何处理?
2022-05-25
2214
可以用
串口
空闲
中断
+
DMA
来实现
串口
接收不定长数据吗?
2023-03-07
499
怎样对HC32F460
串口
空闲
中断
+
DMA
收发进行配置
呢
2022-02-24
1370
怎样去解决STM32F103
DMA
串口
空闲
接收卡顿的问题
呢
2021-12-08
1810
STM32HAL库
串口
空闲
中断
+
DMA
是如何去实现
串口
接收不定长数据的
2021-11-16
1431
怎样使用IDLE
中断
+
DMA
接收的方式接收数据
呢
2022-01-27
1091
DMA
串口
空闲
中断
的实现流程是怎样的
2021-11-16
969
怎样使用
空闲
中断
+
DMA
的方法接受
串口
任意长数据
呢
2021-12-09
1150
STM32F103VET6的
串口
是怎样去使用
DMA
+
串口
空闲
中断
接收数据的
2021-12-13
952
发帖
登录/注册
20万+
工程师都在用,
免费
PCB检查工具
无需安装、支持浏览器和手机在线查看、实时共享
查看
点击登录
登录更多精彩功能!
英国威廉希尔公司网站
william hill官网 版块
小组
免费开发板试用
ebook
直播
搜索
登录
×
20
完善资料,
赚取积分