1. 程式人生 > 實用技巧 >STM32中的SPI

STM32中的SPI

SPI協議簡介:

  SPI是摩托羅拉公司提出的一種通訊協議,運用了全雙工的通訊方式。其通訊速率可以達到Mbps的數量級,是一種廣泛使用,優秀的通訊協議。在STM32的開發中,經常被用來進行Flash儲存器的通訊,也被用作向一些小的液晶螢幕傳送資料。


物理層:

  在SPI的通訊中,訊號線有兩條,MOSI,MISO,對應的兩個通訊方向,即主機》從機。從機》主機,在一些情況下,我們只使用主到從的這條訊號線(例如控制液晶屏的顯示,液晶屏不返回資訊),時鐘訊號線有一條,即SCK。然後便是若干條片選訊號線(SS)。

  片選訊號線是SPI通訊的特點之一,SPI通訊總線上有幾個裝置,就存在幾條片選訊號線。當某一個片選訊號線的電平被拉低,這個裝置就被選中,即被選為通訊物件。(圖源網路)

  


協議層:

  在協議層中,SPI通過SCK時鐘訊號線來統一時間基準。具體通訊流程有三步:(圖源網路)

  

  開始:SS訊號線拉低,通訊開始。

  傳輸資料:MOSI\MISO在每個時鐘週期都會傳輸一位資料。

  結束:SS訊號拉高,傳輸結束。

  需要注意的是,在SPI中,存在著幾個不同的傳輸資料模式:首先,SCK在空閒時,有高電平和低電平兩種狀態(圖中為空閒高電平)。其次,訊號線會在時鐘訊號對的邊緣進行取樣(虛線位置),而取樣的邊緣選擇有兩種:奇數邊緣和偶數邊緣(圖中為偶數邊緣)。通常,我們使用SCK空閒高電平,偶數邊緣取樣。或者SCK空閒低電平,奇數邊緣取樣。


STM32中的SPI:

  STM32中的SPI初始化:

void SPI1_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
  
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_SPI1, ENABLE );    
 
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;  //複用推輓輸出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &GPIO_InitStructure); GPIO_SetBits(GPIOA,GPIO_Pin_5|GPIO_Pin_6|GPIO_Pin_7); SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex; //SPI設定為雙線雙向全雙工 SPI_InitStructure.SPI_Mode = SPI_Mode_Master; //定義此裝置為主機 SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b; //SPI傳送接收8位幀結構 SPI_InitStructure.SPI_CPOL = SPI_CPOL_High; //選擇了序列時鐘的穩態:時鐘懸空高 SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;    //資料捕獲於第二個時鐘沿 SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;     //NSS訊號由軟體控制 SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_256; //定義波特率預分頻的值:波特率預分頻值為256 SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB; //資料傳輸從MSB位開始 SPI_InitStructure.SPI_CRCPolynomial = 7;       //CRC值計算的多項式 SPI_Init(SPI1, &SPI_InitStructure);           //初始化外設SPI1暫存器 SPI_Cmd(SPI1, ENABLE); //使能SPI外設