1. 程式人生 > >STM32 SPI NSS大揭祕

STM32 SPI NSS大揭祕

      關於這個NSS我曾經為它頭痛了很久,看手冊,看程式,看視訊,看帖子,我都沒有徹底搞明白它。曾經幾次想徹底解決它,但是都夭折了,只能把自己寫好的筆記拋棄。還因此多慮導致氣血不足,上火,由此導致牙痛,嘴脣乾裂。簡直痛苦不已。那時候,我真的覺得我可能永遠搞不明白了。就這樣算了吧。老師說,讓我先做做技術,再去追求原理,後來我通過接手了一個用SPI控制ADXL345加速度感測器的任務並結合了一個SPI全雙工的例項,才由此慢慢使謎團浮出水面,再通過學會除錯技術,終於搞明白了。SPI真的很複雜,不過複雜而有趣。我以一個菜鳥的身份,寫出我對STM32 SPI NSS

的相關理解。希望大家指正。

     這個NSS到底是怎麼作用呢?回答是片選。

     主裝置和從裝置在進行SPI通訊的時候,從裝置都有個CS片選訊號,低電平有效,我們通常都要用這個NSS連到從裝置的CS上。但是這裡只是大體讓大家大體明白怎麼回事,東西很多,關於這個NSS,還有很多東西呢,下面讓我娓娓道來。

     先看輸入輸出模式.

     對於每個SPINSS可以輸入,也可以輸出。所謂輸入,就是NSS

的電平訊號給自己,所謂輸出,就是將NSS的電平訊號傳送出去,給從機。配置為輸出,還是不輸出,我們可以通過SPI_CR2暫存器的SSOE位。當SSOE1時,並且SPI處於主模式控制時,NSS就輸出低電平,也就是拉低,因此當其他SPI裝置的NSS引腳與它相連,必然接收到低電平,則片選成功,都成為從裝置了。NSS的輸出就介紹到這裡

     下面介紹NSS的輸入。

     我們都知道NSS輸入又分為硬體輸入和軟體控制輸入兩種模式,那麼就從這兩種模式入手,來揭開它的面紗吧。

     

先說軟體模式吧

     1對於SPI主機來說,需要設定SPI_CR1暫存器的SSM1SSI位為1SSM1是為了使能軟體管理。,NSS有內部和外部引腳。這時候,外部引腳留作他用(可以用來作為GPIO驅動從裝置的片選訊號)。內部NSS引腳電平則通過SPI_CRL暫存器的SSI位來驅動。SSI位為1是為了使NSS內電平為高電平。這時候,不免產生疑問,為什麼主裝置的內部NSS電平要為1呢?

STM32手冊上說,要保持MSTRSPE位為1,也就是說要保持主機模式,只有NSS接到高電平訊號時,這兩位才能保持置1.也就是說對於STM32SPI,要保持為主機狀態,內部輸入的NSS電平必須為高。當然這裡在硬體模式下也是如此。

2 對於SPI 從機來說

 主機自己的內部NSS高電平解決了,那麼SPI從機的NSS片選低電平也得解決啊。

如果從機選擇STM32的一個SPI,譬如主機選為SPI1,從機選為SPI2則要按照以下操作

手冊說,NSS引腳在完成位元組傳輸之前必須連線到一個低電平訊號。在軟體模式下,則需要設定SPI_CR1暫存器的SSM位為1(軟體管理使能)和SSI位為0.果然如此。SSI必須要為0,也就是SPI2的片選為低,則片選成功。

若從機為一個其他的SPI晶片,譬如我那個ADXL345加速度感測器。那麼,我們可以有兩種方法

一種方法,是把晶片的CS接到GND上,另一種方法是,用一個GPIO口去輸出低電平來控制CS片選成功。這個GPIO可以是任何一個GPIO口,當然我們上面提到當SPI的主機配置為軟體模式,外部NSS引腳留作他用了,它就是一個GPIO了,我們也可以用它。這時候,我們可以設定它推輓輸出為低電平,然後用線跟從機的CS相連,那麼就可以片選從晶片了。

再說說硬體模式。

對於主機,我們的NSS可以直接接到高電平,對於從機,NSS接低就可以。

當然我們上面提過當一個主機的SSOE1時,主機工作在輸出模式,而且NSS拉低了,我們要讓從機片選,只要將CS接到主機的NSS上,CS自動拉低。

這便是,ST公司設計的STM32SPI NSS的工作流程。下面用例項向大家介紹。

我們介紹一個STM32SPI1SPI2全雙工通訊的程式,具體的程式,可以加QQ843538946,問我要。這裡只介紹SPI配置方面的程式。

/* SPI1 Config-------------------------------------------------------------*/

  SPI_InitStructure.SPI_Direction =SPI_Direction_2Lines_FullDuplex;

  SPI_InitStructure.SPI_Mode = SPI_Mode_Master,//這裡設定SPI1為主模式,設定SSI1

  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;//這裡設定SSM1,軟體管理

  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;//這裡設定SPI2為從模式SSI0

  //因為SPI2SPI1用的是同一個SPI_InitStructure,所以SSM位已經為1

  SPI_Init(SPI2, &SPI_InitStructure);

對於SPI2的配置,和SPI1用的是同一個結構體,只需要把模式和SSI一改就行,其他的譬如軟體使能,還有時序什麼的都不用改。這樣SPI1SPI2就配置好了。以後就可以傳輸資料了。

  登陸www.dd360.info 膠州外賣網,點選客服1,就可與我進行交流