1. 程式人生 > >STM32值SPI的使用及SPI初始化注意事項

STM32值SPI的使用及SPI初始化注意事項

在STM32F10x系列晶片中,雖然所擁有的SPI同步串列埠數量不相同,但是初始化的方法都是一樣的。其中使用SPI時候我們回憶GPIO的使用,要注意6點,我們這裡主要講解一點。

根據系統對該不同功能的要求,初始化不同功能外設,初始化GPIO,初始化SPI同步串列埠裝置就會比較複雜。STM32F10x系列晶片的所有SIP同步串列埠都是和GPIO共用,SPI的初始化分為2大塊,就是SPI所使用的I/O口的初始化和SPI功能的初始化。對於SPI同步串列埠要用到的引腳,根據資料的方向,要設定GPIO_Mode_IN_FLOATING或者GPIO_Mode_AF_PP複用推免輸出。其他的和GPIO引腳設定一樣。

至於低於SPI同步串列埠引數的初始化方法將在之後的一個例子中體現出來。

我們在使用SPI時候,必須開啟SPI的同步串列埠的時鐘。這樣系統才可以從這個開啟的同步串列埠中傳送和接收資料。

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1,ENABLE);

在SPI傳送資料很簡單,把要傳送的資料位元組寫進發送緩衝器時,傳送過程就開始了。只不過在試圖寫傳送緩衝器之前,需要確認TXE標誌是否為1.

同樣對於接收器而言,當資料傳輸完成時,資料結束以後也完成。在最後取樣時鐘沿,RXNE標誌位置位。在移位暫存器中接收到的資料字被傳送到接收快取器。都SPI_DR暫存器時將清楚RXNE位。

故:在傳送資料時要判斷上一次的資料是否傳送完成。只有資料傳送完成才可以進行新的資料的傳送。

例:要用PA7做SPI1同步串列埠的MOSI引腳,用PA6做SPI1同步串列埠的MISO引腳,同PA5做SCK引腳,用PA4做NSS片選引腳。在定義同步串列埠SPI1為主裝置,每次傳送8個 資料位,高位在前,SPI時鐘頻率為9MHz,資料捕獲在第二個時鐘沿,時鐘空閒時為低電平,NSS引腳有軟體管理。

完整的程式碼如下:

#include"stm32f10x_lib.h"

void SPI_Configuration(void)

{

//SPI_1串列埠引數部分定義,SPI_1引數為時鐘平時為高,上升沿取樣

SPI_InitTypeDef  SPI_InitStructure;

GPIO_InitTypeDef  GPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI2,ENABLE);//使能SPI_2時鐘

//配置SPI1的MISO(PA6)為浮空輸入

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;

GPIO_InitStructure.GPIO_MODE = GPIO_Mode_IN_FLOATING;

GPIO_Init(GPIOA,&GPIO_InitStructure);

//配置SPI1的MOSI(PA7)和SPI1的CLK(PA5)為複用推免輸出

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_7;

GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

GPIO_Init(GPIOA,&GPIO_InitStructure);

//配置SPI1的NSS(PA4)為推免輸出

GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;

GPIO_InitSturcture.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;

GPIO_Init(GPIOA,&GPIO_InitSturcture);

//SPI1同步引數初始化定義

SPI_InitTypeDef SPI_InitStructure;

SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_Fullduplex;

SPI_InitStructure.SPI_Mode = SPI_Mode_Master;

SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;

SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;

SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;

SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;

SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_4;

SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;

SPI_InitStructure.SPI_CRCPolynomial = 7;

SPI_Init(SPI1,&SPI_InitStructure);

SPI_Cmd(SPI1,ENABLE);

}

//通過SPI1口傳送一個數據,同時接受一個數據

unsigned char SPI_SendByte(unsigned char Byte)

{

//如果傳送暫存器資料沒有傳送完,迴圈等待

while(SPI_T1S_GetFlagStatus(SPI1,SPI_T1S_FLAG_TXE) == RESET);

//往傳送暫存器寫入要傳送的資料

SPI_T1S_SendData(SPI2,Byte);

//如果接受暫存器沒有收到資料,迴圈

while(SPI_T1S_GetFlagStatus(SPI1,SPI_T1S_FLAG_RXNE) == RESET);

return SPI_T1S_ReceiveData(SPI1);

}