(學習筆記)stm32f429——DMA控制器

DMA(Direct Memory Access,直接存儲器訪問)。什麼提高cpu效率,什麼工作原理都不管,高速傳輸也不說。

只說兩個案例,存儲器到存儲器的模式 + 存儲器到外設的模式 。

從DMA框圖上來說,DMA由以下組成:首先是數據流,f429有0~7這8條數據流;接着是通道選擇,每條數據流對應0~7這8個通道,數據流與通道選擇形成一個表格,具體外設對應固定的流和通道,由查參考手冊中的表可得;然後是仲裁器,當外設DMA請求衝突時,由仲裁器規則決定執行對象,這個仲裁器好比分兩個層次,先是軟件設置優先級(有4個優先級),當兩個請求優先級相同時,由硬件決定——編號低的數據流優先於編號高的數據流;最後是FIFO(First In First Out,(這不就是隊嘛)。。。),這是32位先進先出的存儲器緩衝區。

說下FIFO的模式:直接模式和FIFO模式。直接模式是禁止FIFO模式下的默認模式,在這種模式下,初始化DMA之後,源的數據直接進入FIFO緩衝區,DMA請求一來就開始傳輸數據。在這種模式下,源與目標數據寬度必須相同,而且數據流只能生成單次傳輸,手冊中說由硬件強制配置。(這邊得提一下一個問題,中文參考手冊在存儲器到存儲器的模式下有一個注意點:使用存儲器到存儲器的模式時,不允許循環模式和直接模式。但是,在Flash到SRAM的實例中,直接模式是行得通的,FIFO模式倒是沒有嘗試。)

FIFO模式,源與目標的數據寬度可以不同,通過設置FIFO閾值來限制或者是擴展數據寬度,實現突發。FIFO我是真的不是很清楚,在下面的存儲器到外設的實例有所嘗試。

DMA的初始化就簡單點說:1、打開時鐘,兩個DMA都掛載到AHB1上       2、調用DMA_DeInit()復位數據流寄存器 ,通過DMA_GetCmdStatus()判斷復位是否完成

3、初始化結構體,配置各種參數 4、DMA_Cmd()使能DMA,並通過DMA_GetCmdStatus()等待數據裏有效               5、發送DMA請求

在存儲器到存儲器的實例中,在Flash中定義一段數組const uint32_t aSRC_Const_Buffer[BUFFER_SIZE],因爲在DMA中發送數據項數是一定得知道的,除了SDIO外設。定義一個相同大小的變量數組,存放在SRAM內。存儲器到存儲器的模式中不需要DMA請求,在使能DMA之後開始傳輸數據。這邊的初始化結構體應該不需要說明。地址都是數組名,數據項數是BUFFER_SIZE,得使能外設和存儲器的地址自增功能。最後需要寫一個校驗函數來檢驗傳輸是否正確,即比較兩個數組是否相等。

在存儲器到外設的實例中,定義一個存儲器中的數組,將這段數據通過USART1,再通過USB傳輸顯示到PC上的串口調試工具。

先是用了直接模式,定義了一個8位的數組,只需要在初始化中關閉外設地址自增功能(外設數據寄存器地址唯一),在main函數中請求DMA發送就可以接收。這邊有一點小貓膩,以爲USART是8位串口傳輸的,正好數組是8位的,所以傳輸結果正確。我也沒去試試16位的直接模式,明天試試吧。

然後因爲對FIFO模式的不理解,嘗試了下。說下菜鳥的嘗試過程:決定還是定義8位數組,但是目的數據寬度設置爲半字,使能FIFO,設置閾值爲1/4滿,1/4滿是1個字,我定義數組爲{‘A’,'B','C','D'};(在FIFO模式下如果設置目標數據寬度爲字節,結果正確。)

結果顯示爲AC,16位進制顯示結果爲41 43 00 00;

之後數組定義爲{‘A’,'0','B','0','C','0','D','0'};,這回顯示結果爲ABCD,16進制顯示結果爲41 42 43 44 00 00 00 00。

然後大概明白是因爲USART是8位傳輸的原因,但是後面的4個00 是什麼原因也是不明白。

有沒有大神給我講講突發模式中的節拍增量是什麼意思?手冊看不懂勒。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章