STM32 的SPI讀寫函數解析

//SPIx 讀寫一個字節

//TxData:要寫入的字節

//返回值:讀取到的字節

u8 SPIx_ReadWriteByte(u8 TxData)

{                                                              

         while((SPI1->SR&(1<<1))==0);           

         SPI1->DR=TxData;            //發送一個byte          

         while((SPI1->SR&(1<<0))==0);                                                           

         returnSPI1->DR;          //返回收到的數據                                  

}

 

 

對於這樣的讀寫函數曾有這樣的疑惑,讀就是讀寫就寫爲什麼要放一起呢。這樣是不是很麻煩,查詢相關資料有如下解答。

 

轉自:http://www.ec66.com/article/list.asp?indexid=4538

a)寫一個字節:

​while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

//確保發生前Buffer爲空,也就是說上一次已經發生完成

​SPI_I2S_SendData(SPI1, Data); 

//往寄存器中寫入一個字節

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET);

//等待接受到一個字節數據,

爲什麼要這麼做?加這一句的原因是爲了確保這個字節已經發送出去因爲發生和接受是並行同步進行,那就是說你發生出去一個字節意味着你收到一個字節。所以這樣判斷完全沒有問題,再說必要性,如果你不加這句你就會容易犯過早拉高CS信號的錯誤(相當於檢測到收到數據,那麼說明數據一定發完了),你想想如果在SPI_I2S_SendData(SPI1, Data)後面立即拉高CS是什麼後果。SPI_I2S_ReceiveData(SPI1); //都會接收到的數據,看起來沒什麼必要,但以用stm32的經驗推薦這樣做,也許會有意想不到的收穫。

SPI_Writebyteu8data

{

while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);

SPI_I2S_SendData(SPI1, Data); 

​while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); 

​SPI_I2S_ReceiveData(SPI1);

 }

b)​讀一個字節:讀的時候要注意一個問題,因爲從模式是沒法提供時鐘的,所以主模式下必須要在接收的同時提供時鐘。辦法就是發送一個字節來實現,因爲還是上面說的,發送一個字節就意味着收到一個字節,代碼和寫完全一樣,只要把讀出來的字節保存即可。u8 SPI_Readbyteu8data{ while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET);SPI_I2S_SendData(SPI1, Data); while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) == RESET); return SPI_I2S_ReceiveData(SPI1); }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章