STM32使用串口IDLE中断+DMA注意事项

STM32的串口使用方式很多,其中IDLE+DMA方式可能是最受欢迎的一种。但是官方对这个组合的例程不太详细,网友分享的又多种多样,直接COPY后常常出现各种疑难杂症,故在此记录几个重点。

环境:
STM32CubeMX 6.1.2
1.8.4 HAL_Lib
STM32F103C8T6
KEIL 5.34

  1. 接收数据是单次的,就是说每次收完数据都会关掉DMA,需要手动再次开启,即执行一次HAL_UARTEx_ReceiveToIdle_DMA函数才能继续接收下一帧数据
  2. 发数据前需要先判断上一次发送是否完成,否则会丢失数据,可在中断里自定义标志(官方例程做法),也可直接判断huartx.gState是否等于HAL_UART_STATE_READY
  3. 收到数据后依次进入的函数:USARTx_IRQHandler->HAL_UARTEx_RxEventCallback
  4. 发送数据后依次进入的函数:DMA1_Channelx_IRQHandler->HAL_UART_TxHalfCpltCallback->DMA1_Channelx_IRQHandler->HAL_UART_TxCpltCallback
  5. 收数据产生错误需要在HAL_UART_ErrorCallback里有处理代码,而且一旦出错将不会再进入HAL_UARTEx_RxEventCallback,很多人把HAL_UARTEx_ReceiveToIdle_DMA放在HAL_UARTEx_RxEventCallback中,此时就不能再收到数据(有同学说那我把错误中断EIE关掉不就行了?理论上可行,但是HAL_UARTEx_ReceiveToIdle_DMA中会打开错误中断EIE,除非你把这里的也关了,一般不建议修改库代码)

以上要点中的一些疑问:

1.明明用了DMA,为何接收过程没有进入DMA中断?
答:DMA中断发生前先发生了串口中断,而串口中断程序USARTx_IRQHandler中调用了HAL_DMA_Abort,所以DMA1_Channelx_IRQHandler不再进入。串口中断就是比DMA中断快,找不到相关说明,但是实测就是这样,与中断优先级无关。

2.为什么发送过程没有进入USARTx_IRQHandler?
答:因为我关了串口发送中断。如果打开发送中断,那么发送后的执行流程是这样的USARTx_IRQHandler->DMA1_Channelx_IRQHandler->HAL_UART_TxHalfCpltCallback->DMA1_Channelx_IRQHandler->HAL_UART_TxCpltCallback

3.HAL_UART_TxHalfCpltCallba是什么鬼?
答:DMA发送完成一半的中断,我目前还没遇到需要用到这个函数的场景。可以手动关掉它,关掉后的发送流程即变为:
DMA1_Channelx_IRQHandler->HAL_UART_TxCpltCallback
一般把发送完成的处理代码放在HAL_UART_TxCpltCallback就行

4.使用这套方案需要开哪些中断?
答:DMA发送中断,串口IDLE中断,总中断。
DMA发送中断需要手动开,也可以MX里配置
串口IDLE中断在调用HAL_UARTEx_ReceiveToIdle_DMA时自动打开
总中断需要手动开

5.为什么DMA接收中断和UART发送中断不用开?
答:用不到

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值