一、通过串口发送解析为什么需要DMA
之前的程序串口如果要发送一个字符串,就需要调用cpu不断对UTXH0输入字符,达到输出字符串。
但是这样占用了太多CPU的时间,显然是一个低效率的方式。所以可以用DMA,让CPU告诉DMA哪些数据需要对I/O口操作,DMA照着执行就好了。
这样就可以释放CPU的使用。
二、DMA控制器
2.1 通道数
The S3C2440A supports four-channel DMA controller located between the system bus and the peripheral bus.
2.2 请求源
四个通道分别可以设置不同的请求源:
2.3 基本时序
nXDREQ请求生效并经过2CLK周期同步后,nXDACK
响应并开始生效,但至少还要经过3CLK的周期延迟,DMA控制器才可获得总线的控制权,并开始数据传输。
2.4 工作模式
Demond模式:
如果
DMA完成一次请求后如果
Request仍然有效,那么
DMA就认为这是下一次
DMA请求,并立即开始下一次的传输
Handshake模式:
DMA完成一次请求后等待
Request信号无效,如果
Request无效,
DMA会无效
ACK两个时钟周期,再等待下一次
Request。
三、2440DMA程序设计
-
#define DISRC0 *((volatile unsigned long*)0x4B000000)
-
#define DISRCC0 *((volatile unsigned long*)0x4B000004)
-
#define DIDST0 *((volatile unsigned long*)0x4B000008)
-
#define DIDSTC0 *((volatile unsigned long*)0x4B00000C)
-
#define DCON0 *((volatile unsigned long*)0x4B000010)
-
#define DMASKTRIG0 *((volatile unsigned long*)0x4B000020)
-
-
#define UTXH0 (volatile unsigned long*)0x50000020
-
-
char *buf = "Hello World!";
-
-
void dma_init()
-
{
-
//初始化原地址
-
DISRC0 = (unsigned int)buf; //源地址
-
DISRCC0 = (0<<1)|(0<<0);
-
-
//初始化目的地址
-
DIDST0 = UTXH0; //目的地址,串口的地址
-
DIDSTC0 = (0<<2)|(1<<1)|(1<<0);
-
-
DCON0 = (1<<24)|(1<<23)|(1<<22)|(12<<0);
-
-
}
-
-
void dma_start()
-
{
-
DMASKTRIG0 = (1<<1);
-
}
这样在main.c中调用dma_init()和dma_start();并不能实现hello world!。
在uart.c中的发送模式需要修改成DMA模式
-
void uart_init()
-
{
-
//1.配置引脚功能
-
GPHCON &= ~(0xf<<4);
-
GPHCON |= (0xa<<4);
-
-
//2.1设置数据格式
-
ULCON0 = 0b11;
-
//2.2设置工作模式
-
//UCON0 = 0b0101;中断轮循
-
UCON0 = 0b1001;
-
-
//3.设置波特率
-
UBRDIV0 = (int)(PCLK / (BAUD *16) - 1);
-
}
阅读(624) | 评论(0) | 转发(0) |