您的位置:首页 > 其它

S3C2440 Mini 2440 DMA方式实现Uart(串口)通信

2013-05-16 12:50 375 查看
转自:http://blog.csdn.net/fengyaqi123/article/details/7833300

参考一下

搞了好久,终于完成了DMA方式实现串口通信。使用DMA不是很难,主要是DCONn的配置比较麻烦以及几种模式的理解。

DMA service mode:single service&Whole service。前一模式下,一次DMA请求完成一项原子操作,并且transfer count的值减1。后一模式下,一次DMA请求完成一批原子操作,直到transfer count等于0表示完成一次整体服务。具体对应DCON[27]。

DMA DREQ/DACK PROTOCOL:DMA请求和应答的协议有两种,Demond mode 和 Handshake mode。两者对Request和Ack的时序定义有所不同:

在Demond模式下,如果DMA完成一次请求后如果Request仍然有效,那么DMA就认为这是下一次DMA请求,并立即开始下一次的传输;
在Handshake模式下,DMA完成一次请求后等待Request信号无效,如果Request无效,DMA会无效ACK两个时钟周期,再等待下一次Request。

/***********************************************************************

功能:用DMA方式实现串口传输,

将字符串数据通过DMA0通道传递给UTXH0,然后在终端

显示。数据传输完后,DMA0产生中断,LED1亮。

************************************************************************

Mini2440 调试通过

2012-08-05

*********************************************************************/

#include "2440addr.h"

#define MDIV 92

#define SDIV 1

#define PDIV 1

#define HDIVN 2

#define PDIVN 1

#define PCLK_ 50000000

#define Led1_on() {rGPBDAT&=(~(1<<5)); }

char *SendBuffer = "Hello world!" ; //source data

/*****************LED 初始化************************************/

void Led_init()

{

rGPBCON &=~((3<<10) | (3<<12) | (3<<14) | (3<<16)|(3<<0));

rGPBCON |=((1<<10) | (1<<12) | (1<<14) | (1<<16)|(1<<0));

rGPBUP &=~((1<<5) | (1<<6) | (1<<7) | (1<<8)|(1<<0));

rGPBDAT =0xfffe;

}

/*****************UART0 io口初始化****************************/

void Uart0_io_init() //uart io port

{

rGPHCON =0xa0; //gph2,gph3 used for txd0,rxd0.

rGPHUP=0x0; //enable the pull up function

}

/***************************UART0配置****************************/

void Uart0_init(int bandrate)

{

rULCON0 |=0x3; //8-bit data ,1bit stop

rUCON0 |=((1<<0) | (1<<3) | (2<<10) ); //used pclk as the clock, transmit use DMA mode , receive use polling mode

rUBRDIV0=(int)(PCLK_/(bandrate*16))-1 ; //bandrate is 115200

}

/***************************时钟配置********************************************/

void Clk_init( )

{

rCLKCON |=(1<<10); //enable uart0 used pclk

rLOCKTIME=0xffff; //locktime

rCLKCON |=(1<<13); //gpio enable pclk

rCLKDIVN =((PDIVN<<0) | (HDIVN<<1)); //1:4:8

rMPLLCON |=((MDIV<<12) | (PDIV<<4) | (SDIV<<0)); // f_out=400MHZ

//__asm{

// mrc p15, 0, r1, c1, c0, 0

// orr r1, r1, #0xc0000000

//mcr p15, 0, r1, c1, c0, 0

// }

}

/*****************************DMA初始化***************************************/

void Dma_init()

{

rGPBCON |=((1<<19)|(1<<21)); //GPB9,10 used for nXDACK0,nXDREQ0

rDISRC0=(U32)SendBuffer; //source data address

rDISRCC0 |=((0<<1)|(0<<0)); //address increment , the source is in the AHB

rDIDST0=(U32)UTXH0; //destination is UTXH0

rDIDSTC0 |=((0<<2)|(1<<1)|(1<<0)); //address not change , APB , enable interrupt

rDCON0 |=(1<<31)|(0<<30)|(1<<29)|(0<<28)|(0<<27)|(1<<24)|(1<<23)|(1<<22)|(0<<20)|(12);

//Handshake mode, PCLK synchronization ,enable dma interrupt , unit transfer , single service ,

//UART0 is the request source, H/W request mode ,disable auto reload , Byte transmit ,12 Byte data

rDMASKTRIG0=(0<<2)|(1<<1)|(0<<0); //start dma transmit

}

/**********************DMA中断初始化***************************************/

void Dma_eint()

{

rINTMSK &=~(1<<17); //open the dma0 interrupt

}

/************************DMA中断服务函数*********************************/

void __irq Dma_isr()

{

rSRCPND|=(1<<17); //clear the srcpnd

rINTPND |=(1<<17); //clear the int pnd

Led1_on();

}

int Main()

{

Clk_init();

Led_init();

Uart0_io_init();

Uart0_init(115200);

Dma_eint();

pISR_DMA0=(U32) Dma_isr;

Dma_init();

while(1)

{

;

}

return 0;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: