新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > S3C2440 Mini 2440 DMA方式實(shí)現(xiàn)Uart串口通信

S3C2440 Mini 2440 DMA方式實(shí)現(xiàn)Uart串口通信

作者: 時(shí)間:2016-11-20 來(lái)源:網(wǎng)絡(luò) 收藏
搞了好久,終于完成了DMA方式實(shí)現(xiàn)串口通信。使用DMA不是很難,主要是DCONn的配置比較麻煩以及幾種模式的理解。

本文引用地址:http://butianyuan.cn/article/201611/318593.htm

DMA service mode:single service&Whole service。前一模式下,一次DMA請(qǐng)求完成一項(xiàng)原子操作,并且transfer count的值減1。后一模式下,一次DMA請(qǐng)求完成一批原子操作,直到transfer count等于0表示完成一次整體服務(wù)。具體對(duì)應(yīng)DCON[27]。

DMA DREQ/DACK PROTOCOL:DMA請(qǐng)求和應(yīng)答的協(xié)議有兩種,Demond mode 和 Handshake mode。兩者對(duì)Request和Ack的時(shí)序定義有所不同:

在Demond模式下,如果DMA完成一次請(qǐng)求后如果Request仍然有效,那么DMA就認(rèn)為這是下一次DMA請(qǐng)求,并立即開(kāi)始下一次的傳輸;

在Handshake模式下,DMA完成一次請(qǐng)求后等待Request信號(hào)無(wú)效,如果Request無(wú)效,DMA會(huì)無(wú)效ACK兩個(gè)時(shí)鐘周期,再等待下一次Request。


/*

功能:用DMA方式實(shí)現(xiàn)串口傳輸,
將字符串?dāng)?shù)據(jù)通過(guò)DMA0通道傳遞給UTXH0,然后在終端
顯示。數(shù)據(jù)傳輸完后,DMA0產(chǎn)生中斷,LED1亮。

Mini2440 調(diào)試通過(guò)
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


}


/*時(shí)鐘配置/
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中斷服務(wù)函數(shù)*/
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;
}



評(píng)論


技術(shù)專區(qū)

關(guān)閉