一、SPI 協(xié)議簡(jiǎn)介
SPI (Serial Peripheral Interface)協(xié)議,即串行外圍設(shè)備接口,是一種高速全雙工的通信總線。
它被廣泛地使用在ADC、LCD 等設(shè)備與MCU 間,要求通訊速率較高的場(chǎng)合。
SPI 物理層
SPI 通訊使用3 條總線及片選線,3 條總線分別為SCK、MOSI、MISO,片選線為SS(CS),它們的作用介紹如下:
(1) SS( Slave Select): 從設(shè)備選擇信號(hào)線,常稱為片選信號(hào)線,也稱為NSS、CS,以下用NSS 表示。低電平表示選中
當(dāng)有多個(gè)SPI 從設(shè)備與SPI 主機(jī)相連時(shí),設(shè)備的其它信號(hào)線SCK、MOSI 及MIS O 同時(shí)并聯(lián)到相同的SPI 總線上,即無(wú)論有多少個(gè)從設(shè)備,都共同只使用這3 條總線;
而每個(gè)從設(shè)備都有獨(dú)立的這一條NSS 信號(hào)線,本信號(hào)線獨(dú)占主機(jī)的一個(gè)引腳,即有多少個(gè)從設(shè)備,就有多少條片選信號(hào)線。
I2C 協(xié)議中通過(guò)設(shè)備地址來(lái)尋址、選中總線上的某個(gè)設(shè)備并與其進(jìn)行通訊;而SPI 協(xié)議中沒(méi)有設(shè)備地址,它使用NSS 信號(hào)線來(lái)尋址,當(dāng)主機(jī)要選擇從設(shè)備時(shí),把該從設(shè)備的NSS 信號(hào)線設(shè)置為低電平,該從設(shè)備即被選中,即片選有效,接著主機(jī)開(kāi)始與被選中的從設(shè)備進(jìn)行SPI 通訊。所以SPI 通訊以NSS 線置低電平為開(kāi)始信號(hào),以NSS 線被拉高作為結(jié)束信號(hào)。
(2) SCK (Serial Clock): 時(shí)鐘信號(hào)線,用于通訊數(shù)據(jù)同步。
它由通訊主機(jī)產(chǎn)生,決定了通訊的速率,不同的設(shè)備支持的最高時(shí)鐘頻率不一樣,如STM32 的SPI 時(shí)鐘頻率最大為fpclk/2,兩個(gè)設(shè)備之間通訊時(shí),通訊速率受限于低速設(shè)備。
(3) MOSI (Master Output,Slave Input): 主設(shè)備輸出/從設(shè)備輸入引腳。
主機(jī)的數(shù)據(jù)從這條信號(hào)線輸出,從機(jī)由這條信號(hào)線讀入主機(jī)發(fā)送的數(shù)據(jù),即這條線上數(shù)據(jù)的方向?yàn)橹鳈C(jī)到從機(jī)。
(4) MISO(Master Input,,Slave Output): 主設(shè)備輸入/從設(shè)備輸出引腳。
主機(jī)從這條信線讀入數(shù)據(jù),從機(jī)的數(shù)據(jù)由這條信號(hào)線輸出到主機(jī),即在這條線上數(shù)據(jù)的方向?yàn)閺臋C(jī)到主機(jī)。
SPI 協(xié)議層
SPI 協(xié)議定義了通訊的起始和停止信號(hào)、數(shù)據(jù)有效性、時(shí)鐘同步等環(huán)節(jié)。
SPI 基本通訊過(guò)程
這是一個(gè)主機(jī)的通訊時(shí)序。
NSS、SCK、MOSI 信號(hào)都由主機(jī)控制產(chǎn)生,而MISO 的信號(hào)由從機(jī)產(chǎn)生,主機(jī)通過(guò)該信號(hào)線讀取從機(jī)的數(shù)據(jù)。MOSI 與MISO 的信號(hào)只在NSS 為低電平的時(shí)候才有效,在SCK 的每個(gè)時(shí)鐘周期MOSI 和MISO 傳輸一位數(shù)據(jù)。
以上通訊流程中包含的各個(gè)信號(hào)分解如下:
通訊的起始和停止信號(hào) :
標(biāo)號(hào)(1)處,NSS 信號(hào)線由高變低,是SPI 通訊的起始信號(hào)。NSS 是每個(gè)從機(jī)各自獨(dú)占的信號(hào)線,當(dāng)從機(jī)在自己的NSS 線檢測(cè)到起始信號(hào)后,就知道自己被主機(jī)選中了,開(kāi)始準(zhǔn)備與主機(jī)通訊。
標(biāo)號(hào)(6)處,NSS 信號(hào)由低變高,是SPI 通訊的停止信號(hào),表示本次通訊結(jié)束,從機(jī)的選中狀態(tài)被取消。
數(shù)據(jù)有效性:
SPI 使用MOSI 及MISO 信號(hào)線來(lái)傳輸數(shù)據(jù),使用SCK 信號(hào)線進(jìn)行數(shù)據(jù)同步。
MOSI 及MISO 數(shù)據(jù)線在SCK 的每個(gè)時(shí)鐘周期傳輸一位數(shù)據(jù),且數(shù)據(jù)輸入輸出是同時(shí)進(jìn)行的。數(shù)據(jù)傳輸時(shí),MSB先行或LSB 先行并沒(méi)有作硬性規(guī)定,但要保證兩個(gè)SPI 通訊設(shè)備之間使用同樣的協(xié)定,一般都會(huì)采用上圖中的MSB 先行模式。
標(biāo)號(hào)(3)處,MOSI 及MISO 的數(shù)據(jù)在SCK 的上升沿期間變化輸出,在SCK 的下降沿時(shí)被采樣。即在SCK 的下降沿時(shí)刻,MOSI 及MISO 的數(shù)據(jù)有效,高電平時(shí)表示數(shù)據(jù)“1”,為低電平時(shí)表示數(shù)據(jù)“0”。在其它時(shí)刻,數(shù)據(jù)無(wú)效,MOSI 及MISO 為下一次表示數(shù)據(jù)做準(zhǔn)備。
SPI 每次數(shù)據(jù)傳輸可以8 位或16 位為單位,每次傳輸?shù)膯挝粩?shù)不受限制。
CPOL/CPHA 及通訊模式:
上面講述的時(shí)序只是SPI 中的其中一種通訊模式,SPI 一共有四種通訊模式,它們的主要區(qū)別是總線空閑時(shí)SCK 的時(shí)鐘狀態(tài)以及數(shù)據(jù)采樣時(shí)刻。
為方便說(shuō)明,在此引入“時(shí)鐘極性CPOL”和“時(shí)鐘相位CPHA”的概念。
時(shí)鐘極性CPOL 是指SPI 通訊設(shè)備處于空閑狀態(tài)時(shí),SCK 信號(hào)線的電平信號(hào)(即SPI 通訊開(kāi)始前、NSS 線為高電平時(shí)SCK 的狀態(tài))。
CPOL=0 時(shí),SCK 在空閑狀態(tài)時(shí)為低電平,CPOL=1 時(shí),則相反。時(shí)鐘相位CPHA 是指數(shù)據(jù)的采樣的時(shí)刻,當(dāng)CPHA=0 時(shí),MOSI 或MISO 數(shù)據(jù)線上的信號(hào)將會(huì)在SCK 時(shí)鐘線的“奇數(shù)邊沿”被采樣。
當(dāng)CPHA=1 時(shí),數(shù)據(jù)線在SCK 的“偶數(shù)邊沿”采樣。就是下圖
由CPOL 及CPHA 的不同狀態(tài),SPI 分成了四種模式,主機(jī)與從機(jī)需要工作在相同的模式下才可以正常通訊,實(shí)際中采用較多的是 “模式0”與“模式3”
SPI | 模式CPOL | CPHA | 空閑時(shí)SCK 時(shí)鐘 | 采樣時(shí)刻 |
---|---|---|---|---|
0 | 0 | 0 | 低電平 | 奇數(shù)邊沿 |
1 | 0 | 1 | 低電平 | 偶數(shù)邊沿 |
2 | 1 | 0 | 高電平 | 奇數(shù)邊沿 |
3 | 1 | 1 | 高電平 | 偶數(shù)邊沿 |
二、SPI 的架構(gòu)
STM32 的SPI 外設(shè)可用作通訊的主機(jī)及從機(jī),支持最高的SCK 時(shí)鐘頻率為fpclk/2 (STM32F103 型號(hào)的芯片默認(rèn)f:sub:pclk1 為36MHz,fpclk2 為72MHz),完全支持SPI 協(xié)議的4 種模式,數(shù)據(jù)幀長(zhǎng)度可設(shè)置為8 位或16 位,可設(shè)置數(shù)據(jù)MSB 先行或LSB 先行。
它還支持雙線全雙工、雙線單向以及單線模式。其中雙線單向模式可以同時(shí)使用MOSI 及MISO 數(shù)據(jù)線向一個(gè)方向傳輸數(shù)據(jù),可以加快一倍的傳輸速度。而單線模式則可以減少硬件接線,當(dāng)然這樣速率會(huì)受到影響。
通訊引腳
SPI 的所有硬件架構(gòu)都從上圖中左側(cè)MOSI、MISO、SCK 及NSS 線展開(kāi)的。
STM32 芯片有多個(gè)SPI 外設(shè),它們的SPI 通訊信號(hào)引出到不同的GPIO 引腳上,使用時(shí)必須配置到這些指定的引腳。
引腳 | SPI 編號(hào) | ||
---|---|---|---|
SPI1 | SPI2 | SPI3 | |
NSS | PA4 | PB12 | PA15 下載口的TDI |
CLK | PA5 | PB13 | PB3 下載口的TDO |
MISO | PA6 | PB14 | PB4下載口的NTRST |
MOSI | PA7 | PB15 | PB5 |
其中SPI1 是APB2 上的設(shè)備,最高通信速率達(dá)36Mbtis/s,SPI2、SPI3 是APB1 上的設(shè)備,最高通信速率為18Mbits/s。
除了通訊速率,在其它功能上沒(méi)有差異。其中SPI3 用到了下載接口的引腳,這幾個(gè)引腳默認(rèn)功能是下載,第二功能才是IO 口,如果想使用SPI3 接口,則程序上必須先禁用掉這幾個(gè)IO 口的下載功能。一般在資源不是十分緊張的情況下,這幾個(gè)IO 口是專門用于下載和調(diào)試程序,不會(huì)復(fù)用為SPI3。
時(shí)鐘控制邏輯
SCK 線的時(shí)鐘信號(hào),由波特率發(fā)生器根據(jù)“控制寄存器CR1”中的BR[0:2] 位控制,該位是對(duì)fpclk時(shí)鐘的分頻因子,對(duì)fpclk 的分頻結(jié)果就是SCK 引腳的輸出時(shí)鐘頻率,計(jì)算方法見(jiàn)下表。
BR[0:2] | 分頻結(jié)果(SCK 頻率) | BR[0:2] | 分頻結(jié)果(SCK 頻率) | ||
---|---|---|---|---|---|
000 | f | pclk/2 | 100 | f | pclk/32 |
001 | f | pclk/4 | 101 | f | pclk/64 |
010 | f | pclk/8 | 110 | f | pclk/128 |
011 | f | pclk/16 | 111 | f | pclk/256 |
其中的fpclk 頻率是指SPI 所在的APB 總線頻率,APB1 為fpclk1,APB2 為fpckl2。
數(shù)據(jù)控制邏輯
SPI 的MOSI 及MISO 都連接到數(shù)據(jù)移位寄存器上,數(shù)據(jù)移位寄存器的數(shù)據(jù)來(lái)源及目標(biāo)接收、發(fā)送緩沖區(qū)以及MISO、MOSI 線。
當(dāng)向外發(fā)送數(shù)據(jù)的時(shí)候,數(shù)據(jù)移位寄存器以“發(fā)送緩沖區(qū)”為數(shù)據(jù)源,把數(shù)據(jù)一位一位地通過(guò)數(shù)據(jù)線發(fā)送出去;當(dāng)從外部接收數(shù)據(jù)的時(shí)候,數(shù)據(jù)移位寄存器把數(shù)據(jù)線采樣到的數(shù)據(jù)一位一位地存儲(chǔ)到“接收緩沖區(qū)”中。通過(guò)寫SPI 的“數(shù)據(jù)寄存器DR”把數(shù)據(jù)填充到發(fā)送緩沖區(qū)中,通訊讀“數(shù)據(jù)寄存器DR”,可以獲取接收緩沖區(qū)中的內(nèi)容。
其中數(shù)據(jù)幀長(zhǎng)度可以通過(guò)“控制寄存器CR1”的“DFF 位”配置成8 位及16 位模式;配置“LSBFIRST 位”可選擇MSB 先行還是LSB 先行。
整體控制邏輯
整體控制邏輯負(fù)責(zé)協(xié)調(diào)整個(gè)SPI 外設(shè),控制邏輯的工作模式根據(jù)我們配置的“控制寄存器(CR1/CR2)”的參數(shù)而改變,基本的控制參數(shù)包括前面提到的SPI 模式、波特率、LSB 先行、主從模式、單雙向模式等等。
在外設(shè)工作時(shí),控制邏輯會(huì)根據(jù)外設(shè)的工作狀態(tài)修改“狀態(tài)寄存器(SR)”,我們只要讀取狀態(tài)寄存器相關(guān)的寄存器位,就可以了解SPI 的工作狀態(tài)了。
除此之外,控制邏輯還根據(jù)要求,負(fù)責(zé)控制產(chǎn)生SPI 中斷信號(hào)、DMA 請(qǐng)求及控制NSS 信號(hào)線。
實(shí)際應(yīng)用中,我們一般不使用STM32 SPI 外設(shè)的標(biāo)準(zhǔn)NSS 信號(hào)線,而是更簡(jiǎn)單地使用普通的GPIO,軟件控制它的電平輸出,從而產(chǎn)生通訊起始和停止信號(hào)。
三、通訊過(guò)程
STM32 使用SPI 外設(shè)通訊時(shí),在通訊的不同階段它會(huì)對(duì)“狀態(tài)寄存器SR”的不同數(shù)據(jù)位寫入?yún)?shù),通過(guò)讀取這些寄存器標(biāo)志來(lái)了解通訊狀態(tài)。
主模式收發(fā)流程及事件說(shuō)明如下:
(1) 控制NSS 信號(hào)線,產(chǎn)生起始信號(hào);
(2) 把要發(fā)送的數(shù)據(jù)寫入到“數(shù)據(jù)寄存器DR”中,該數(shù)據(jù)會(huì)被存儲(chǔ)到發(fā)送緩沖區(qū);
(3) 通訊開(kāi)始,SCK 時(shí)鐘開(kāi)始運(yùn)行。MOSI 把發(fā)送緩沖區(qū)中的數(shù)據(jù)一位一位地傳輸出去;MISO則把數(shù)據(jù)一位一位地存儲(chǔ)進(jìn)接收緩沖區(qū)中;
(4) 當(dāng)發(fā)送完一幀數(shù)據(jù)的時(shí)候,“狀態(tài)寄存器SR”中的“TXE 標(biāo)志位”會(huì)被置1,表示傳輸完一幀,發(fā)送緩沖區(qū)已空;類似地,當(dāng)接收完一幀數(shù)據(jù)的時(shí)候,“RXNE 標(biāo)志位”會(huì)被置1,表示傳輸完一幀,接收緩沖區(qū)非空;
(5) 等待到“TXE 標(biāo)志位”為1 時(shí),若還要繼續(xù)發(fā)送數(shù)據(jù),則再次往“數(shù)據(jù)寄存器DR”寫入數(shù)據(jù)即可;等待到“RXNE 標(biāo)志位”為1 時(shí),通過(guò)讀取“數(shù)據(jù)寄存器DR”可以獲取接收緩沖區(qū)中的內(nèi)容。
假如我們使能了TXE 或RXNE 中斷,TXE 或RXNE 置1 時(shí)會(huì)產(chǎn)生SPI 中斷信號(hào),進(jìn)入同一個(gè)中斷服務(wù)函數(shù),到SPI 中斷服務(wù)程序后,可通過(guò)檢查寄存器位來(lái)了解是哪一個(gè)事件,再分別進(jìn)行處理。也可以使用DMA 方式來(lái)收發(fā)“數(shù)據(jù)寄存器DR”中的數(shù)據(jù)。
四、STM32Cube MX配置
Mode: 模式
Full-Duplex Master 主機(jī)全雙工模式
Full-Duplex Slave 從機(jī)全雙工模式
Half-Duplex Master 主機(jī)半雙工模式
Half-Duplex Slave 從機(jī)半雙工模式
Receive Only Master 只接收主機(jī)模式
Receive Only Slave 只接收從機(jī)模式
Transmit Only Master 只發(fā)送從機(jī)模式
Hardware NSS Signal : 硬件NSS信號(hào)
可以選擇這里的固定引腳使能,也可以使用其他IO口接到外設(shè)的NSS上進(jìn)行代替;
其中SIP1的片選NSS : SPI1_NSS(PA4)
其中SIP2的片選NSS : SPI2_NSS(PB12)
如果片選引腳沒(méi)有連接硬件NSS信號(hào),則需要選擇軟件片選
NSS管腳就是片選信號(hào),作為主設(shè)備NSS管腳為高電平,從設(shè)備NSS管腳為低電平。
當(dāng)NSS管腳為低電平時(shí),該SPI設(shè)備被選中,可以和主設(shè)備進(jìn)行通信。
在STM32中,每個(gè)SPI控制器的NSS信號(hào)引腳都具有兩種功能,即輸入和輸出。輸入就是NSS管腳接收外界的信號(hào)。輸出就是將NSS的信號(hào)發(fā)給外界。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-544085.html
對(duì)于NSS的輸入,分為軟件輸入和硬件輸入。
軟件輸入:
NSS分為內(nèi)部管腳和外部管腳,通過(guò)設(shè)置spi_cr1寄存器的ssm位和ssi位都為1可以設(shè)置NSS管腳為軟件輸入模式且內(nèi)部管腳提供的電平為高電平,其中SSM位為使能軟件輸入位。SSI位為設(shè)置內(nèi)部管腳電平位。同理通過(guò)設(shè)置SSM和SSI位1和0則此時(shí)的NSS管腳為軟件輸入模式但內(nèi)部管腳提供的電平為0。若從設(shè)備是一個(gè)其他的帶有spi接口的芯片,并不能選擇NSS管腳的方式,則可以有兩種辦法,一種是將NSS管腳直接接低電平。另一種就是通過(guò)主設(shè)備的任何一個(gè)gpio口去輸出低電平選中從設(shè)備。
硬件輸入:
主機(jī)接高電平,從機(jī)接低電平。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-544085.html
五、SPI HAL庫(kù)函數(shù)
HAL_SPI_Transmit(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);//發(fā)送數(shù)據(jù)
功能:HAL庫(kù) SPI發(fā)送數(shù)據(jù)函數(shù)
參數(shù):
*hspi: 選擇SPI1/2,比如&hspi1,&hspi2
*pData : 需要發(fā)送的數(shù)據(jù),可以為數(shù)組
Size: 發(fā)送數(shù)據(jù)的字節(jié)數(shù),1 就是發(fā)送一個(gè)字節(jié)數(shù)據(jù)
Timeout: 超時(shí)時(shí)間,就是執(zhí)行發(fā)送函數(shù)最長(zhǎng)的時(shí)間,超過(guò)該時(shí)間自動(dòng)退出發(fā)送函數(shù)
HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);//接收數(shù)據(jù)
功能:SPI接收數(shù)據(jù)函數(shù)
參數(shù):
*hspi: 選擇SPI1/2,比如&hspi1,&hspi2
*pData : 接收發(fā)送過(guò)來(lái)的數(shù)據(jù)的數(shù)組
Size: 接收數(shù)據(jù)的字節(jié)數(shù),1 就是接收一個(gè)字節(jié)數(shù)據(jù)
Timeout: 超時(shí)時(shí)間,就是執(zhí)行接收函數(shù)最長(zhǎng)的時(shí)間,超過(guò)該時(shí)間自動(dòng)退出接收函數(shù)
HAL_SPI_TransmitReceive_IT(&hspi1, TXbuf,RXbuf,CommSize);
當(dāng)SPI上接收出現(xiàn)了 CommSize個(gè)字節(jié)的數(shù)據(jù)后,中斷函數(shù)會(huì)調(diào)用SPI回調(diào)函數(shù):
HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
用戶可以重新定義回調(diào)函數(shù),編寫預(yù)定功能即可,在接收完成之后便會(huì)進(jìn)入回調(diào)函數(shù)
到了這里,關(guān)于STM32 HAL庫(kù) STM32CubeMX -- SPI的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!