PIC学习——DMA发送

一、介绍

         DMA传输是一种不需要占用 CPU的传输方式,当把数据装进去并启动DMA发送后,CPU可以去执行其它主线程任务,而不用等待。使用DMA传输可以给CPU减负,提高程序的执行效率。

二、使用

发送函数如下: 

void uart1_dma_tx(uint8_t *buf, uint8_t len)
{
    if (len == 0)
    {
        return;
    }
    
    while (!U1STAbits.TRMT);          //检测发送缓冲区是否为空
    DMA0STAL = (uint16_t)buf;
    DMA0CNT = len - 1;
    DMA0STAH = 0x0000;
    DMA0CONbits.CHEN  = 1;            // Re-enable DMA0 Channel
    DMA0REQbits.FORCE = 1;            // Manual mode: Kick-start the first transfer
}

三、常见问题

DMA发送缓冲区覆盖:

       调用DMA时,是让DMA0STAL 指向要发送的buf,也就是说如果在DMA执行到一半时,该缓冲区给修改了就会造成发出来的数据出现紊乱的现象。一般解决方法是申请2个或以上缓冲区,采用乒乓形式,当其中一个缓冲区正在发送时,这时候过来数据就用另一个缓冲区去接收,保证不会出现给覆盖现象。当生产数据较快,来不及发送时,可以适当扩大缓冲区,或者采用链表形式将数据保存下来,再取出来一个一个发送(这种消费较大,一般是数据相对重要时才会采用)。

首字节丢失:

      博主前面使用while(DMA0CONbits.CHEN == 1);代替while (!U1STAbits.TRMT);时,出现发送出来的首字节会丢失的现象。主要的原因是DMA0CONbits.CHEN并不是在所有数据都发送完之后,硬件自动置0,造成了没有卡住,重复调用DMA发送。当上一帧8bit数据还没发完时,下一帧进来,这时候接着发送直到停止位结束,这时候发的数据格式不是8bit数据位1bit停止位,出现异常造成首字节丢失。

猜你喜欢

转载自blog.csdn.net/wanruiou/article/details/106425232
pic
DMA