關於 STM32 中 SPI 做從機和半雙工的理解和使用


前言

最近調試工作上用到和很多SPI,不同傳感器的、不同控制平台之間的。遇到了不少奇奇怪怪的問題,記錄一下。主要是stm32上這個平台上的使用,當然對於SPI這個常用的通信協議這里不多介紹了,可以找一下相關的資料熟悉相關概念和使用,全雙工下的使用無論是中斷還是DMA都比較簡單沒有啥好說的,這里就講一下做從機和使用半雙工的一些問題。

從機

由於使用 stm32 做從機的時候使用的是軟件去操作CS引腳,出現的問題是從機接收端會出現錯誤的數據,對比發現是數據錯位了,出現這種情況可能是 SPI 主機復位、主機重新重新上電、意外的時鍾電平干擾都可能會讓 SPI 從機接受數據的時候錯位,整體數據右移了。所以一開始的解決思路就是看有沒有相關的操作可以在每次清空掉RX - Shift Register里面的錯誤數據,但是查了很多資料都沒有相關的描述。

嘗試了如下的方式:

  • 關閉使能關閉后重新打開
  • 關閉SPI時鍾后重新初始化(deinit)

結論是關閉SPI使能位SPE后在打開使能,問題依舊仍是接受到了錯誤數據;而使用后面的操作可以清除掉原來移位寄存器中的數據,為了速度直接使用寄存器賦值的操作直接先關閉 spi 時鍾后再重新打開,然后對 CR1 賦值完成初始化,實測第二種方式解決了我的問題

半雙工

關於半雙工的使用是因為使用 TLE5012B 這個磁編碼器的時候它使用的是3線的 SPI ,發送和接受數據都在同一條數據線上分時復用也就是半雙工的方式,但是看了網上很多資料發現他們的操作都是使用下面這種方式,在MOSI和MISO之間串聯一個電阻這樣就可以使用全雙工的SPI去通信了。不過我印象中stm32 的SPI 是支持半雙工通信的,所以嘗試了一下使用半雙工的方式來通信。

  • 更改后使用如下的連接方式

  • 半雙工和只讀模式

    這里配置成雙向數據線

  • 發送和接受的切換

    有前面可以知道傳輸的方向是由 BIDIOE 位控制的所以只需要在發送完成的時候切換成接受狀態就可以了,那什么時候可以切換狀態呢,首先先等待TXE = 1 ,這表明數據移入到移位寄存器中開始發送,接着等待 BSY = 0,這表明物理線上的傳輸已經結束了,這時候我們就可以切換狀態到接受模式了,在hal庫和LL庫中都有相應的操作,當然也可以直接操作 BIDIOE 這個位進入到接受模式。

  • 時鍾信號的控制

可以看出在雙向模式接受的是時候只要使能了SPE,那么就意味着傳輸開始了,SPI主機會自動發送時鍾這時候就可以接受到數據

  • 參考代碼
uint8_t send_and_read_byte(uint8_t cmd)
{
    uint8_t result;
    GPIO_ResetBits(GPIOA, GPIO_Pin_4); // CS low
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) == RESET); //wait buffer empty
    SPI_SendData8(SPI1, cmd);
    while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_BSY) == SET); //wait finish sending
    // Read receiving FIFO until it is empty
    while (SPI_GetReceptionFIFOStatus(SPI1) != SPI_ReceptionFIFOStatus_Empty)
        SPI_ReceiveData8(SPI1);
    SPI_BiDirectionalLineConfig(SPI1, SPI_Direction_Rx);
    while (!(SPI1->SR & SPI_I2S_FLAG_RXNE)) ; // wait data received
    GPIO_SetBits(GPIOA, GPIO_Pin_4); // CS high
    SPI1->CR1 |= SPI_Direction_Tx;  // Set Tx mode to stop Rx clock
    result = SPI_ReceiveData8(SPI1);
    return result;
}  

參考:HOWTO: Use STM32 SPI half duplex mode – Digital Me (ba0sh1.com)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM