STM32技術--SPI通信


SPI

一、SPI簡介

  SPI(Serial Peripheral Interface )是串行外圍接口設備,是一種高速的,全雙工,同步的通信總線,並且在芯片上只占用四根線,節約了芯片的管腳,同時為PCB的布局上節省空間,提供方便,正是處於這種簡單易用的特性,現在越來越多的芯片集成了這種協議。

  SPI 是一個環形總線結構,由 ss(cs)、 sck、 sdi、 sdo 構成,其時序其實很簡單,主要是在 sck 的控制下,兩個雙向移位寄存器進行數據交換。

因為是全雙工同步通信,所以在傳輸數據時,左邊主機的數據從移位寄存器進入MOSI線上進入右邊的從機,並存入最低位,同時從機的最高位通過MISO傳輸到主機的最低位,當第二位數據進行發送時,最低位的數據會向左移一位並將新數據存入最低位。

二、通信協議

1、物理層

 motorola公司  首先提出的全雙工三線同步串行外圍接口,采用主從模式( Master Slave)架構;支持多 slave 模式應用,一般僅支持單Master(單主機模式)。

 管腳

  三線SPI:SCLK(時鍾線),MISO(主機接收從機發送),MOSI(主機發送從機接收)

  四線SPI:CS(片選線),SCLK,MISO,MOSI

  片選:被選,確定該設備處於何種工作模式

   連接方式

  

 

2、數據鏈路層
 SPI采用位協議,------高位在前,低位在后

 SPI有四種工作模式,SPI0 SPI1 SPI2 SPI3

           SPI 模塊為了和外設進行數據交換,根據外設工作要求,其輸出串行同步時鍾極性和相位可以進行配置,時鍾極性(CPOL)對傳輸協

議沒有重大的影響。如果 CPOL=0,串行同步時鍾的空閑狀態為低電平;如果 CPOL=1,串行同步時鍾的空閑狀態為高電平。時鍾相位(CPHA)
能夠配置用於選擇兩種不同的傳輸協議之一進行數據傳輸。如果 CPHA=0,在串行同步時鍾的第一個跳變沿(上升或下降)數據被采樣;如
果 CPHA=1,在串行同步時鍾的第二個跳變沿(上升或下降)數據被采樣。 SPI 主模塊和與之通信的外設音時鍾相位和極性應該一致。
SPI 時序圖詳解---SPI 接口在模式 下輸出第一位數據的時刻

    

 

三、STM32中SPI控制器

數量:2個  SPI1  SPI2

特性:全雙工同步通信

            8/16是傳輸幀選擇

            主從結構

            8個主模式波特率預分頻系數

            主模式和從模式下均可以由軟件或硬件進行NSS管理

            可編程的時鍾極性和相位

             可編程的數據順序, MSB在前或LSB在前

四、配置工作模式

1、NSS管理

      SPI可以工作為主機模式和從機模式,可以通過軟件模式和硬件模式進行管理。

  SPI的NSS引腳分為內部引腳和外部引腳,當內部引腳檢測到高電平的時候,設備會工作在主機模式,檢測到低電平,工作在從機模式。

 先說軟件模式,軟件模式可以通過SPI_CR1寄存器的SSM為進行設置,當SSM位為1時,SPI的模式管理為軟件管理模式,且當SSI位為1時(SSI位僅在SSM位為1時有效),內部的NSS會被驅動為高電平,該設備就設置為主機模式且外部NSS引腳會輸出一個低電平信號,當其他的設備檢測到低電平信號時,會自動進入從機模式。

硬件模式:

  

       NSS輸出使能通過CR2的SSOE位進行控制,一旦該位被使能,NSS引腳作為一個輸出引腳,若SPI工作為主機模式,NSS會輸出一個低電平,當其他設備的NSS引腳接到主設備的引腳,會檢測到一個低電平,並會自動進入從設備狀態。當配置為主模式,NSS配置為輸入引腳,(MSTR=1,SSOE=0)時,如果NSS被拉低,則配置為主模式水白,會自動進入從工作模式。

       若向通過硬件管理工作模式,只需將需要配置為主模式的NSS引腳接高電平,從模式的NSS接低電平即可。

  更詳細的NSS工作模式介紹見:https://blog.csdn.net/andylauren/article/details/52259703

五、SPI配置過程

1、查看原理圖確定引腳,以及各個引腳的工作模式

 

這里spi的四個引腳分別對應pa4,pa5,pa6,pa7,SPI作為主機,MOSI,cs,clk應給配置為輸出模式,miso配置為輸入。

所以為了將SPI的功能復用到IO扣上,pa5,pa7要用作復用推挽輸出。(pa4為什么配置為通用推挽輸出現在我還沒弄明白,等明白了再改回來)

2、確定spi的時鍾相位以及時鍾極性等工作模式

 因為時鍾相位和時鍾極性可以配置出4種spi的模式,而spi的工作模式與數據的采集以及輸出有關,所以我們這里要根據外設來確當spi的工作模式。

復制代碼
#include "spi.h"

void SPI_Config(void)
{
    /*
        pa4        sf cs            通用推挽輸出
        pa5        sc clk        復用推挽輸出
        pa6        miso            浮空輸入
        pa7        mosi            復用推挽輸出
    */
    //GPIO
    GPIO_InitTypeDef GPIOInitStruct;
    //SPI
    SPI_InitTypeDef SPIInitStruct;
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_SPI1,ENABLE);
    //pa4 通用推挽輸出
    GPIOInitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIOInitStruct.GPIO_Pin = GPIO_Pin_4;
    GPIOInitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIOInitStruct);
    //pa5 pa7 復用推挽輸出
    GPIOInitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIOInitStruct.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;
    GPIO_Init(GPIOA,&GPIOInitStruct);
    //pa6 浮空輸入
    GPIOInitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
    GPIOInitStruct.GPIO_Pin = GPIO_Pin_6;
    GPIO_Init(GPIOA,&GPIOInitStruct);
    
    //SPI
    SPIInitStruct.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;            //分頻
    SPIInitStruct.SPI_CPHA = SPI_CPHA_1Edge;                                                        //時鍾相位
    SPIInitStruct.SPI_CPOL = SPI_CPOL_Low;                                                            //時鍾極性
    SPIInitStruct.SPI_DataSize = SPI_DataSize_8b;                                                //數據寬度
    SPIInitStruct.SPI_Direction = SPI_Direction_2Lines_FullDuplex;            //全雙工
    SPIInitStruct.SPI_FirstBit = SPI_FirstBit_MSB;                                            //高位在前
    SPIInitStruct.SPI_Mode = SPI_Mode_Master;                                                        //主機
    SPIInitStruct.SPI_NSS = SPI_NSS_Soft;                                                                //軟件模式
    SPI_Init(SPI1,&SPIInitStruct);
    //使能SPI
    SPI_Cmd(SPI1,ENABLE);
    
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM