一 問題
最近在一個項目中,調試SPI的過程中遇到一個問題——接收數據整體向左移了一位(1bit)。SPI數據收發是數據交換,因此接收數據時從第二個字節開始纔是有效數據,也就是數據整體向右移一個字節(1byte)。這個問題非常具備典型性,也暴露了筆者自身知識的一些薄弱點。這裏做一個總結。
二 根源
這個問題的根源是SPI master和SPI salve的配置出現了差異。具體哪個配置,筆者花費了一些功夫,還是找到了其中的端倪呢。
其實,就是主機從機的CPOL和CPHA配置相反導致的。那麼,到底什麼是CPOL和CPHA呢?
SPI串行同步時鐘可以設置爲不同的極性(Clock Polarity ,CPOL)與相位(Clock Phase ,CPHA)。
時鐘的極性(CPOL)用來決定在總線空閒時,同步時鐘(SCK)信號線上的電位是高電平還是低電平。當時鍾極性爲0時(CPOL=0),SCK信號線在空閒時爲低電平;當時鍾極性爲1時(CPOL=1),SCK信號線在空閒時爲高電平;
時鐘的相位(CPHA)用來決定何時進行信號採樣。這兩個配置一樣的時候,就可以解決問題了。STM32 的SPI
接口如下所示:
hspi2.Init.CLKPolarity = SPI_POLARITY_LOW;
hspi2.Init.CLKPhase = SPI_PHASE_1EDGE;
三 概念
1.CPOL極性
先說什麼是SCLK時鐘的空閒時刻,其就是當SCLK在發送8個bit比特數據之前和之後的狀態,
於此對應的,SCLK在發送數據的時候,就是正常的工作的時候,有效active的時刻了。
其英文精簡解釋爲:Clock Polarity = IDLE state of SCK。
SPI的CPOL,表示當SCLK空閒idle的時候,其電平的值是低電平0還是高電平1:
CPOL=0,時鐘空閒idle時候的電平是低電平,所以當SCLK有效的時候,就是高電平,就是所謂的active-high;
CPOL=1,時鐘空閒idle時候的電平是高電平,所以當SCLK有效的時候,就是低電平,就是所謂的active-low;
2.CPHA相位
首先說明一點,capture strobe = latch = read = sample,都是表示數據採樣,數據有效的時刻。
相位,對應着數據採樣是在第幾個邊沿(edge),是第一個邊沿還是第二個邊沿,
0對應着第一個邊沿,1對應着第二個邊沿。對於:
CPHA=0,表示第一個邊沿:
對於CPOL=0,idle時候的是低電平,第一個邊沿就是從低變到高,所以是上升沿;
對於CPOL=1,idle時候的是高電平,第一個邊沿就是從高變到低,所以是下降沿;
CPHA=1,表示第二個邊沿:
對於CPOL=0,idle時候的是低電平,第二個邊沿就是從高變到低,所以是下降沿;
對於CPOL=1,idle時候的是高電平,第一個邊沿就是從低變到高,所以是上升沿;