Ⅰ、寫在前面
SPI(Serial Perripheral Interface)串行外設(shè)通信接口,主要實(shí)現(xiàn)設(shè)備(主從)之間的通信。硬件上由CS、SCK、MISO、MOSI四根通信線連接而成。關(guān)于SPI更多介紹不再詳細(xì)描述,本文主要以STM32F103為主機(jī)、W25Q16為從機(jī)進(jìn)行SPI通信實(shí)驗(yàn)。
本文將提供STM32硬件SPI、軟件模擬SPI兩實(shí)例工程代碼供大家參考、掌握兩種方式的區(qū)別。
STM32硬件SPI:控制簡(jiǎn)單、運(yùn)行效率高、使用方便等。
軟件模擬SPI:移植性強(qiáng),只需要簡(jiǎn)單修改接口,就能在其他MCU芯片(如:51、430等)上使用。
實(shí)例實(shí)驗(yàn)效果:
兩個(gè)實(shí)例SPI通信控制方式不一樣,但實(shí)驗(yàn)效果是一樣的。
W25Q16設(shè)備ID:
上電,讀取W25Q16設(shè)備ID,并通過(guò)串口打印出來(lái);
寫數(shù)據(jù):
SFLASH_WriteNByte((uint8_t*)"ABCDEF",0, 6); 通過(guò)該函數(shù)在W25Q16的0地址處 連續(xù)寫入6字節(jié)“ABCDEF”數(shù)據(jù)。(測(cè)試的時(shí)候:第一次下載之后讓程序運(yùn)行一次,即寫入W25Q16數(shù)據(jù)。再將該函數(shù)屏蔽、下載。斷電重新讓程序運(yùn)行看讀出來(lái)的數(shù)據(jù)是否是前面寫入的數(shù)據(jù))
讀數(shù)據(jù):
SFLASH_ReadNByte(read_buf,0, 6); 通過(guò)該函數(shù)從W25Q16的0地址連續(xù)讀取6字節(jié)數(shù)據(jù),保存在read_buf里面。(地址、數(shù)據(jù)及數(shù)據(jù)長(zhǎng)度都可以修改,但讀寫的地址要相同,讀出來(lái)的數(shù)據(jù)才是寫入的數(shù)據(jù))
關(guān)于本文的更多詳情請(qǐng)往下看。
Ⅱ、實(shí)例工程下載
筆者針對(duì)于初學(xué)者提供的例程都是去掉了許多不必要的功能,精簡(jiǎn)了官方的代碼,對(duì)初學(xué)者一看就明白,以簡(jiǎn)單明了的工程供大家學(xué)習(xí)。
筆者提供的實(shí)例工程都是在板子上經(jīng)過(guò)多次測(cè)試并沒(méi)有問(wèn)題才上傳至360云盤,歡迎下載測(cè)試、參照學(xué)習(xí)。
提供下載的軟件工程是基于Keil(MDK-ARM) V5版本、STM32F103ZE芯片,但F1其他型號(hào)也適用(適用F1其他型號(hào):關(guān)注微信,回復(fù)“修改型號(hào)”)。
STM32F10x_SPI(硬件接口)讀寫Flash(25Q16)實(shí)例源代碼工程:
https://yunpan.cn/c6mfRJWva6AJ2 訪問(wèn)密碼 4bc4
STM32F10x_SPI(軟件模擬)讀寫Flash(25Q16)實(shí)例源代碼工程:
https://yunpan.cn/c6mf6zyzCaMwd 訪問(wèn)密碼 cf45
STM32F1資料:
https://yunpan.cn/crBUdUGdYKam2 訪問(wèn)密碼 ca90
Ⅲ、STM32硬件SPI
STM32所有系列芯片都帶有SPI硬件控制器,根據(jù)芯片型號(hào)不同,SPI數(shù)量也不同,有些有一個(gè)SPI,有些有3個(gè)SPI。STM32的SPI控制器功能也是很強(qiáng)大的,只需要簡(jiǎn)單的配置就能高效的進(jìn)行SPI通信。
1.SPI原理
上面是SPI的系統(tǒng)框圖,來(lái)自STM32F1的參考手冊(cè).
A.引腳
MOSI:主設(shè)備輸出/從設(shè)備輸入引腳。該引腳在主模式下發(fā)送數(shù)據(jù),在從模式下接收數(shù)據(jù)。
MISO:主設(shè)備輸入/從設(shè)備輸出引腳。該引腳在從模式下發(fā)送數(shù)據(jù),在主模式下接收數(shù)據(jù)。
SCK:串口時(shí)鐘,為通信提供時(shí)鐘。(作為主設(shè)備的輸出,從設(shè)備的輸入)。
NSS:從設(shè)備選擇。這是一個(gè)可選的引腳,用來(lái)選擇主/從設(shè)備。它的功能是用來(lái)作為“片選引腳”,讓主設(shè)備可以單獨(dú)地與特定從設(shè)備通訊,避免數(shù)據(jù)線上的沖突。
B.緩沖區(qū)SPI->DR
發(fā)送緩沖區(qū):只要往SPI1->DR寫入數(shù)據(jù),它自動(dòng)將存入發(fā)送緩沖區(qū),并執(zhí)行發(fā)送操作。這就是高效的一點(diǎn),而不像模擬SPI,還需要我們控制時(shí)鐘,控制MOSI引腳輸出高低電平。
接收緩沖區(qū):原理和發(fā)送緩沖區(qū)差不多,只是這個(gè)是接收數(shù)據(jù)。接收滿了,才通知我們需要去讀取數(shù)據(jù)。
C.波特率發(fā)生器
STM32的硬件SPI還可以通過(guò)配置來(lái)控制通信的速度。
2.SPI引腳
該函數(shù)位于spi.c文件下面;
使用的SPI需與引腳對(duì)應(yīng),CS片選信號(hào)我們這里是通過(guò)普通IO來(lái)控制的,若不同請(qǐng)?jiān)趕pi.h里面修改為你開(kāi)發(fā)板上的引腳。
3.SPI配置
該函數(shù)位于spi.c文件下面;
該函數(shù)是文章的重要一項(xiàng),主要是對(duì)硬件SPI進(jìn)行的一些初始化配置。
SPI為主模式,時(shí)鐘線平時(shí)為高,上升沿采集數(shù)據(jù),8位數(shù)據(jù)格式,軟件控制片選,數(shù)據(jù)高位在前。
1.傳輸方向:SPI_Direction =SPI_Direction_2Lines_FullDuplex;
總共有四個(gè)方式:
兩線全雙工:SPI_Direction_2Lines_FullDuplex
兩線只接收:SPI_Direction_2Lines_RxOnly
單線只接收:SPI_Direction_1Line_Rx
單線只發(fā)送:SPI_Direction_1Line_Tx
2.模式:SPI_Mode = SPI_Mode_Master;
總共有兩種模式:
主機(jī)模式:SPI_Mode_Master
從機(jī)模式:SPI_Mode_Slave
3.數(shù)據(jù):SPI_DataSize = SPI_DataSize_8b;
8位數(shù)據(jù)長(zhǎng)度:SPI_DataSize_8b
16位數(shù)據(jù)長(zhǎng)度:SPI_DataSize_16b
4.時(shí)鐘極性:SPI_CPOL = SPI_CPOL_High;
也就是我們平時(shí)不操作時(shí),時(shí)鐘的電平。
低電平:SPI_CPOL_Low
高電平:SPI_CPOL_High
5.時(shí)鐘相位:SPI_CPHA = SPI_CPHA_2Edge;
也就是我們需要等多少個(gè)“時(shí)鐘”操作通信口MOSI、MISO。
1個(gè)時(shí)鐘:SPI_CPHA_1Edge
2個(gè)時(shí)鐘:SPI_CPHA_2Edge
6.片選信號(hào):SPI_NSS = SPI_NSS_Soft;
也就是我們?nèi)绻刂芅SS片選引腳;
軟件控制:SPI_NSS_Soft
硬件控制:SPI_NSS_Hard
7.波特率(時(shí)鐘)分頻:SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;
也就是我們控制SPI通信的速率,和USART串口的波特率類似。
這里的參數(shù)有很多種,請(qǐng)見(jiàn)源代碼。
8.第一位傳輸數(shù)據(jù):SPI_FirstBit = SPI_FirstBit_MSB;
在一根通信線上一字節(jié)(8Bit)數(shù)據(jù)分8次傳輸才能完成,這里是高位先傳輸,還是低位先傳輸?shù)囊馑肌?/p>
高位:SPI_FirstBit_MSB
低位:SPI_FirstBit_LSB
9.校驗(yàn):SPI_CRCPolynomial = 7;
校驗(yàn)的數(shù)據(jù)位長(zhǎng)度。
4.SPI讀寫數(shù)據(jù)
函數(shù)位于spi.c文件下面;
這兩個(gè)函數(shù)就是我們使用到的接口,在上面SPI配置好之后,操作這兩個(gè)函數(shù)就可以控制其引腳讀寫了。
這兩個(gè)函數(shù)就是我們上面說(shuō)的“發(fā)送緩沖區(qū)”和“接收緩沖區(qū)”所需要使用到的部分。
這里需要注意:發(fā)送和接收數(shù)據(jù)都是通過(guò)SPI->DR寄存器,讀、寫操作會(huì)控制數(shù)據(jù)的流向。
Ⅳ、軟件模擬SPI
從51學(xué)習(xí)過(guò)來(lái)的朋友就應(yīng)該知道,51的資源很少,沒(méi)有SPI硬件控制器,要想使用SPI通信方式,就需要使用IO口模擬的方式來(lái)實(shí)現(xiàn)SPI通信。只需要按照通信的時(shí)序就能控制其通信。
使用軟件模擬SPI通信有優(yōu)點(diǎn),也有缺點(diǎn)。
優(yōu)點(diǎn):移植很方便,代碼只需要簡(jiǎn)單修改就可以使用在其他芯片上;
缺點(diǎn):控制IO麻煩,對(duì)時(shí)序要求高;
1.模擬SPI引腳
該函數(shù)位于spi.c文件下面;
這個(gè)主要配置模擬SPI引腳。(如果你板子上使用的引腳不同,請(qǐng)修改spi.h文件的定義即可)
2.模擬SPI初始化
該函數(shù)位于spi.c文件下面;
這里初始化需要把狀態(tài)定好,不然第一次操作會(huì)有問(wèn)題。
3.模擬SPI寫函數(shù)(時(shí)序)
該函數(shù)位于spi.c文件下面;
這種時(shí)序的寫法在學(xué)習(xí)過(guò)51的朋友來(lái)看再熟悉不過(guò)了。
注意:
1、高字節(jié)在前,說(shuō)以上面紅色標(biāo)記的的部分就是將高位先輸出,依次移位輸出。
2、在時(shí)鐘的上升沿將數(shù)據(jù)輸出,所以在“時(shí)鐘-高”之前將數(shù)據(jù)輸出。
4.模擬SPI讀函數(shù)(時(shí)序)
該函數(shù)位于spi.c文件下面;
讀時(shí)序和寫時(shí)序原理類似,但還是存在差異。
注意:
1、高位先輸出來(lái)(從機(jī)輸出),所以,需要將讀取的數(shù)據(jù)依次移向高位。
2、在時(shí)鐘的下降沿讀出數(shù)據(jù),所以,我紅色標(biāo)記的部分可以看得出來(lái),是在時(shí)鐘為低之后才去讀取數(shù)據(jù)。
Ⅴ、修改代碼,適應(yīng)開(kāi)發(fā)板
看見(jiàn)這篇文章,你可能覺(jué)得芯片型號(hào)(STM32F103ZE)不是你的芯片芯片型號(hào),硬件接口(SPI1)、(USART1)也不是板子上的接口,那怎么辦呢,其實(shí)很簡(jiǎn)單,適當(dāng)修改一下就行。
1.修改芯片型號(hào)
該工程適合STM32F1系列的所有芯片,只需要修改一下型號(hào)。修改芯片型號(hào),可以看我的另外一篇文章:
如何將工程(修改來(lái))運(yùn)行在自己開(kāi)發(fā)板上
當(dāng)然,其他系列(F0、F2、F3、F4等)也可以使用該配置,但需要更換外設(shè)庫(kù)。
2.修改硬件接口
筆者提供的工程源代碼,在個(gè)人看來(lái)整理的還算比較整潔(名稱清晰、排版整齊、文件分類明確)、相比很多開(kāi)發(fā)板賣家提供的例程來(lái)說(shuō),要好的多。所以,看了之后,你應(yīng)該知道如何修改。
1、LED燈的IO,位于bsp.h下,修改為你的LED燈IO口就行了。
2、USART,本文是使用USART1,如果你使用USART2的話,需要usart.c文件下“USART_GPIO_Configuration”引腳配置、USART_Configuration串口配置、發(fā)送接收函數(shù)USART1 改為USART2等。
3、SPI接口
這個(gè)在上面講述中都提及了修改,就是修改spi.c和spi.h文件里面的配置。
-
FlaSh
+關(guān)注
關(guān)注
10文章
1635瀏覽量
148040 -
SPI
+關(guān)注
關(guān)注
17文章
1706瀏覽量
91598 -
STM32F10x
+關(guān)注
關(guān)注
1文章
81瀏覽量
20691
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論