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条回答
shuen729
1楼-- · 2019-12-20 03:27
SCREA 发表于 2018-11-23 11:04
谢谢回复,不是对你生气。别误会朋友。
1:那俩个地址一样的。
2:今晚测试下串口中断中的TC完成中断,以判 ...

没有觉得你对我生气了,难道我说话的语气不对?哈哈
祝你早日搞定
qwe2231695
2楼-- · 2019-12-20 08:16
DMA有专门的中断
haso2007
3楼-- · 2019-12-20 12:00
zhongsandaoren 发表于 2018-4-27 15:16
一般都是送出就不管了

我也是,DMA足够快了,而且用DMA的目的就是为了不用再管它了,可以去做别的事,如果用while结构实在不是很好的方法
SCREA
4楼-- · 2019-12-20 16:15
shuen729 发表于 2018-11-23 12:00
没有觉得你对我生气了,难道我说话的语气不对?哈哈
祝你早日搞定

请教下,我测试稳定性时候。当每隔小于150ms发送一次50字节的数据,单片机就死了。若是不用DMA反倒没问题。
你的稳定吗?
我DMA1的所有通道全用上了
shuen729
5楼-- · 2019-12-20 19:49
 精彩回答 2  元偷偷看……
knight_sh
6楼-- · 2019-12-20 23:04
我使用DMA发送完成中断,然后在中断中检测发送队列是否有数据,有的话继续开启中断...
/**
* 运行在DMA ISR中
* @param user_data
*/
static void _usart_tx_dma_cb(void *user_data) {
    usart_t *instance = (usart_t *) user_data;

    instance->tx.dma.ops->disable(&instance->tx.dma);

    queue_advance_rd(&instance->tx.queue, instance->tx.prev_trans_bytes);

    if (queue_used(&instance->tx.queue)) {
        queue_chunk_t chunk = queue_get_rd_chunk_no_wrap(&instance->tx.queue);
        instance->tx.prev_trans_bytes = chunk.size;
        instance->tx.dma.ops->set_trans_bytes(&instance->tx.dma, chunk.p_buf,
                chunk.size);
    }
}

一周热门 更多>