STM32內部flash存儲小數——別樣的C語言技巧


今天在進行STM32內部falsh存儲的時候,發現固件庫歷程的函數原型是這樣的:

第一個是地址,在我的STM32中是2K一頁的,第二個是要寫入的數據。

問題就來了,存儲一個小數該怎么辦呢?固件庫給的是整形數據啊!

三種解決辦法:

第一:最具大眾性的

把小數乘以系數放大,當做整數存儲,然后再除以放大系數得到小數本身。例如 float  a=1.23; int b=a*100;把b存進去,取出來的時候再除以100,就可以得到小數a了。這是最簡單可能也是最好想到的了,但同時,這也是最麻煩的了。稍有C語言基礎的都不會選擇這個方式,所以pass 掉了。

第二:基礎扎實性的

不管你說小數,還是整數,在內存中的二進制表述形式都是0或1的組合,關鍵就在於怎么去解析,這里也不去說符合

IEEE 754什么規范了,記住就是,C語言中float 4字節,double 8字節。在筆者的IDE上,指針是4字節的。
所以,我們可以這樣調用ST的庫函數:
eg:
Address為內部flash的一個地址;
float  a=1.23;
FLASH_ProgramWord(Address,*(volatile uint32_t *)&a);
先對a取地址,然后把這個地址強轉成uint32_t *類型,再解引用,此時編譯器會按照整形的規則去解讀這個地址的內容,
但是最后在取出這個地址的內容時,我們這樣:
*(__IO float*) Address
首先是把地址轉換成float *類型,然后解引用,編譯器就會按照float的規則取解讀這個地址里的內容了,這樣就可以存儲小數了。
第三種:創新深思性的
C語言中,有一個東西叫做聯合,union。同樣列舉上面的例子 float數據a;
建立聯合體如下:

union test
{
  float a;
  uint32_t b;
}Test;

Test.a=1.23;
你不是說ST庫函數是uint32_t(4字節)類型的嗎?那好,我就用聯合體來給你存,
FLASH_ProgramWord( Address,Test.b);這樣進行存儲,聯合體的實質還是第二種方式的理論。
讀取flash數據的時候,也是直接按照庫函數讀取:
*(__IO uint32_t*) Address
但是,這樣的數據可以直接和Test.b比較,看看是否相等,相等證明寫入和讀取一致,是成功的。當我們想用float數據的時候,
直接使用Test.a

Summary:
活學活用C語言,帶着創造性去研究,方能看到些許 Linus Torvalds的思維。



免責聲明!

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



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