STM32F103_LL库+寄存器学习笔记12.2 - 串口DMA高效收发实战2:进一步提高串口接收的效率
导言
通过优化代码算法,在串口空闲中断回调里不需要暂时关闭DMA接收,达到提高串口接收的效率。在IDLE接收中断里关闭DMA接收会导致接收过程中有数据丢失风险(关DMA的瞬间如果有数据到来,会丢帧!)。
回顾一下三种中断并用的本质优势:
- DMA半传输中断(HT):大包时减少等待时间,能及时处理前半区数据,不等整个缓冲区满。
- DMA完成中断(TC):大包时搬运后半区数据,保证不会丢数据。
- USART空闲中断(IDLE):短包/不定长帧/突发帧,能及时取走实际收到的数据,极大减少帧延迟。
总之,三者结合既保证高吞吐大包效率,也保证短包/突发帧实时性。
项目地址:
github:
- LL库: https://github.com/q164129345/MCU_Develop/tree/main/stm32f103_ll_library12_2_usart_rx_dma_more_efficient
- 寄存器方式: https://github.com/q164129345/MCU_Develop/tree/main/stm32f103_reg_library12_2_usart_rx_dma_more_effcient
gitee(国内):
- LL库: https://gitee.com/wallace89/MCU_Develop/tree/main/stm32f103_ll_library12_2_usart_rx_dma_more_efficient
- 寄存器方式: https://gitee.com/wallace89/MCU_Develop/tree/main/stm32f103_reg_library12_2_usart_rx_dma_more_effcient
一、之前的串口空闲中断代码
如上所示,在串口接收空闲中断里短暂地关闭DMA接收,函数的尾部在重新开启DMA接收。
二、本章节新代码
2.1、LL库
如上所示,核心的函数USART1_DMA_RX_Copy()
被三种中断分别调用,将接收到的串口数据放入ringbuffer,在大循环中在处理ringbuffer消息。注意,代码不再出现函数LL_DMA_DisableChannel()
关闭DMA接收。而且,代码更加简洁了。
2.2、寄存器方式
三、细节补充
3.1、USART1_DMA_RX_Copy()如何避免数据重复/遗漏?
关键点是:每次处理后都要有记录“DMA读到哪里了”,三类中断都要对“已处理指针”做同步!