STM32 SPI NSS大揭秘
SSM可以控制內(nèi)部NSS引腳與SSI(一個(gè)寄存器,軟件模式)相連,還是與NSS外部引腳(真正的STM32引腳,硬件模式)相連。真正作用的是內(nèi)部NSS引腳(內(nèi)部NSS引腳才真正連接到SPI通信控制器上)
SPI從模式的配置(MSTR=0)
1.硬件模式:SSM=0,當(dāng)外部NSS為低電平時(shí),內(nèi)部NSS也為低電平,此時(shí)可以傳送數(shù)據(jù)。
2.軟件模式:SSM=1,并SSI=0.讓內(nèi)部NSS引腳為低電平,此時(shí)可以傳送數(shù)據(jù)。
相比較而言: 讓stm32工作在軟件從模式,還是硬件從模式,取決于主從之間的通訊協(xié)議,通訊協(xié)議中是否需要NSS控制。如果讓STM32模擬一個(gè)存儲(chǔ)器芯片W25Q16的話,則需工作在硬件模式。
? ?? ?? ?? ?? ?? ?如果通訊協(xié)議不需要NSS控制,也能達(dá)到要求,就可以選擇軟件模式,可以釋放出一個(gè)GPIO引腳做它用。
SPI主模式配置(MSTR=1)
1.硬件模式:SSM=0??
? ?A:輸入模式:SSOE=0,在外部NSS引腳為高電平,即內(nèi)部NSS引腳也為高電平時(shí),才能進(jìn)行數(shù)據(jù)傳輸。 如果要使能從設(shè)備,還需要一個(gè)GPIO引腳。
? ?B:輸出模式:SSOE=1, 外部NSS引腳會(huì)輸出低電平,使能從設(shè)備,進(jìn)行數(shù)據(jù)傳輸。 不需要額外的GPIO引腳就能控制從設(shè)備。? ?? ?? ?? ?
2.軟件模式:SSM=1,SSI=1,將內(nèi)部NSS引腳設(shè)置為高電平。這樣隨時(shí)可以傳輸數(shù)據(jù)。當(dāng)然多數(shù)情況還需要一個(gè)GPIO引腳輸出低電平,來(lái)使能從設(shè)備,讓從設(shè)備可以接收數(shù)據(jù)。
??
以驅(qū)動(dòng)W25Q16為例, SPI主模式配置的優(yōu)劣可以想象到,硬件的輸入模式,占用外部NSS引腳和GPIO引腳,一共兩個(gè)引腳;
硬件的輸出模式和軟件模式,都只占用一個(gè)引腳,他們的不同在于,硬件輸出模式必須使用某固定的端口,而軟件模式可以使用任意GPIO端口。
在實(shí)際中,stm32通常用作主模式,選擇軟件模式。?
關(guān)于這個(gè)NSS我曾經(jīng)為它頭痛了很久,看手冊(cè),看程序,看視頻,看帖子,我都沒(méi)有徹底搞明白它。曾經(jīng)幾次想徹底解決它,但是都夭折了,只能把自己寫好的筆記拋棄。還因此多慮導(dǎo)致氣血不足,上火,由此導(dǎo)致牙痛,嘴唇干裂。簡(jiǎn)直痛苦不已。那時(shí)候,我真的覺(jué)得我可能永遠(yuǎn)搞不明白了。就這樣算了吧。老師說(shuō),讓我先做做技術(shù),再去追求原理,后來(lái)我通過(guò)接手了一個(gè)用SPI控制ADXL345加速度傳感器的任務(wù)并結(jié)合了一個(gè)SPI全雙工的實(shí)例,才由此慢慢使謎團(tuán)浮出水面,再通過(guò)學(xué)會(huì)調(diào)試技術(shù),終于搞明白了。SPI真的很復(fù)雜,不過(guò)復(fù)雜而有趣。我以一個(gè)菜鳥的身份,寫出我對(duì)STM32 SPI NSS的相關(guān)理解。希望大家指正。
? ???這個(gè)NSS到底是怎么作用呢?回答是片選。
? ???主設(shè)備和從設(shè)備在進(jìn)行SPI通信的時(shí)候,從設(shè)備都有個(gè)CS片選信號(hào),低電平有效,我們通常都要用這個(gè)NSS連到從設(shè)備的CS上。但是這里只是大體讓大家大體明白怎么回事,東西很多,關(guān)于這個(gè)NSS,還有很多東西呢,下面讓我娓娓道來(lái)。
? ???先看輸入輸出模式.
? ?? ? 對(duì)于每個(gè)SPI的NSS可以輸入,也可以輸出。所謂輸入,就是NSS的電平信號(hào)給自己,所謂輸出,就是將NSS的電平信號(hào)發(fā)送出去,給從機(jī)。配置為輸出,還是不輸出,我們可以通過(guò)SPI_CR2寄存器的SSOE位。當(dāng)SSOE為1時(shí),并且SPI處于主模式控制時(shí),NSS就輸出低電平,也就是拉低,因此當(dāng)其他SPI設(shè)備的NSS引腳與它相連,必然接收到低電平,則片選成功,都成為從設(shè)備了。NSS的輸出就介紹到這里
? ???下面介紹NSS的輸入。
? ???我們都知道NSS輸入又分為硬件輸入和軟件控制輸入兩種模式,那么就從這兩種模式入手,來(lái)揭開它的面紗吧。
? ???先說(shuō)軟件模式吧。
? ???1 對(duì)于SPI主機(jī)來(lái)說(shuō),需要設(shè)置SPI_CR1寄存器的SSM為1和SSI位為1,SSM為1是為了使能軟件管理。,NSS有內(nèi)部和外部引腳。這時(shí)候,外部引腳留作他用(可以用來(lái)作為GPIO驅(qū)動(dòng)從設(shè)備的片選信號(hào))。內(nèi)部NSS引腳電平則通過(guò)SPI_CRL寄存器的SSI位來(lái)驅(qū)動(dòng)。SSI位為1是為了使NSS內(nèi)電平為高電平。這時(shí)候,不免產(chǎn)生疑問(wèn),為什么主設(shè)備的內(nèi)部NSS電平要為1呢?
STM32手冊(cè)上說(shuō),要保持MSTR和SPE位為1,也就是說(shuō)要保持主機(jī)模式,只有NSS接到高電平信號(hào)時(shí),這兩位才能保持置1.也就是說(shuō)對(duì)于STM32的SPI,要保持為主機(jī)狀態(tài),內(nèi)部輸入的NSS電平必須為高。當(dāng)然這里在硬件模式下也是如此。
? ???2 對(duì)于SPI 從機(jī)來(lái)說(shuō)
? ???主機(jī)自己的內(nèi)部NSS高電平解決了,那么SPI從機(jī)的NSS片選低電平也得解決啊。
? ???如果從機(jī)選擇STM32的一個(gè)SPI,譬如主機(jī)選為SPI1,從機(jī)選為SPI2,則要按照以下操作手冊(cè)說(shuō),NSS引腳在完成字節(jié)傳輸之前必須連接到一個(gè)低電平信號(hào)。在軟件模式下,則需要設(shè)置SPI_CR1寄存器的SSM為1(軟件管理使能)和SSI位為0.果然如此。SSI必須要為0,也就是SPI2的片選為低,則片選成功。
若從機(jī)為一個(gè)其他的SPI芯片,譬如我那個(gè)ADXL345加速度傳感器。那么,我們可以有兩種方法
一種方法,是把芯片的CS接到GND上,另一種方法是,用一個(gè)GPIO口去輸出低電平來(lái)控制CS片選成功。這個(gè)GPIO可以是任何一個(gè)GPIO口,當(dāng)然我們上面提到當(dāng)SPI的主機(jī)配置為軟件模式,外部NSS引腳留作他用了,它就是一個(gè)GPIO了,我們也可以用它。這時(shí)候,我們可以設(shè)置它推挽輸出為低電平,然后用線跟從機(jī)的CS相連,那么就可以片選從芯片了。
再說(shuō)說(shuō)硬件模式。
對(duì)于主機(jī),我們的NSS可以直接接到高電平,對(duì)于從機(jī),NSS接低就可以。
當(dāng)然我們上面提過(guò)當(dāng)一個(gè)主機(jī)的SSOE為1時(shí),主機(jī)工作在輸出模式,而且NSS拉低了,我們要讓從機(jī)片選,只要將CS接到主機(jī)的NSS上,CS自動(dòng)拉低。
這便是,ST公司設(shè)計(jì)的STM32 SPI NSS的工作流程。下面用實(shí)例向大家介紹。
我們介紹一個(gè)STM32上SPI1和SPI2全雙工通信的程序,具體的程序,可以加QQ843538946,問(wèn)我要。這里只介紹SPI配置方面的程序。
[cpp] view plain copy /*?SPI1?Config?-------------------------------------------------------------*/??????SPI_InitStructure.SPI_Direction?=?SPI_Direction_2Lines_FullDuplex;??????SPI_InitStructure.SPI_Mode?=?SPI_Mode_Master,//這里設(shè)置SPI1為主模式,設(shè)置SSI為1????SPI_InitStructure.SPI_DataSize?=?SPI_DataSize_8b;??????SPI_InitStructure.SPI_CPOL?=?SPI_CPOL_Low;??????SPI_InitStructure.SPI_CPHA?=?SPI_CPHA_2Edge;??????SPI_InitStructure.SPI_NSS?=?SPI_NSS_Soft;//這里設(shè)置SSM為1,軟件管理????SPI_InitStructure.SPI_BaudRatePrescaler?=?SPI_BaudRatePrescaler_4;??????SPI_InitStructure.SPI_FirstBit?=?SPI_FirstBit_LSB;??????SPI_InitStructure.SPI_CRCPolynomial?=?7;??????SPI_Init(SPI1,?&SPI_InitStructure);??????/*?SPI2?Config?-------------------------------------------------------------*/??????SPI_InitStructure.SPI_Mode?=?SPI_Mode_Slave;//這里設(shè)置SPI2為從模式SSI為0??????//因?yàn)镾PI2和SPI1用的是同一個(gè)SPI_InitStructure,所以SSM位已經(jīng)為1??????SPI_Init(SPI2,?&SPI_InitStructure);??
對(duì)于SPI2的配置,和SPI1用的是同一個(gè)結(jié)構(gòu)體,只需要把模式和SSI一改就行,其他的譬如軟件使能,還有時(shí)序什么的都不用改。這樣SPI1和SPI2就配置好了。以后就可以傳輸數(shù)據(jù)了。





