[国嵌攻略][059][2440-DMA程序设计]
初始化DMA控制器
1.设置源地址
DISRC(0x4B000000)设置为发送数据的源地址,DISRCC0(0x4B0000004)设置为内存AHB总线,目的地址增长
2.设置目的地址
DIDST0(0x4B00000C)设置为发送数据的目的地址,DIDSTC0设置中断模式为数据减为0,设置串口APH总线,目的地址不增长
3.设置DMA控制寄存器
DCON0(0x4B000010)设置请求源为中断(26-24位),设置DMA请求源为硬件(23位),关闭重载(22位),设置发送数据长度(19-0位)
4.打开DMA传输
DMASKTRIG0(0x4B000020)设置为打开(1位)
/******************************************************************** *名称:dma *作者:D *时间:2015.11.17 *功能:直接存储访问控制器 ********************************************************************/ /******************************************************************** * 宏定义 ********************************************************************/ #define DISRC0 ( (*(volatile unsigned long *)0x4B000000) ) //DMA0初始化源地址寄存器 #define DISRCC0 ( (*(volatile unsigned long *)0x4B000004) ) //DMA0初始化源地址控制寄存器 #define DIDST0 ( (*(volatile unsigned long *)0x4B000008) ) //DMA0初始化目的地址寄存器 #define DIDSTC0 ( (*(volatile unsigned long *)0x4B00000C) ) //DMA0初始化目的地址控制寄存器 #define DCON0 ( (*(volatile unsigned long *)0x4B000010) ) //DMA0控制寄存器 #define DMASKTRIG0 ( (*(volatile unsigned long *)0x4B000020) ) //DMA0掩码触发寄存器 /******************************************************************** *名称:memcopy *参数: src 源地址 dst 目的地址 len 数据长度 *返回: none *功能:内存数据复制 *********************************************************************/ void memcopy(const char *src, char *dst, int len){ //初始化源地址和目的地址 DISRC0 = (unsigned long)src; //地址转换为32位无符号类型 DISRCC0 = 0; //LOC[1]:0 AHB, INC[0]:0 Increment DIDST0 = (unsigned long)dst; DIDSTC0 = 0; //CHK_INT[2]:0 TC reaches 0, LOC[1]:0 AHB, INC[0]:0 Increment //初始化DMA控制寄存器 //DMD_HS[31]:1 Handshake SYNC[30]:1 HCLK, INT[29]:0 Disable interrup, SERVMODE[27]:1 Whole service, SWHW_SEL[23]:1, RELOAD[22]:1 turned off reload, TC[19:0]:len DCON0 = (1<<31)|(1<<30)|(1<<27)|(1<<22)|(len&0xFFFFF); //打开DAM传输 DMASKTRIG0 = (1<<1)|(1<<0); }
/******************************************************************** *名称:uartsend *参数: adr 内存地址 len 数据长度 *返回: none *功能:使用DMA发送数据到串口 *********************************************************************/ void uartsend(const char *adr, int len){ //设置串口为DMA工作模式 UCON0 = (0x2<<2)|(0x2<<0); //设置recevi mode[1:0]:10 DMA mode, transmit mode[3:2]:10 DMA mode, clock selection[11:10]:00 PCLK //注意:在串口初始化时已经初始化为了轮询模式,因为这里要使用DMA所以设置为DMA模式 //串口打印函数仍然使用轮询模式实现,设置成DMA模式后并没有恢复为轮询模式 //初始化源地址和目的地址 DISRC0 = (unsigned long)adr; //地址转换为32位无符号类型 DISRCC0 = 0; //LOC[1]:0 AHB, INC[0]:0 Increment DIDST0 = (unsigned long)&UTXH0; //取UTXH0寄存器地址 DIDSTC0 = (1<<1)|(1<<0); //CHK_INT[2]:0 TC reaches 0, LOC[1]:1 APB, INC[0]:1 Fixed //初始化DMA控制寄存器 //DMD_HS[31]:1 Handshake SYNC[30]:0 PCLK, INT[29]:0 Disable interrup, SERVMODE[27]:0 Single service, SWHW_SEL[23]:1, RELOAD[22]:1 turned off reload, TC[19:0]:len DCON0 = (1<<31)|(0<<30)|(0<<27)|(1<<24)|(1<<23)|(1<<22)|(len&0xFFFFF); //注意:DMD_HS设置为Demand和Handshake模式串口都可以正常,推荐的是Handshake,可以预防意外情况 //SERVMODE必须设置为Single模式,因为串口初始化时没有使用FIFO,如果使用Whole,只能收到最后一个字符 //打开DAM传输 DMASKTRIG0 = (1<<1); //设置ON_OFF[1]:1 turn on }
参考网址:
http://blog.sina.com.cn/s/blog_56dee71a0100dwik.html~type=v5_one&label=rela_nextarticle