STM32F0系列芯片SPI發送一字節數據卻輸出16個CLK時鍾的解決辦法


問題

上一個項目在用寄存器操作STM32F0芯片的SPI_DR寄存器的時候,發現一個問題:

我給DR寄存器賦值一個uint8_t一字節大小的數據,SPI引腳能正確輸出數據和時鍾,但前面八位正確的數據輸出完成后,時鍾CLK沒有停下來,又緊接着輸出了八個時鍾脈沖

也就是原數據0xfe 變成了十六位的 0xfe00 , 導致時序錯誤,使用邏輯分析才得以檢查出來

 

為什么

去國外的st論壇轉了一圈,發現有幾個老外也是遇到了相同的問題,但他們是使用正確的固件庫函數解決的,這並不是我想要找到的寄存器解決方法

后來又認真閱讀了一次F030的數據手冊,又仔細看了很久的HAL庫底層代碼,終於找到了問題所在:

如果你要spi輸出一個字節八個時鍾的數據,應該只操作SPI_DR寄存器的低八位,什么意思呢?

DR寄存器是16位的,如果你直接SPI1->DR = 0x85 ; 這樣的操作是不正確的,你的數據會變成0x0085之后賦值給DR寄存器,也就是操作了16位,所以STM32會輸出16個時鍾脈沖

 

怎么辦

那么看看我是怎么改的:

1 void SPI_WriteByte(uint8_t BYTE)
2 {
3     //將DR寄存器的地址向后偏移1字節再賦值,不能操作高八位只能賦值給低八位
4     *((uint8_t*)&(SPI1->DR) + 1 ) = BYTE ;
5     while(SPI1->SR & 0x80);//等待BSY為空閑
6 }

我們先找到DR寄存器的地址,再用一個八位的指針指向這個地址,現在指向的是DR寄存器的開頭,那么指針+1,指針指向了DR寄存器的低八位

這時候給指針指向的地址賦值0x85,那么這個字節就會放入DR低八位的空間內,而不是操作整個16位DR寄存器

去看看那SPI的輸出把,哈哈,正常了,八位數據對應八個時鍾然后結束 ;

 

嘻嘻

希望能幫助到在學習或者工作中遇到同樣問題的朋友


免責聲明!

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



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