您的位置 首页 IC

第7课:DMA

DMA用来连接外部设备和内部设备之间的数据传输。有了它就可以绕开CPU,直接进行数据传输。但同时DMA的传输也会用到数据总线。所以它的使用…

DMA用来衔接外部设备和内部设备之间的数据传输。有了它就能够绕开CPU,直接进行数据传输。但一起DMA的传输也会用到数据总线。所以它的运用也是有利有弊的。

DMA使用了有限状况机来剖析。它分红3个状况。

状况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 != \0) {
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(“\r\n”);

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(“\r\n”);
}

这个是中止是ISR

#include”s3c2440.h”

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

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/bandaoti/274799.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部