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