CC2530 DMA(已补充完整)

CC2530 裸机环境下dma例程,主要包括四部分,内存到内存,内存到外设,外设到内存,外设到外设,四种启动方式统一为一个函数,尾部附带完整程序

1.内存到内存

使用内存到内存dma方式,初始化如下

/****************************************************************************
* 名    称: init_dma0()
* 功    能: dma功能,内存到内存
* 入口参数: 无
* 出口参数: 无
****************************************************************************/
void init_dma0()
{
    dmaConfig0.SRCADDRH = ((uint16)&data >> 8) & 0x00FF;  // 获取到data地址(源地址)的高8位地址
    dmaConfig0.SRCADDRL = ((uint16)&data) & 0x00FF;       // 获取到data地址(源地址)的低8位地址
    dmaConfig0.DESTADDRH = ((uint16)&copy >> 8) & 0x00FF; // 获取到copy地址(目的地址)的高8位地址
    dmaConfig0.DESTADDRL = ((uint16)&copy) & 0x00FF;      // 获取到copy地址(目的地址)的低8位地址

    dmaConfig0.VLEN = DMA_VLEN_USE_LEN;            // 设置可变长度为0
    dmaConfig0.LENH = (DATA_AMOUNT >> 8) & 0x00FF; // 获取传输长度的高5位
    dmaConfig0.LENL = (DATA_AMOUNT) & 0x00FF;      // 获取传输长度的低8位

    dmaConfig0.WORDSIZE = DMA_WORDSIZE_BYTE; // 设置为字节传输模式,赋值0
    dmaConfig0.TMODE = DMA_TMODE_BLOCK;      // 块传输模式
    dmaConfig0.TRIG = DMA_TRIG_NONE;         // 无触发模式,即无触发源

    dmaConfig0.SRCINC = DMA_SRCINC_1;   // 源地址1个字节/字递增
    dmaConfig0.DESTINC = DMA_DESTINC_1; // 目的地址1个字节/字递增

    dmaConfig0.IRQMASK = DMA_IRQMASK_ENABLE; // 通道的中断使能
    dmaConfig0.M8 = DMA_M8_USE_8_BITS;        // 采用所有8位作为传输长度
    dmaConfig0.PRIORITY = DMA_PRI_HIGH;       // 高优先级,DMA优先

    DMA0CFGH = ((uint16)&dmaConfig0 >> 8) & 0x00FF; // DMA通道0配置地址高8位地址
    DMA0CFGL = ((uint16)&dmaConfig0) & 0x00FF;      // DMA通道0配置地址低8位地址

    /*清除中断标志*/
    DMAIF = 0;
    DMAIRQ &= ~DMAARM_DMAARM(0);
    DMAIE = 1;
    EA = 1;
}

2.内存到外设

使用内存到外设dma方式,初始化如下

/****************************************************************************
* 名    称: init_dma1()
* 功    能: dma功能,内存到外设
* 入口参数: sourceaddr:发送的字节数据  len:发送的长度
* 出口参数: 无
****************************************************************************/
void init_dma1(uint8* sourceaddr, uint8 len)
{
    // 测试DMA通道,DMA_TRIG_UTX1触发,data数据复制到X_U1DBUF,启用DMA中断,测试成功,DMA传输无误
    dmaConfig1.SRCADDRH = ((uint16)sourceaddr >> 8) & 0x00FF; // 获取到sourceaddr地址(源地址)的高8位地址
    dmaConfig1.SRCADDRL = ((uint16)sourceaddr) & 0x00FF;      // 获取到sourceaddr地址(源地址)的低8位地址
    dmaConfig1.DESTADDRH = ((uint16)&X_U0DBUF >> 8) & 0x00FF; // 获取到X_U0DBUF地址(目的地址)的高8位地址
    dmaConfig1.DESTADDRL = ((uint16)&X_U0DBUF) & 0x00FF;      // 获取到X_U0DBUF地址(目的地址)的低8位地址

    dmaConfig1.VLEN = DMA_VLEN_USE_LEN;    // 设置可变长度为0
    dmaConfig1.LENH = (len >> 8) & 0x00FF; // 获取传输长度的高5位
    dmaConfig1.LENL = (len) & 0x00FF;      // 获取传输长度的低8位

    dmaConfig1.WORDSIZE = DMA_WORDSIZE_BYTE; // 设置为字节传输模式,赋值0  
    dmaConfig1.TMODE = DMA_TMODE_SINGLE;     // 单字节传输模式
    dmaConfig1.TRIG = DMA_TRIG_UTX1;         // 串口发送完成触发模式
    
    dmaConfig1.SRCINC = DMA_SRCINC_1;        // 源地址1个字节/字递增
    dmaConfig1.DESTINC = DMA_DESTINC_0;      // 目的地址固定不动
   
    dmaConfig1.IRQMASK = DMA_IRQMASK_ENABLE;// 通道的中断使能
    dmaConfig1.M8 = DMA_M8_USE_8_BITS;  // 采用所有8位作为传输长度
    dmaConfig1.PRIORITY = DMA_PRI_HIGH; // 高优先级,DMA优先
    

   
    DMA1CFGH = ((uint16)&dmaConfig1 >> 8) & 0x00FF; // DMA通道1配置地址高8位地址
    DMA1CFGL = ((uint16)&dmaConfig1) & 0x00FF;      // DMA通道1配置地址低8位地址
  
    DMAIF = 0;
    DMAIRQ &= (~DMAARM_DMAARM(1));
    DMAIE = 1;
    EA = 1;   

}

3.外设到内存(已更新)

通过dma把串口接收的数据传到内存中

/****************************************************************************
* 名    称: init_dma2()
* 功    能: dma功能,外设到内存
* 入口参数: sourceaddr:发送的字节数据  len:发送的长度
* 出口参数: 无
****************************************************************************/
void init_dma2(uint8* sourceaddr, uint8 len)
{
    // 测试DMA通道,DMA_TRIG_UTX1触发,data数据复制到X_U1DBUF,启用DMA中断,测试成功,DMA传输无误
    dmaConfig.SRCADDRH = ((uint16)&X_U0DBUF >> 8) & 0x00FF; // 获取到X_U0DBUF地址(源地址)的高8位地址
    dmaConfig.SRCADDRL = ((uint16)&X_U0DBUF) & 0x00FF;      // 获取到X_U0DBUF地址(源地址)的低8位地址
    dmaConfig.DESTADDRH = ((uint16)sourceaddr >> 8) & 0x00FF; // 获取到sourceaddr地址(目的地址)的高8位地址
    dmaConfig.DESTADDRL = ((uint16)sourceaddr) & 0x00FF;      // 获取到sourceaddr地址(目的地址)的低8位地址

    dmaConfig.VLEN = DMA_VLEN_USE_LEN;    // 设置可变长度为0
    dmaConfig.LENH = (len >> 8) & 0x00FF; // 获取传输长度的高5位
    dmaConfig.LENL = (len) & 0x00FF;      // 获取传输长度的低8位

    dmaConfig.WORDSIZE = DMA_WORDSIZE_BYTE; // 设置为字节传输模式,赋值0  
    dmaConfig.TMODE = DMA_TMODE_SINGLE;     // 单字节传输模式
    dmaConfig.TRIG = DMA_TRIG_URX1;         // 串口接收完成触发模式
    
    dmaConfig.SRCINC =DMA_DESTINC_0 ;        // 源地址固定不动
    dmaConfig.DESTINC = DMA_SRCINC_1;      // 目的地址1个字节/字递增
   
    dmaConfig.IRQMASK = DMA_IRQMASK_ENABLE;// 通道的中断使能
    dmaConfig.M8 = DMA_M8_USE_8_BITS;  // 采用所有8位作为传输长度
    dmaConfig.PRIORITY = DMA_PRI_HIGH; // 高优先级,DMA优先
    


    DMA0CFGH = ((uint16)&dmaConfig >> 8) & 0x00FF; // DMA通道0配置地址高8位地址
    DMA0CFGL = ((uint16)&dmaConfig) & 0x00FF;      // DMA通道0配置地址低8位地址
  
    DMAIF = 0;
    DMAIRQ &= (~DMAARM_DMAARM(0));
    DMAIE = 1;
    EA = 1;   

}

4.外设到外设(已更新)

通过dma把adc通道0的转换结果输出到串口寄存器中


/****************************************************************************
* 名    称: init_dma3()
* 功    能: dma功能,外设到外设
* 入口参数: len:发送的长度
* 出口参数: 无
****************************************************************************/
void init_dma3()
{
    // 测试DMA通道,DMA_TRIG_ADC0,adc数据复制到X_U0DBUF,启用DMA中断,测试成功,DMA传输无误
    //源地址是adc转换完成寄存器低地址位,每次dma传输两个字节
    dmaConfig.SRCADDRH = ((uint16)&X_ADCL >> 8) & 0x00FF; // 获取到X_ADCL地址(源地址)的高8位地址,
    dmaConfig.SRCADDRL = ((uint16)&X_ADCL) & 0x00FF;      // 获取到X_ADCL地址(源地址)的低8位地址
    dmaConfig.DESTADDRH = ((uint16)&X_U0DBUF >> 8) & 0x00FF; // 获取到X_U0DBUF地址(目的地址)的高8位地址
    dmaConfig.DESTADDRL = ((uint16)&X_U0DBUF) & 0x00FF;      // 获取到X_U0DBUF地址(目的地址)的低8位地址

    dmaConfig.VLEN = DMA_VLEN_USE_LEN;    // 设置可变长度为0
    dmaConfig.LENH = (2 >> 8) & 0x00FF; // 获取传输长度的高5位
    dmaConfig.LENL = (2) & 0x00FF;      // 获取传输长度的低8位

    dmaConfig.WORDSIZE = DMA_WORDSIZE_BYTE; // 设置为字节传输模式,赋值0  
    dmaConfig.TMODE = DMA_TMODE_BLOCK_REPEATED;     // 重复块传输模式
    dmaConfig.TRIG = DMA_TRIG_ADC0;         // adc通道0转换完成触发模式
    
    dmaConfig.SRCINC = DMA_DESTINC_1 ;        // 源地址1个字节/字递增
    dmaConfig.DESTINC = DMA_DESTINC_0;      // 目的地址固定不动
   
    dmaConfig.IRQMASK = DMA_IRQMASK_ENABLE;// 通道的中断使能
    dmaConfig.M8 = DMA_M8_USE_8_BITS;  // 采用所有8位作为传输长度
    dmaConfig.PRIORITY = DMA_PRI_HIGH; // 高优先级,DMA优先
    


    DMA0CFGH = ((uint16)&dmaConfig >> 8) & 0x00FF; // DMA通道0配置地址高8位地址
    DMA0CFGL = ((uint16)&dmaConfig) & 0x00FF;      // DMA通道0配置地址低8位地址
  
    DMAIF = 0;
    DMAIRQ &= (~DMAARM_DMAARM(0));
    DMAIE = 1;
    EA = 1;   

}

5.dma启动函数以及dma中断函数

通过指定通道号启动对于的dma,在中断函数中做出对于的处理

/****************************************************************************
* 名    称: dma_start()
* 功    能: 启动dma功能
* 入口参数: dma通道号0~4
* 出口参数: 无
****************************************************************************/
void dma_start(uint8 ch)
{
    /*DMA进入工作模式通道0*/
    DMAARM |= DMAARM_DMAARM(ch); // 为了任何DMA传输能够在该通道上发生,该位必须置1,对于非重复传输模式,一旦完成传送,该位自动清0
    /*一个通道准备工作(即获得配置数据)的时间需要9个系统时钟*/
    NOP();
    NOP();
    NOP();
    NOP();
    NOP();
    NOP();
    NOP();
    NOP();
    NOP(); // 9 NOPs

}

 /****************************************************************************
* 名    称: dma_IRQ(void) dma中断处理函数 
* 描    述: 当dma完成后产生中断,可以进行相应的处理
****************************************************************************/
#pragma vector=DMA_VECTOR
__interrupt void dma_IRQ(void)
{
  
  
  if(DMAIRQ == 0x01)
  {
    
    DMAIRQ = ~DMAIRQ_DMAIF(0);
  }
  else if(DMAIRQ == 0x02)
  {
    
    DMAIRQ = ~DMAIRQ_DMAIF(1);
  }
  
  DMAIF = 0;  
}

gitee

链接: gitee链接

1.如果懂git的直接克隆即可
2.如果不懂git的话,再打开的页面中间偏右上点击《克隆/下载》按钮,再出现的页面右上角有下载zip,相当于下载压缩包,如果需要有更新的话,需要重新下载压缩包
3.该例程在DMA文件夹下

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值