新闻中心

第7课:DMA

作者:时间:2016-11-11来源:网络收藏
A用来连接外部设备和内部设备之间的数据传输。有了它就可以绕开CPU,直接进行数据传输。但同时A的传输也会用到数据总线。所以它的使用也是有利有弊的。

A利用了有限状态机来分析。它分成3个状态。

本文引用地址:http://www.eepw.com.cn/article/201611/316800.htm

状态1等待REQ,一切状态为0

状态2这个状态已经接受到了REQ,这个时候把CNT中的值导入到DMA中的CURR—TC中,然后ACK就变成了1

状态3这个时候分为2个有限状态机,子机用来作数据传输,从源地址取数据,再写到目标地址。而主机负责计数,以及计数到0的中断等。。。

其实 有限状态机FSM这种分析方法简单来说就是把过程的变化无视掉,转而只看状态稳定后的结果。

以下来介绍在传输中的3种基本分类。

第一类 是 单元式 和 突发式 unit and brust

unit 发送1个Byte,而brust发送4个。

第2类 服务类 单一服务 和 连续服务 single and whole

单一服务本质上来讲就是做一个原子操作 必须再从状态1到状态3再走一遍,也就是说 需要等待REQ的这比有请求。而连续服务则在CURR_TC中的计数到0才停止。但是需要注意的一点:虽然是连续的,但是它也要短暂的释放数据总线,来给“饥渴”的CPU控制。

第3类 请求式和握手式 demand and shake

请求式就是当ACK结束整个一次传输后,恢复到0,发现REQ仍然是1的话,继续进行传输。

而shake mode 指的是 ,ACK完成一次传输后,一定要等到REQ 变成0,来确认才能继续进行。不然会一直等待。

请求式单服务,握手式单服务,握手式全服务,请求式全服务。一般如果是外设对外设的话,推荐使用请求全服务。

而从速度上来讲,连续服务的确比单服务快一点。

简单说下需要设置的寄存器。

因为我们有4组DMA,每组要设置的寄存器是9个,所以总共算术36个。

在9个中,前4个设置源地址,源地址的控制,目标地址,目标地址的控制等选项。

第5个是DMA控制寄存器,它要可以设置DMA的模式等具体的内容。

第6,7个是看源地址和目标地址在现在的数值。

而第8个是看CT内部计数器中,递减到了几。

第9个是控制DMA启动和停止的寄存器。例如在单一模式下,传完一次 on/off位会自动置0,需要再次置1才能再次传输

以下来进行举例:

写一个程序 利用分别利用DMA传输1M数据,另外一个正常拷贝,利用定时器PWM来计时 并输出到UART串口中。基本上除了中断,前2次用到的设备这次都利用到了。

#include"s3c2440.h"
#define UART_CLK 50000000
#define UART_BAUD_RATE 115200
#define UART_BRD (int)(UART_CLK/(UART_BAUD_RATE *16))-1

int n=0; //定义外部变量

void init_uart()
{
rGPHCON |=0xa0;
rGPHUP = 0x0c;
rULCON0 = 0x3;
rUCON0 = 0x5;
rUFCON0 = 0;
rUMCON0 = 0;
rUBRDIV0 = UART_BRD;
}

void init_timer0() //初始化pwm,0.5秒计65535次数
{
rTCFG0 = 0x63;
rTCFG1 = 0x1;
rTCNTB0 = 0xFFFF;
rTCON = 0xa;
rTCON = 0x9;
}

void init_irq()
{
rINTMOD = 0;
rINTMSK = ~(1<<10);//计时到0进入ISR,其中进行计数的累加,和小灯亮暗处理,小灯亮暗 为了说明进入了中断
}

void uart_write(char *data)
{
while (*data != ) {
while (!(rUTRSTAT0 & 0x4));
rUTXH0 = *data;
data++;
}
}

void init_dma()
{
rDISRC0 = 0x31000000;//初始化源地址
rDISRCC0 = 0x0;
rDIDST0 = 0x32000000;
rDIDSTC0 = 0x4;
rDCON0 = 0xb820ffff; //设置为模式
}

void long2char(long n)// 65535 is half second 把计数的值变成2进制,输出到uart中。
{
int c=32;
while(c!=0){
if(n&(0x1<<31))
uart_write("1");
else
uart_write("0");
c--;
n=n<<1;
}
}

void init_led()
{
rGPECON = GPE12_out|GPE13_out;
}

int main()
{
init_uart();
init_led();
init_irq();
init_timer0();
long t,t1,t2,num;
char *src = (char *)0x31000000;
char *obj = (char *)0x32000000;
num = 1024*1024;
n=0;
t1= (long)rTCNTO0;//t1第一次计数
uart_write("This is the time of normal memory copy :");
while(num>0){
*obj++ = *src++;//正常的拷贝
num--;
}
t2= (long)rTCNTO0;//t2第2次
t = (t1-t2)+65535*n;//计算时间差
long2char(t);
uart_write("rn");

init_dma();
n = 0;
t1 = rTCNTO0;
rDMASKTRIG0 = 3; //set the reg and then DMA will operate
while(rDSTAT0 & 0x1<<20);
t2 = rTCNTO0;
t= (t1-t2)+65535*n;
uart_write("This is the time of DMA :");
long2char(t);
uart_write("rn");
}

这个是中断是ISR

#include"s3c2440.h"

void ISR_Handle()
{
extern int n;//外部变量的声明
n++;
rGPEDAT ^= (3<<12);
rSRCPND = 1<<10;
rINTPND = 1<<10;
}



关键词: DM

评论


相关推荐

技术专区

关闭