1. 程式人生 > >關於SPI通信原理與程序實現

關於SPI通信原理與程序實現

時鐘 程序 size mos pre img 平時 gpo 基於

第一次接觸SPI是因為當時用到NRF24L01,需要用SPI進行通信。因為2401上面寫著MOSI、MISO、SS、RST,當時以為只要用到SPI就肯定有這幾個引腳,以至於限制了自己的思維。只認識MISO/MOSI/,並不知道他們的真實意義。所以後來遇到DO、DI、CS、RES時,就不知道是什麽意思了。真是一知半解。下面就說說一些關於SPI的那些事。

參考博客:https://www.cnblogs.com/deng-tao/p/6004280.html


1、什麽是SPI?
SPI是串行外設接口(Serial Peripheral Interface)的縮寫。是 Motorola 公司推出的一 種同步串行接口技術,是一種高速的,全雙工,同步的通信總線。

2、SPI優點
支持全雙工通信、通信簡單、數據傳輸速率塊

3、缺點
沒有指定的流控制,沒有應答機制確認是否接收到數據,所以跟IIC總線協議比較在數據 可靠性上有一定的缺陷。


4、特點
1):高速、同步、全雙工、非差分、總線式
2):主從機通信模式

5、協議通信時序詳解
1):SPI的通信原理很簡單,它以主從方式工作,這種模式通常有一個主設備和一個或多 個從設備,需要至少4根線,事實上3根也可以(單向傳輸時)。也是所有基於SPI的設備共有的,它們是

SDI(數據輸入)、SDO(數據輸出)、SCLK(時鐘)、CS(片選)。
(1)SDO/MOSI ((master out slaver in))– 主設備數據輸出,從設備數據輸入;
(2)SDI/MISO – 主設備數據輸入,從設備數據輸出;
(3)SCLK – 時鐘信號,由主設備產生;
(4)CS/SS – 從設備使能信號,由主設備控制。當有多個從設備的時候,因為每個從設 備上都有一個片選引腳接入到主設備機中,當我們的主設備和某個從設備通信時將需 要將從設備對應的片選引腳電平拉低或者是拉高。

技術分享圖片

SPI時序圖舉例:四線制,高位在前,下降沿跳邊,上升沿采樣。

技術分享圖片


2):需要說明的是,我們SPI通信有4種不同的模式,不同的從設備可能在出廠是就是配 置為某種模式,這是不能改變的;但我們的通信雙方必須是工作在同一模式下,所以我們 可以對我們的主設備的SPI模式進行配置,通過CPOL(時鐘極性)和CPHA(時鐘相位)來 控制我們主設備的通信模式,具體如下:
Mode0:CPOL=0,CPHA=0
Mode1:CPOL=0,CPHA=1
Mode2:CPOL=1,CPHA=0
Mode3:CPOL=1,CPHA=1
時鐘極性CPOL是用來配置SCLK的電平出於哪種狀態時是空閑態或者有效態,時鐘相位CPHA 是用來配置數據采樣是在第幾個邊沿:
CPOL=0,表示當SCLK=0時處於空閑態,所以有效狀態就是SCLK處於高電平時
CPOL=1,表示當SCLK=1時處於空閑態,所以有效狀態就是SCLK處於低電平時
CPHA=0,表示數據采樣是在第1個邊沿,數據發送在第2個邊沿
CPHA=1,表示數據采樣是在第2個邊沿,數據發送在第1個邊沿

需要註意的是:我們的主設備能夠控制時鐘,因為我們的SPI通信並不像UART或者IIC通信 那樣有專門的通信周期,有專門的通信起始信號,有專門的通信結束信號;這些SPI都沒有。所以我們的 SPI協議能夠通過控制時鐘信號線,當沒有數據交流的時候我們的時鐘線要麽是保持高電平要麽是保持低電平。

程序仿真:

/*    SPI寫數據/命令 
 *    Mode :O:寫命令   1:寫數據 
 *    data :數據/命令 
*/  
void SPI_Write(char data, int Mode)  
{      
    int i = 0; 
    
    if(Mode)  
    {  
        OLED_DC(1);        //DC引腳輸入高,表示寫數據  
    }  
    else  
    {  
        OLED_DC(0);        //DC引腳輸入低,表示寫命令  
    }  
    OLED_CS(0);            //CS引腳輸入低,片選使能  
    for(i = 0; i < 8; i++)  
    {  
        OLED_D0(0);        //D0引腳輸入低  
        if(data&0x80)    //判斷傳輸的數據最高位為1還是0  
        {  
            OLED_D1(1);    //D1引腳輸入高  
        }  
        else  
        {  
            OLED_D1(0);    //D1引腳輸入低  
        }  
        OLED_D0(1);        //D1引腳輸入高  
        data<<=1;        //將數據左移一位  
    }  
    OLED_DC(0);            //DC引腳輸入低  
    OLED_CS(1);            //CS引腳輸入高,片選失能  
}  

關於SPI通信原理與程序實現