新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM學習《十一》—不用庫函數自己動手配置STM32中的DMA

        ARM學習《十一》—不用庫函數自己動手配置STM32中的DMA

        作者: 時間:2016-11-20 來源:網絡 收藏
        今天調試的STM32DMA部分,第一次接觸這部分,8位的單片機沒有這部分的功能,一開始感覺這東西很神秘,所以懷著敬畏的心情來學習它。慢慢的發現這確實是個好東西,功能強大,可以分擔CPU的任務。但它沒有想象中那么棘手。

        DMA英文全稱是Direct Memory Access,意思是直接存儲器訪問。他的作用就是不需要經過CUP進行數據傳輸,也就是替CPU分擔點事情做,什么事情?數據傳輸方面的事情。也就是說,你只要使能并配置好了DMA,DMA就可以將一批數據從源地址搬運到目的地址去而不經過CPU的干預,這樣可以為CPU節省好多精力去干更重要的事情很人性化。就像我們人一樣,我們平常習慣性的動作是不用經過大腦思考的,比如說眨眼睛,呼吸等。DMA就是負責這些工作的,但它沒人這么智能,需要將它設置好了它才會正常工作。

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

        要進行數據傳輸就必須有兩個條件:數據從哪傳(源地址),數據傳到哪里去(目的地址)。是的DMA的確有這兩項設置,通過軟件設置,設置好源地址和目的地址。在一個重要的條件就是觸發源是什么,就是說什么時候進行DMA數據傳輸呢?這叫觸發信號。也可以通過軟件編程設置具體時間,具體條件來觸發DMA數據傳輸。

        總之,要使用DMA就要將各種參數,條件配置好才可以用。就提的DMA寄存器說明見STM32的參考手冊。下面舉一簡單的歷程來說明DMA的用法,本歷程將串口數據發送設置為DMA模式,串口1將持續從RAM中的一段連續的地址中取數據,然后發送出去。用串口調試助手可以監測DMA的工作和CPU互不沖突,串口發送就相當于后臺運行的一段程序。具體配置如下:

        寄存器定義:

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

        //

        // DMA-Register

        //

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

        #define DMA_ISR(*((volatile unsigned long *)0x40020000)) //中斷狀態寄存器

        #define DMA_IFCR(*((volatile unsigned long *)0x40020004))//中斷標志清零寄存器

        #define DMA_CCR1(*((volatile unsigned long *)0x40020008))//通道1配置寄存器

        #define DMA_CCR2(*((volatile unsigned long *)0x4002001C))//通道2配置寄存器

        #define DMA_CCR3(*((volatile unsigned long *)0x40020030))//通道3配置寄存器

        #define DMA_CCR4(*((volatile unsigned long *)0x40020044))//通道4配置寄存器

        #define DMA_CCR5(*((volatile unsigned long *)0x40020058))//通道5配置寄存器

        #define DMA_CCR6(*((volatile unsigned long *)0x4002006C))//通道6配置寄存器

        #define DMA_CCR7(*((volatile unsigned long *)0x40020080))//通道7配置寄存器

        #define DMA_CNDTR1(*((volatile unsigned long *)0x4002000C))//通道1傳輸數量寄存器

        #define DMA_CNDTR2(*((volatile unsigned long *)0x40020020))//通道2傳輸數量寄存器

        #define DMA_CNDTR3(*((volatile unsigned long *)0x40020034))//通道3傳輸數量寄存器

        #define DMA_CNDTR4(*((volatile unsigned long *)0x40020048))//通道4傳輸數量寄存器

        #define DMA_CNDTR5(*((volatile unsigned long *)0x4002005C))//通道5傳輸數量寄存器

        #define DMA_CNDTR6(*((volatile unsigned long *)0x40020070))//通道6傳輸數量寄存器

        #define DMA_CNDTR7(*((volatile unsigned long *)0x40020084))//通道7傳輸數量寄存器

        #define DMA_CPAR1(*((volatile unsigned long *)0x40020010))//通道1外設地址寄存器

        #define DMA_CPAR2(*((volatile unsigned long *)0x40020024))//通道2外設地址寄存器

        #define DMA_CPAR3(*((volatile unsigned long *)0x40020038))//通道3外設地址寄存器

        #define DMA_CPAR4(*((volatile unsigned long *)0x4002004C))//通道4外設地址寄存器

        #define DMA_CPAR5(*((volatile unsigned long *)0x40020060))//通道5外設地址寄存器

        #define DMA_CPAR6(*((volatile unsigned long *)0x40020074))//通道6外設地址寄存器

        #define DMA_CPAR7(*((volatile unsigned long *)0x40020088))//通道7外設地址寄存器

        #define DMA_CMAR1(*((volatile unsigned long *)0x40020014))//通道1存儲器地址寄存器

        #define DMA_CMAR2(*((volatile unsigned long *)0x40020028))//通道2存儲器地址寄存器

        #define DMA_CMAR3(*((volatile unsigned long *)0x4002003C))//通道3存儲器地址寄存器

        #define DMA_CMAR4(*((volatile unsigned long *)0x40020050))//通道4存儲器地址寄存器

        #define DMA_CMAR5(*((volatile unsigned long *)0x40020064))//通道5存儲器地址寄存器

        #define DMA_CMAR6(*((volatile unsigned long *)0x40020078))//通道6存儲器地址寄存器

        #define DMA_CMAR7(*((volatile unsigned long *)0x4002008C))//通道7存儲器地址寄存器

        配置DMA,手冊上表示可以將串口UART1的發送Tx功能配置為DMA發送,在DMA通道4:

        void DMA_configration(void)

        {

        //DMA設置:

        //設置DMA源:內存地址&串口數據寄存器地址

        //方向:內存-->外設

        //每次傳輸位:8bit

        //傳輸大小:10字節

        //地址自增模式:外設地址不增,內存地址自增1

        //DMA模式:循環

        //優先級:高

        RCC_AHBENR|=0x00000001; //位0 DMAEN DMA時鐘使能

        DMA_CCR4&=0xFFFF800E;//0:通道禁用

        DMA_CPAR4=(unsigned long)&USART1_DR;

        DMA_CMAR4=(unsigned long)Data_Buffer;

        DMA_CNDTR4=10;

        DMA_CCR4=0x00000000;

        DMA_CCR4|=0x000030B0;

        //DMA_CCR4|=0x00000001;//DMA使能

        }

        Main函數:

        unsigned char Data_Buffer[10]={0x11,0x22,0x33,0x44,0x55};

        //將Data_Buffer設為全局變量

        int main()

        {

        SystemInit0();//系統(時鐘)初始化

        stm32_UsartSetup ();//串口初始化,前面的文章中有介紹

        DMA_configration();// DMA配置

        USART1_CR3|=0x00000080; //將USART1模塊發送數據Tx設置成DMA方式工作

        DMA_CCR4|=0x00000001;//使能DMA

        while(1)

        {

        //CPU可以不受打擾的做其他事情

        }

        }

        打開串口助手就可以看到Data_Buffer[]中的數據,其實這只是一個簡單的演示實例,DMA的用處是很大的,先學會配置,以后會有它大顯身手的時候。

        USART1_CR3|=0x00000080; //將USART1模塊發送數據Tx設置成DMA方式工作

        DMA_CCR4|=0x00000001;//使能DMA

        上面這兩句就是觸發源,你可以把這兩句放到定時器TIMx中,比如定時1S觸發DMA,這些都是可以任意設置的,不難吧!




        評論


        技術專區

        關閉
        主站蜘蛛池模板: 佳木斯市| 天全县| 青冈县| 女性| 赣榆县| 加查县| 通州区| 五华县| 无为县| 佛学| 庆元县| 桐城市| 彭泽县| 青冈县| 汝阳县| 甘南县| 利辛县| 全南县| 大安市| 五台县| 伊宁县| 南江县| 小金县| 黄浦区| 峨边| 云安县| 绥芬河市| 宁强县| 乳山市| 敦煌市| 柘荣县| 炉霍县| 五寨县| 兴国县| 连州市| 思南县| 衡水市| 仪征市| 德保县| 白水县| 延川县|