[国嵌攻略][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

原文地址:https://www.cnblogs.com/d442130165/p/4972671.html