完美解决HAL库HAL_UART_Transmit_DMA()不延时就发不了下一条的问题

文章讨论了在使用HAL_UART_Transmit_DMA函数进行DMA传输时遇到的串口忙碌问题,因为DMA传输速度过快,导致数据未完全发送就尝试发送下一批数据。作者提出了一种解决方案,即通过检查串口状态并在发送前等待其准备好,使用一个线程标志来顺序执行发送任务,避免了使用延时或频繁查询状态导致的效率降低。这种方法允许连续发送多个数据块,同时保持DMA和串口的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题原因

在连续用HAL_UART_Transmit_DMA()函数的时候,会遇到只能发出第一条的问题,原因是DMA传输数据到串口这个外设太快了,传输完后程序并不会在该处停留,但是串口发送需要时间,运行到下一条HAL_UART_Transmit_DMA()函数的时候,上一条数据还没来得及发完,导致串处于BUZY(即 HAL_UART_STATE_BUSY )状态

如果串口处于BUZY状态,则HAL_UART_Transmit_DMA()不会进入发送程序,直接return HAL_BUSY;这就导致了HAL_UART_Transmit_DMA()不能连续运行,

目前网上主流的解决办法是延时一定时间或while(HAL_DMA_GetState(&hdma_usart1_tx) == HAL_DMA_STATE_BUZY),等串口发完数据在执行下一条指令。但是这样让CPU卡在这里,让DMA和串口外设的速度优势荡然无存,并且,HAL_DMA_GetState()好像只要初始化之后它的状态就不会生变化,要采用if((&huart1)->gState == HAL_UART_STATE_READY)进行判断比较有用。

于是我采用了如下办法

解决方法
    while (1)
  {
        if((&huart1)->gState == HAL_UART_STATE_READY)
        {    
            if(dma_uartThread == 4)
               dma_uartThread=0;
         
        dma_state=1;
            dma_uartThread++;
        }
                
    if(dma_state)
{
    switch(dma_uartThread)
    {
        case 1:
            HAL_UART_Transmit_DMA(&huart1,dma_sentTest1,sizeof(dma_sentTest1));
           dma_state=0;
        break;
        
        case 2:
            HAL_UART_Transmit_DMA(&huart1,dma_sentTest2,sizeof(dma_sentTest2));
          dma_state=0;
        break;
                
                 case 3:
                        HAL_UART_Transmit_DMA(&huart1,dma_sentTest3,sizeof(dma_sentTest3));
                    dma_state=0;
                break;
                 
                    case 4:
                        HAL_UART_Transmit_DMA(&huart1,dma_sentTest4,sizeof(dma_sentTest4));
                  
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值