新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > S3C2440 Mini 2440 DMA方式實現Uart(串口)通信

        S3C2440 Mini 2440 DMA方式實現Uart(串口)通信

        作者: 時間:2016-11-09 來源:網絡 收藏
        搞了好久,終于完成了DMA方式實現串口通信。使用DMA不是很難,主要是DCONn的配置比較麻煩以及幾種模式的理解。

        本文引用地址:http://www.104case.com/article/201611/317614.htm

        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;
        }


        評論


        相關推薦

        技術專區

        關閉
        主站蜘蛛池模板: 彭阳县| 新源县| 镇原县| 梨树县| 平原县| 北海市| 青阳县| 自治县| 新余市| 出国| 长汀县| 江门市| 穆棱市| 罗江县| 舟曲县| 称多县| 会东县| 红原县| 武宁县| 福安市| 东乌珠穆沁旗| 乌鲁木齐县| 文成县| 嘉定区| 涞水县| 广南县| 依安县| 左云县| 定日县| 如东县| 乃东县| 顺平县| 大悟县| 阿克苏市| 仪陇县| 太谷县| 辉南县| 茌平县| 蓬莱市| 宾阳县| 绩溪县|