STM32103 USART DMA发送完成判断方法分享

2019-12-14 13:33发布

<i class="pstatus"> 本帖最后由 shuen729 于 2018-4-28 11:57 编辑 </i><br> <br><p> 今天调代码的时候,遇到这个问题,USART在DMA模式下,进DMA发送完成中断后发现数据其实USART那边还没有真正的完成发送,论坛里面搜“DMA 发送完成”有一篇帖子,但是很遗憾不让看,要密码。</p><br><p> 然后不得已,看参考手册,找到下面的时序图</p><br> <p><img src="https://www.xiaopingtou.net/data/attach/1912/s7logd01cd1ixh2sli8xicabop2ykx9w.jpg" lazyloadthumb="1" border="0" alt=""></p><br><p> 然后在中断里面改了下,先把DMA禁止掉,然后等待TC置位,TC置位就可以确认所有数据已经送出。</p><br><p> void DMA1_Channel7_IRQHandler(void)</p><br><p> {</p><br><p> &nbsp; &nbsp; if(SET==DMA_GetITStatus(DMA1_IT_TC7))</p><br><p> &nbsp; &nbsp; {</p><br><p> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;DMA_ClearITPendingBit(DMA1_IT_TC7);</p><br><p> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;DMA_Cmd(DMA_USART2_TX, DISABLE);</p><br><p> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;DMA_USART2_TX-&gt;CNDTR = 0;</p><br><p> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;while(RESET == USART_GetFlagStatus(USART2,USART_FLAG_TC))</p><br><p> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;{</p><br><p> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;USART_ClearFlag(USART2,USART_FLAG_TC);</p><br><p> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;}</p><br><p> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;Usart2_TR_Sw(RS485_RX);</p><br><p> &nbsp; &nbsp;&nbsp; &nbsp;&nbsp;&nbsp;return ;</p><br><p> &nbsp; &nbsp; }</p><br><p> }</p> <br> <p><img src="https://image.xiaopingtou.net/data/attach/191214/zbahRxQ9.png" alt="135857g95xy0xgxfpkfxmm"><br></p><p><br></p>
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
58条回答
SCREA
1楼-- · 2019-12-21 02:27
本帖最后由 SCREA 于 2018-11-26 21:39 编辑
shuen729 发表于 2018-11-26 13:32
不好意思,这几天没上论坛。你可能已经把问题找出来了,哈哈。不过我还是回复下。
我都是先放进队列,然 ...


是的,找到原因了。现在只能做到最快18ms,把接到的50字节数据解析出来执行相应命令动作然后返回结果帧。
还可以快,没时间去做了。
好奇为何发的太快了CPU没死,倒是串口死了 ,但看寄存器都很正常。有时间去分析吧

对了,DMA全部用掉时会降低DMA速度。以前用1~3个通道没感觉,现在用了9个通道,压力测试还是很明显体现出来DMA快到极限了
shuen729
2楼-- · 2019-12-21 03:59
解决了就好。谢谢分享过程和经验,有空了我再试一试你说的发的太快串口会死的现象,看看能不能出现
saccapanna
3楼-- · 2019-12-21 07:27
发快了会死?我一直把USART发送允许打开,DMA只负责写数据,不管发送,DMA完毕就关闭DMA,用USART1跑3000000bps,压力测试一点问题都没有。不知道你说的假死是什么,多半程序那里时序有点问题。
tdh03z
4楼-- · 2019-12-21 09:25
 精彩回答 2  元偷偷看……
SCREA
5楼-- · 2019-12-21 09:37
saccapanna 发表于 2018-11-27 08:57
发快了会死?我一直把USART发送允许打开,DMA只负责写数据,不管发送,DMA完毕就关闭DMA,用USART1跑300000 ...

只负责写,不管发送,是什么意思。是DMA只负责接收,发送不用DMA?
saccapanna
6楼-- · 2019-12-21 12:20
SCREA 发表于 2018-11-28 09:32
只负责写,不管发送,是什么意思。是DMA只负责接收,发送不用DMA?

写数据到DR寄存器,和数据发送是两个步骤。DMA只负责把数据写到DR寄存器,写完数据就不管了,数据写到DR寄存器后,是USART接口负责发送出去的。只要一直开着发送允许位,写入DR寄存器的值是一定能发送出去的。有问题的是,DMA数据写完,有的觉得是USART发送完了,就把USART发送允许位关闭了。或者一次DMA没有完毕,要再次开启DMA,是要等上次DMA结束的。等等,这些细节不把握好,都会有问题。

我没用官方的库,都是自己定义寄存器,进行的寄存器操作,编写自己的库函数,所以对底层细节熟悉一些。就算调用库函数,也要熟悉底层操作,不然也容易出问题。

一周热门 更多>