spi協議,即序列外圍裝置介面,是一種高速的全雙工通訊匯流排。spi匯流排在實際電路中相當常見,比如flash晶元讀寫,以及ad晶元等。spi訊號線一般有4條匯流排,片選cs,時鐘線clk,兩條資料線mosi和miso,。因為spi分主從機,所以mosi是主機輸出從機輸入的資料線,而miso則是主機輸入從機輸出資料線。
片選訊號(cs):類似於使能位,一般低電平有效,只有當cs為低電平的時候,spi才算有效。
時鐘訊號(clk):時鐘的上公升沿或者下降沿,才是資料被取樣的時刻。
在stm32微控制器中,其自帶spi外設,並被分為4種spi模式,主要是根據spi時鐘極性(cpol)以及時鐘相位(cpha)。時鐘極性是指spi在裝置處於空閒時的狀態,clk的電平訊號,cpol=0,clk在空閒狀態時為低電平,cpol=1時為高電平。而時鐘相位是指資料被取樣的時刻,cpha=0.,資料線上的訊號將會在clk時鐘的奇數邊沿被取樣,當cpha=1,
則是在clk的偶數邊沿取樣。
雖然上面解釋了一堆,但是實際使用時,上述的通用spi具有一定的侷限性,為什麼這麼說呢?
void spi_i2s_senddata(spi_typedef* spix, uint16_t data);
uint16_t spi_i2s_receivedata(spi_typedef* spix);
上面兩條函式是stm32函式庫自帶的,可以發現其傳送或者讀取只能是16bit資料,很多情況下,我們使用spi傳輸的一幀資料不會恰巧是16bit(或者8bit和32bit),比如下面這個時序:
雖然和我們上述說的4線spi不太一樣,但是其本質上也是spi序列匯流排,此時的資料還是108位的,這個時候我們使用函式庫自帶的函式就不太好用了,這個時候可以考慮自己模擬spi匯流排。我們首先分析,上述的spi匯流排也是4根線。sel即片選cs,低電平有效,clk,預設低電平並且資料是在下降沿被取樣,data資料傳108位,並低位先傳,最後的ld類似於鎖存。
void spi_write(u32*data)
unsigned char i,j;
u32 writedata;
gpio_setbits(gpioc,gpio_pin_7);//設定gpioc的7引腳為片選(sel),並將其拉高
gpio_resetbits(gpioc,gpio_pin_6);//設定gpioc的6引腳為時鐘(clk),並將其拉低
gpio_resetbits(gpioc,gpio_pin_9);//設定gpioc的9引腳為鎖存(ld),並將其拉低
gpio_resetbits(gpioc,gpio_pin_7);//將sel拉低,意味著使能有效
for(i=0;i<4;i++)
writedata=*(data+i); // writedata為區域性變數
for(j=0;j<27;j++) //雖然是定義了乙個32位的資料,但是只用到27位
gpio_setbits(gpioc,gpio_pin_6);//拉高clk,但是此時不取樣
if(writedata&(1
else
gpio_resetbits(gpioc,gpio_pin_8);//資料位拉低
delay(100); //做乙個延時讓資料保持一段時間
gpio_resetbits(gpioc,gpio_pin_6); //clk拉低,此時資料被取樣
delay(100); //讓clk的電平保持一段時間
}//一共4組,每組27位資料,正好是108位
gpio_setbits(gpioc,gpio_pin_7);//資料傳輸好後cs位拉高,意味著通訊結束
gpio_setbits(gpioc,gpio_pin_9);//此時拉高ld位(中間可以適當加延時)
delay(100);//讓ld保持一段高電平
gpio_resetbits(gpioc,gpio_pin_9);//z最後將ld拉低
上述的函式完成了整個spi的傳輸,其實spi的傳輸有很多形式,上面的函式稍作改動可以完成通用模式的spi傳輸。
比如傳輸位數n,如果傳輸的是n位,那麼首先看n與8、16、32位的關係,比如我這裡的108位,傳4組,那我每組其實有5為是無效的,那麼我在做判斷時只要判斷u32 writedata的後27位,前5位就直接可以捨棄。
那如果我是上公升沿取樣呢,那麼clk最開始還是拉低,等到資料做完判斷後再拉高並保持一段時間就好了。
那如果我是高位先傳呢,那麼for函式就可寫成for(i=3;i>=0;i--);for(j=26;j>=0;j--)。
如果你真的熟練使用模擬spi,那麼或許你對stm32自帶的spi的cpha和cpol已經沒那麼在意了。但是也要注意,在講究高時速的場合,模擬spi的傳輸速率還是和通用spi有差距的,所以在選擇使用模擬spi的時候,要檢視是否滿足速率要求哦。
STM32之間SPI通訊
這幾天實驗室比較忙,所以部落格這邊停了一下,繼續吧。繼串列埠中斷後,大家可以嘗試微控制器間串列埠通訊,這裡就不再多贅述。串列埠完了之後,我接著學的就是spi通訊了,作為hello moto公司推出的這種4線全雙工通訊,很節約pcb布局空間,但缺點就是沒有指定的流控制,沒有應答機制來確定訊號收到與否,...
STM32 快速上手SPI
基本的部分前文 stm32 spi 已經介紹過了,這裡只記怎麼用。stm32f103zet6的三個spi的引腳分別為 spi1在apb1時鐘下,spi2和spi3在apb2時鐘下。void spi i2s deinit spi typedef spix void spi init spi typed...
STM32中SPI概述與程式設計
spi 是英語serial peripheral inte ce的縮寫,顧名思義就是序列外圍裝置介面。是motorola首先在其mc68hcxx系列處理器上定義的。c1101的引腳為 vcc gnd csn si so sck gd00 gd02 後兩個貌似可以不接,他們能產生中斷 spi,是一種高...