日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

SPI通信的基础知识

發布時間:2024/6/21 综合教程 30 生活家
生活随笔 收集整理的這篇文章主要介紹了 SPI通信的基础知识 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1 SPI物理層
SPI通信設備之間常用物理連接方式如下圖

?SPI通訊使用3條總線及片選線,3條總線分別為SCK、MOSI、MISO,片選線為CS。
?CS:從設備選擇信號線,常稱為片選信號線,也稱為NSS。當有多個SPI從設備與SPI主機相連時,設備的其它信號線SCK、MOSI及MISO同時并聯到相同的SPI總線上,即無論有多少個從設備,都共同只使用這3條總線;而每個從設備都有獨立的這一條CS信號線,本信號線獨占主機的一個引腳,即有多少個從設備,就有多少條片選信號線。SPI協議中沒有設備地址,它使用CS信號線來尋址,當主機要選擇從設備時,把該從設備的CS信號線設置為低電平,該從設備即被選中,即片選有效,接著主機開始與被選中的從設備進行SPI通訊。所以SPI通訊以CS線置低電平為開始信號,以NSS線被拉高作為結束信號。
?SCK:時鐘信號線,用于通訊數據同步。它由通訊主機產生,決定了通訊的速率,不同的設備支持的最高時鐘頻率不一樣,如STM32的SPI時鐘頻率最大為fpclk/2,兩個設備之間通訊時,通訊速率受限于低速設備。
在NRF52832中

typedef enum
{
    NRF_DRV_SPI_FREQ_125K = NRF_SPI_FREQ_125K, ///< 125 kbps.
    NRF_DRV_SPI_FREQ_250K = NRF_SPI_FREQ_250K, ///< 250 kbps.
    NRF_DRV_SPI_FREQ_500K = NRF_SPI_FREQ_500K, ///< 500 kbps.
    NRF_DRV_SPI_FREQ_1M   = NRF_SPI_FREQ_1M,   ///< 1 Mbps.
    NRF_DRV_SPI_FREQ_2M   = NRF_SPI_FREQ_2M,   ///< 2 Mbps.
    NRF_DRV_SPI_FREQ_4M   = NRF_SPI_FREQ_4M,   ///< 4 Mbps.
    NRF_DRV_SPI_FREQ_8M   = NRF_SPI_FREQ_8M    ///< 8 Mbps.
} nrf_drv_spi_frequency_t;

nrf_drv_spi_frequency_t可以用來配置SPI的通信速率。
?MOSI (Master Output, Slave Input)主設備輸出/從設備輸入引腳。主機的數據從這條信號線輸出,從機由這條信號線讀入主機發送的數據,即這條線上數據的方向為主機到從機。
?MISO(Master Input,,Slave Output):主設備輸入/從設備輸出引腳。主機從這條信號線讀入數據,從機的數據由這條信號線輸出到主機,即在這條線上數據的方向為從機到主機。
2 協議層
2.1 SPI基本通信過程

?這是一個主機的通訊時序。NSS、SCK、MOSI信號都由主機控制產生,而MISO的信號由從機產生,主機通過該信號線讀取從機的數據。MOSI與MISO的信號只在NSS為低電平的時候才有效,在SCK的每個時鐘周期MOSI和MISO傳輸一位數據。
?在上圖中的標號1處,NSS信號線由高變低,是SPI通訊的起始信號。NSS是每個從機各自獨占的信號線,當從機檢在自己的NSS線檢測到起始信號后,就知道自己被主機選中了,開始準備與主機通訊。在圖中的標號?處,NSS信號由低變高,是SPI通訊的停止信號,表示本次通訊結束,從機的選中狀態被取消。
?SPI使用MOSI及MISO信號線來傳輸數據,使用SCK信號線進行數據同步。MOSI及MISO數據線在SCK的每個時鐘周期傳輸一位數據,且數據輸入輸出是同時進行的。數據傳輸時,MSB先行或LSB先行并沒有作硬性規定,但要保證兩個SPI通訊設備之間使用同樣的協定,一般都會采用上圖中的MSB先行模式。
?觀察圖中的2,3,4,5標號處,MOSI及MISO的數據在SCK的上升沿期間變化輸出,在SCK的下降沿時被采樣。即在SCK的下降沿時刻,MOSI及MISO的數據有效,高電平時表示數據“1”,為低電平時表示數據“0”。在其它時刻,數據無效,MOSI及MISO為下一次表示數據做準備。
?SPI每次數據傳輸可以8位或16位為單位,每次傳輸的單位數不受限制。
3 SPI的模式
?上面講述的圖中的時序只是SPI中的其中一種通訊模式,SPI一共有四種通訊模式,它們的主要區別是總線空閑時SCK的時鐘狀態以及數據采樣時刻。為方便說明,在此引入“時鐘極性CPOL”和“時鐘相位CPHA”的概念。
?時鐘極性CPOL是指SPI通訊設備處于空閑狀態時,SCK信號線的電平信號(即SPI通訊開始前、 NSS線為高電平時SCK的狀態)。CPOL=0時, SCK在空閑狀態時為低電平,CPOL=1時,則相反。
?時鐘相位CPHA是指數據的采樣的時刻,當CPHA=0時,MOSI或MISO數據線上的信號將會在SCK時鐘線的“奇數邊沿”被采樣。當CPHA=1時,數據線在SCK的“偶數邊沿”采樣。

?我們來分析這個CPHA=0的時序圖。首先,根據SCK在空閑狀態時的電平,分為兩種情況。SCK信號線在空閑狀態為低電平時,CPOL=0;空閑狀態為高電平時,CPOL=1。
?無論CPOL=0還是=1,因為我們配置的時鐘相位CPHA=0,在圖中可以看到,采樣時刻都是在SCK的奇數邊沿。注意當CPOL=0的時候,時鐘的奇數邊沿是上升沿,而CPOL=1的時候,時鐘的奇數邊沿是下降沿。所以SPI的采樣時刻不是由上升/下降沿決定的。MOSI和MISO數據線的有效信號在SCK的奇數邊沿保持不變,數據信號將在SCK奇數邊沿時被采樣,在非采樣時刻,MOSI和MISO的有效信號才發生切換。

?類似地,當CPHA=1時,不受CPOL的影響,數據信號在SCK的偶數邊沿被采樣,見上圖。
?由CPOL及CPHA的不同狀態,SPI分成了四種模式,見下表,主機與從機需要工作在相同的模式下才可以正常通訊,實際中采用較多的是“模式0”與“模式3”。

3 軟件模擬
模式0

void SPI_write_read_mode1(unsigned int n_Data)
{
  unsigned char x = 0x00;
  unsigned int data;
  SPI_CS = 0;  
  delay_us(10);          
  for(x = 0x00;x < 8;x ++)
  {
    SPI_SCK = 0;                //數據發送
    if((n_Data & 0x80) == 0x80)  
       SPI_MOSI = 1;          
    else SPI_MOSI = 0;          
    n_Data = n_Data << 1;  
          
     SPI_SCK = 1;              //數據接收
     data<<=1;  
     if(SPI_MISO)  
     {data++;}
     SPI_SCK = 0;
  }
  
}

模式1

void SPI_write_read_mode2(unsigned int n_Data)
{
  unsigned char x = 0x00;
  unsigned int data;
  SPI_CS = 0;  
  delay_us(10);          
  for(x = 0x00;x < 8;x ++)
  {
    SPI_SCK = 1;                //數據發送
    if((n_Data & 0x80) == 0x80)  
       SPI_MOSI = 1;          
    else SPI_MOSI = 0;        
    n_Data = n_Data << 1;  
          
    SPI_SCK = 0;              //數據接收
    data<<=1;  
    if(SPI_MISO)  
    {data++;}
    SPI_SCK = 0;
  }
  
}

模式2

void SPI_write_read_mode3(unsigned int n_Data)
{
  unsigned char x = 0x00;
  unsigned int data;
  SPI_CS = 0;  
  delay_us(10);          
  for(x = 0x00;x < 8;x ++)
  {
    SPI_SCK = 1;                  //數據發送
    if((n_Data & 0x80) == 0x80)  
       SPI_MOSI = 1;          
    else SPI_MOSI = 0;          
    n_Data = n_Data << 1;  
          
    SPI_SCK = 0;                //數據接收 
    data<<=1;  
    if(SPI_MISO)  
    {data++;}
    SPI_SCK = 0;
  }
  SPI_SCK = 1;    
}

模式3

void SPI_write_read_mode4(unsigned int n_Data)
{
  unsigned char x = 0x00;
  unsigned int data;
  SPI_CS = 0;  
  delay_us(10);        
  for(x = 0x00;x < 8;x ++)
  {
    SPI_SCK = 0;                  //數據發送
    if((n_Data & 0x80) == 0x80)  
       SPI_MOSI = 1;          
    else SPI_MOSI = 0;          
    n_Data = n_Data << 1;  
          
    SPI_SCK = 1;                //數據接收
    data<<=1;  
    if(SPI_MISO)  
    {data++;}
    SPI_SCK = 0;
  }
  SPI_SCK = 1;  
}

參考資料:
1《STM32庫開發實戰指南-基于STM32F4》 劉火良,楊森編著 機械工業出版社
2 軟件模擬SPI部分的程序參考了公眾號“ Bernice堅果丁” https://mp.weixin.qq.com/s/SqKvReXRXCrqIj-G78I9CA

總結

以上是生活随笔為你收集整理的SPI通信的基础知识的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。