實現STM32中USART的DMA

2021-06-04 03:20:06 字數 2861 閱讀 9022

2023年06月29日 星期二 20:56

終於開葷了~~~

dma

先抄一小段dma的說明。

對於沒玩過dma 的朋友,這裡簡單說一下dma,用自己的語言說吧,那就是,從某個位置

傳輸資料到某個位置,如果不用dma,那要cpu參與操作,乙個位元組乙個位元組地搬,效率高

點的,就乙個字乙個字地搬.但當你用了dma 後,那就是只需要設定:a.從**開始搬; b,

搬到**去;c以位元組方式搬還是半字還是字;d:一共搬多少個.之後,啟動dma.cpu內部

就會開始搬資料了,整個搬資料的過程都不需要指令的參與,唯一要做的,就是檢測什麼時

候搬完.你可以掃瞄暫存器,也可以用中斷.這裡,我使用了中斷.

具體設定功能看注釋就可以明白了.注意一點就是,有乙個設定:

dma_initstructure.dma_peripheralinc = dma_peripheralinc_disable;

這個是外設的位址不遞增.也就是說,每次搬動,都是從源頭,也就是usart1的dr暫存器

搬,但記憶體位址卻是遞增的:

dma_initstructure.dma_memoryinc = dma_memoryinc_enable;

這個歷程實現了 接受 串列埠的資料 寫到flash 之中工作,而dma的作用在於將 串列埠收暫存器 usart1->dr 的 資料寫到記憶體之中 比如某個陣列之中 u8 usart1_dma_buf1[512]; 寫滿512個位元組之後將進入dma中斷(通道5)在這裡修改dma 的記憶體寫入入口

u8 usart1_dma_buf2[512]; ,同時標記 下次的入口free_buf_no=buf_no1; 與 buf_ok=true; 證明已有資料準備完成。這時cup將usart1_dma_buf1中的資料寫入flash .

又抄了一點

這次使用的是雙緩衝,也有人

叫桌球緩衝.因為一般情況下,串列埠的資料dma 傳輸進buf1 的過程中,是不建議對

buf1 進行操作的.但由於串列埠資料是不會等待的直傳,所以你總不能等buf1 滿了,

才往flash 上寫,因為這時候串列埠資料依舊是源源不斷.於是,使用雙緩衝就變的理

所當然了.當buf1 滿了的時候,就馬上設定dma的目標為buf2,並且buf1的資料

往25f080上灌.當串列埠dma寫滿了buf2的時候,再設定dma的目標為buf1,此時

再操作buf2寫進25f080.如此一直迴圈,就好像打桌球那樣吧,所以就叫桌球緩衝.

用這個方法的速度極限就是,你必須確保兩點a.dma 灌滿了buf1 的時候,會發生中

斷,此時切換dma 的目標緩衝為buf2,而且切換的過程必須在新的串列埠資料溢位之

前完成.b.在dma的buf1滿之前,另外乙個有資料的buf2必須能全部寫進25f080,

其中包括了遇到新的扇區邊界而要刷除扇區的操作時間!!

可以看出,buf的增大,並不能夠很大程度的提公升速度極限.

/************dma方式傳輸***************************/

#definesrc_usart1_dr    (&(usart1->dr))       

//串列埠接收暫存器作為源頭

//dma目標緩衝,這裡使用雙緩衝

u8usart1_dma_buf1[512];

u8usart1_dma_buf2[512];

boolbuf_ok;   

//buf是否已經可用

buf_nofree_buf_no;       

//空閒的buf號

typedefenumbuf_no;

dma_inittypedefdma_initstructure;

voidusart_dmatobuf1(void)

再來看看dma中斷:

//u16datacounter;

externdma_inittypedefdma_initstructure;

voiddma1_channel5_irqhandler(void)

else

buf_ok=true;

//有準備好的資料了

}

}

寫flash的操作

while(1)

if(free_buf_no==buf_no1)

sst25write(addr,usart1_dma_buf1,512);

else

sst25write(addr,usart1_dma_buf2,512);

addr+=512;

timer1=5000;

//時間重置

led1_off;

}

//檢測超時

開了 定時器

if(timer1==0)

//五秒內沒準備好的資料

}

還是很簡單的。

有一點比較困擾 就是 flagstatus標誌位 與 itstatus中斷標誌位 的區別。 其實就 dma 來說 dma_it值 與 dma_flag值 是一樣的

甚至2者值的獲取 都是讀 dma isr register 的值 清除也是設定 dma_ifcr 暫存器來清除的所以貌似沒有區別.........

STM32詳細配置 USART

前言 串列埠對於處理器來說算是一種標配,也是在軟體開發中必不可少的,那就是使用串列埠來除錯資訊 列印出相應的資訊 stm32f0系列的晶元,串列埠根據型號不同,數量也不同,從1個到8個不等。今天主要總結串列埠簡單且常用的功能,傳送字元和 中斷接收字元。今天提供的串列埠傳送功能將在後面的各個模組總結中...

STM32學習筆記 USART

參考 include stm32f10x.h 配置nvic void nvic config void 配置串列埠,因為串列埠與gpio復用,所以也要配置gpio void usart config void 傳送乙個byte void usart sendbyte usart typedef us...

STM32的USART串列埠通訊

三 總結 韌體庫就是函式的集合,韌體庫函式的作用就是 向下負責與暫存器直接打交道,向上提供使用者函式呼叫的介面。基於固態庫方式開發,也就是直接呼叫庫函式,特點就是外設交流方便 查錯簡單 對主控制器stm32上手簡單。stm32的mcu,暫存器數量較多,韌體庫將這些暫存器底層操作都封裝起來,提供一套a...