打印
[综合信息]

HC32F460_DMA控制器

[复制链接]
103|0
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
Zuocidian|  楼主 | 2025-8-1 10:02 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
0.简介
       DMA用于在存储器和外围功能模块之间传送数据,能够在CPU不参与的情况下实现存储器之间,存储器与外围功能模块之间的数据交换。

拥有2个DMA控制单元,共8个独立通道,可独立操作不同的DMA传输。每个DMA控制单元中包含4个通道,每个通道可以独立配置传输功能。
4个通道优先级顺序为:通道0>通道1>通道2>通道3。

当一个DMA单元有多个通道请求传输时将按优先级顺序执行。但已处于传输中的通道不会被打断,高优先通道需等当前通道传输完成后才会启动。

每个通道的启动源通过独立的触发源选择寄存器配置
每次请求传输一个数据块。数据块最小为1个数据,最多可以是1024个数据。每个数据的宽度可配置为8bit、16bit或32bit。
源地址和目标地址可以独立配置为固定,自增,自减,循环或指定偏移量的跳转
        DMA的控制功能较为复杂,如不连续地址传输、连锁传输、中断等。本文仅介绍一些常规的操作。
        如使用DMA的目的就是为了减少中断,因此一般来讲既然使用了DMA就不会使用中断了,本文就不介绍中断了。

       DMA的具体配置与HC32F4A0基本一致,可参见《HC32F4A0_DMA控制器》

1. HC32F460_DMA例程
1.1 全局变量
unsigned char m_ucRevBuf[32];                //接收DMA数据的缓存
unsigned char m_ucRevTail=0;                //接收缓存的尾指针

#define DMA_UNIT             (M4_DMA1)                //1号DMA单元
#define DMA_CH               (DmaCh0)                        //第0个通道
#define DMA_TRG_SEL         (EVT_USART2_RI)        //触发事件是串口2的接收事件


1.2 初始配置
void DmaInit(void)
{
    stc_dma_config_t stcDmaInit;

    /* Enable peripheral clock */
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_DMA1,Enable);        //使能DMA时钟
    /* Enable DMA. */
    DMA_Cmd(DMA_UNIT,Enable);                //使能DMA1

    /* Initialize DMA. */
    MEM_ZERO_STRUCT(stcDmaInit);
    stcDmaInit.u16BlockSize = 1u;                 //1个数据块
    stcDmaInit.u32SrcAddr = ((uint32_t)(&M4_USART2->DR)+2ul); //源地址接收寄存器
    stcDmaInit.u32DesAddr = (uint32_t)(&(m_ucRevBuf[0])); //目标初始地址寄存器
    stcDmaInit.u16DesRptSize = 32;      //m_ucRevBuf的长度为32字节
       
    stcDmaInit.stcDmaChCfg.enSrcInc = AddressFix;                  //固定源地址
    stcDmaInit.stcDmaChCfg.enDesInc = AddressIncrease;          //递增目的寄存器
    stcDmaInit.stcDmaChCfg.enIntEn = Disable;                       //禁能中断
    stcDmaInit.stcDmaChCfg.enTrnWidth = Dma8Bit;                   //每个数据8位
        stcDmaInit.stcDmaChCfg.enDesRptEn  = Enable;                //使能重复区域
       
    DMA_InitChannel(DMA_UNIT, DMA_CH, &stcDmaInit);

    /* Enable the specified DMA channel. */
    DMA_ChannelCmd(DMA_UNIT, DMA_CH, Enable);
    /* Enable peripheral circuit trigger function. */
    PWC_Fcg0PeriphClockCmd(PWC_FCG0_PERIPH_AOS,Enable);        //使能AOS系统

    DMA_SetTriggerSrc(DMA_UNIT, DMA_CH, DMA_TRG_SEL);          //使能触发源
}



1.3 接收处理
short   Sci_Recv( unsigned char *pucBuf , unsigned short usBufSize)
{//(M4_DMA1->MONDAR1 为目标地址寄存器的当前位置
        unsigned short usHead = (M4_DMA1->MONDAR1 - (uint32_t)(&(m_ucRevBuf[0]))) &0x1F;
        unsigned short usLen = (usHead - m_ucRevTail) & 0x1F; //
       
        if(usHead > m_ucRevTail)                          //线性的
                memcpy( pucBuf , m_ucRevBuf + m_ucRevTail , usLen );
        else if( usHead < m_ucRevTail)                //循环的
        {
                unsigned short usHalfLen = 32 -m_ucRevTail;
                memcpy( pucBuf , m_ucRevBuf + m_ucRevTail ,  usHalfLen);
                memcpy( pucBuf + usHalfLen , m_ucRevBuf , usLen - usHalfLen );
        }
        m_ucRevTail = usHead;
        return usLen;
}
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/liyangchun_2/article/details/149153981

————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/liyangchun_2/article/details/149153981

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

70

主题

200

帖子

0

粉丝