SPI是我最常用的接口之一,連接管腳僅為4根;在常見的芯片間通信方式中,速度遠優于UART、I2C等其他接口 。STM32的SPI口的同步時鐘最快可到PCLK的二分之一,單個字節或字的通信時間都在us以下,因此大多數情況下我們會使用查詢法控制SPI口的傳輸 。但對于大量且連續的通信,再使用查詢法就顯得有些浪費CPU的時間,DMA控制SPI的讀寫顯然成為一種不錯的選擇 。
為DMA控制SPI批量數據讀寫的功能,參照官方代碼編寫的DMA控制SPI口在主/從兩種模式下,讀寫數據的的代碼,供各位網友直接使用或批評指正 。先直接上我得到結論:
1、運用STM32的SPI口的DMA的功能,能夠提升STM32與外設之間通信的速率和實時性 。
2、但在STM32的SPI的主機模式下,DMA控制器無法自動產生片選CS信號,只能與無需同步CS信號的外設器件通信 。為產生同步的CS信號,只能由軟件控制SPI逐字發送,而DMA僅用于接收SPI數據,這樣做的效率和不使用DMA時一樣 。
3、主模式下,軟件控制片選CS信號和SPI讀寫時,存在至少50%的時間空隙,降低了其SPI通信的效率 。
4、STM32的SPI主機模式下,無法只使用DMA接收,而不發送 。原因是沒有觸發SPI的DMA接收的信號 。但SPI的發送可以是軟件控制的逐字發送,也可以是DMA控制的連續發送 。
5、STM32的SPI若要使用DMA方式,最合適的是讓STM32工作在SPI的從模式,由外部主機(如FPGA)來控制通信的實時性和高速性 。
以下原創內容歡迎網友轉載,但請注明出處: https://www.cnblogs.com/helesheng
一、STM32做SPI主機(Master)時的DMA傳輸
STM32做SPI主機進行DMA通信時,尤其需要注意的是:不能單獨使用SPI接收數據DMA,一定要配合SPI發送數據,DMA接收數據通道才能收到數據 。道理很簡單:STM32做主機時,如果不主動發送數據將無法產生時鐘和片選等信號,亦無法在傳輸完成后觸發DMA接收數據 。但在使用時,這一點非常容易被忽視,從而造成DMA接收SPI數據通道DMA1CH2和DMACH4“不工作” 。
![STM32的SPI口的DMA讀寫[原創www.cnblogs.com/helesheng]](http://shimg.jingyanzongjie.com/230725/06315142a-0.png)
文章插圖
圖1、STM32 DMA1各通道功能
具體來說,使用SPI口的DMA接收功能有兩種配置方法:
1、SPI口的接收和發送各使用一個DMA通道
這樣做最符合DMA控制大量數據連續發送和接收的設計初衷,此種情況下的SPI口和兩個DMA通道的配置分別如下:
![STM32的SPI口的DMA讀寫[原創www.cnblogs.com/helesheng]](https://m.360buyimg.com/jdcms/jfs/t1/198810/29/27925/80/633fef66Eb4f827df/11966809860aa403.gif)
文章插圖
![STM32的SPI口的DMA讀寫[原創www.cnblogs.com/helesheng]](https://m.360buyimg.com/jdcms/jfs/t1/108027/29/15999/79/633fef66Eca7d2ff5/cd29a4346a0dbed9.gif)
文章插圖
1 RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE ); 2 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;//PA5 6 7是SPI1的SCK MIOS MOSI 3 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//復用推挽輸出 4 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 5 GPIO_Init(GPIOA, &GPIO_InitStructure); 6 GPIO_SetBits(GPIOA , GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7);//將其置位 7 SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//設置SPI單向或者雙向的數據模式:SPI設置為雙線雙向全雙工 8 SPI_InitStructure.SPI_Mode = SPI_Mode_Master;//設置SPI工作模式:設置為主SPI 9 SPI_InitStructure.SPI_DataSize = SPI_DataSize_16b;//設置SPI的數據大小:SPI發送接收8位幀結構10 SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;//空閑時時鐘為低電平11 SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;//數據捕獲于第1個時鐘沿12 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;//SPI_NSS_Hard;////NSS信號由硬件(NSS管腳)還是軟件(使用SSI位)管理:內部NSS信號有SSI位控制13 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;//定義波特率預分頻的值14 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;//指定數據傳輸從MSB位還是LSB位開始:數據傳輸從MSB位開始15 SPI_InitStructure.SPI_CRCPolynomial = 7;//CRC值計算的多項式16 SPI_Init(SPI1, &SPI_InitStructure);//根據SPI_InitStruct中指定的參數初始化外設SPIx寄存器17 SPI_Cmd(SPI1, ENABLE); //使能SPI1外設
經驗總結擴展閱讀
- 早期卵巢癌可以治愈嗎
- 我國現階段的非公有制經濟的性質
- 臉色不好是貧血嗎
- 芥末醬的注意事項是什么
- 得榮譽證書的心情短語
- 近三十年關于草原的小說有哪些
- 超級好聽的兔子名
- 會計電算化與會計的區別
- 海信電視為什么不定時的自動關機
- 我國現行的主要稅種有那幾種
