CC2530 裸机DMAdemo(已补充完整)
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)© >> 8) & 0x00FF; // 获取到copy地址(目的地址)的高8位地址
dmaConfig0.DESTADDRL = ((uint16)©) & 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文件夹下
3701

被折叠的 条评论
为什么被折叠?



