日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

六、【STM32】eeprom的使用 以13届省赛为例

發布時間:2024/3/26 编程问答 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 六、【STM32】eeprom的使用 以13届省赛为例 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目要求:

?

首先將下面兩個函數加到程序中(記住),比賽時應該需要自己寫:在文章末尾會有一點說明。

//EEPROM_Read void EEPROM_Read(uint8_t add,uint8_t * array,uint8_t n){I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CStop();I2CStart();I2CSendByte(0xa1);I2CWaitAck();while(n--){*array++=I2CReceiveByte();if(n){I2CSendAck();}else{I2CSendNotAck();}}I2CStop();}void EEPROM_Write(uint8_t add,uint8_t * array,uint8_t n){I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(add);I2CWaitAck();while(n--){I2CSendByte(*array++);I2CWaitAck();}I2CStop(); }

接下來就是稍微麻煩的地方了,就是判斷是否為第一次上電,其實以后比賽記住這種模式就可以:稍微解釋一下:我們可以隨便讀取EEPROM里的任意單元地址(不要和我們需要保存的數據地址相同)里的數據。對該數據進行判斷,是否等于一個0x27(等于別的也可以),如果不等于0x27,則讀取到的是EEPROM原本存儲的值,說明是第一次上電,將0xf8寫進該單元,此時該單元的值等于0x27。如果等于0x27,則說明不是第一次上電。其實這種方法也有一點點誤差1/256%,也可以忽略不計了吧。產生誤差的原因是第一次上電eeprom讀取的數據有可能和原來相應位置存儲的數據相同,這就為會產生錯誤了。

void System_Init(){u8 temp;EEPROM_Read(0x07, &temp, 1);if(temp!=0x27){//不等于0x27是第一次上電temp = 0x27;EEPROM_Write(0x07,&temp,1);HAL_Delay(10);EEPROM_Write(0x00,&X_Count,1);HAL_Delay(10);EEPROM_Write(0x01,&Y_Count,1);HAL_Delay(10);EEPROM_Write(0x02,&X_Price,1);HAL_Delay(10);EEPROM_Write(0x03,&Y_Price,1);HAL_Delay(10);}else{//不是第一次上電EEPROM_Read(0x00,&X_Count,1);HAL_Delay(10);EEPROM_Read(0x01,&Y_Count,1);HAL_Delay(10);EEPROM_Read(0x02,&X_Price,1);HAL_Delay(10);EEPROM_Read(0x03,&Y_Price,1);HAL_Delay(10);} }

題目中要求每次修改庫存數量和價格時都要更新eeprom存儲的值,那我們就在按鍵相應部分加上一條更新語句就可以啦!如下圖所示>>>

EEPROM單字節讀取方式

寫函數

void EEPROM_Write(uint8_t add,uint8_t date) {I2CStart();//起始I2CSendByte(0xa0);//控制字,寫I2CWaitAck();I2CSendByte(add);//片內單元地址I2CWaitAck();I2CSendByte(date);//寫入的字節I2CWaitAck();I2CStop(); //停止 }

讀函數:

uint8_t EEPROM_Read(uint8_t add) {uint8_t temp;I2CStart();//起始I2CSendByte(0xa0);//控制字,告訴EEPROM進行寫字節操作I2CWaitAck();I2CSendByte(add);//片內單元地址I2CWaitAck();I2CStop();//停止I2CStart();//起始I2CSendByte(0xa1);//控制字,告訴EEPROM進行讀字節操作I2CWaitAck();temp=I2CReceiveByte();//讀取字節I2CSendNotAck();I2CStop(); //停止return temp; }

AT24C02(EEPROM)片內地址從0x00到0xff共256個地址單元,每個地址單元可以存放一個字節。需要注意的是,連續多個字節寫入EEPROM要進行10ms的延時,這是因為EEPROM處理數據的速度遠小于單片機的速度,為了防止數據丟失,所以需要延時。
????上述代碼中的add即為EEPROM的片內地址,上述代碼中的date即為寫入EEPROM的數據。
????以上代碼就是單字節的讀寫函數,每次只能讀寫一個字節。這些代碼比賽是需要我們自行編寫的。
讀寫舉例:

uint8_t date=26;
EEPROM_Write(0x00,date);//寫入EEPROM的0x00單元,數據大小為26的uint8_t類型數據。
date=19;
date=EEPROM_Read(0x00);//讀取EEPROM的0x00單元數據,當前date大小為26
?

?EEPROM多字節讀取方式

多字節讀寫函數
優點:
????EEPROM不但可以單字節讀寫,還可以按頁一次性多個字節讀寫,每頁8個字節,所以最多可以連續讀寫8個字節,非常的方便。我們只需要向EEPROM傳遞EEPROM每頁的首地址,就可以連續讀寫多個字節。
????除此之外,多字節讀寫方式對于多字節的基本數據類型的讀寫也非常簡單。有效的解決了前面的問題。例如8個字節的double,4個字節的float,2個字節的uint16_t,很多同學都會進行相應的換算,這樣著實麻煩。
????我們知道在相同的平臺上,相同的數據類型,在內存中所占的字節大小是固定的,而且單個數據變量的字節在內存上的排布是連續的,所以,我們可以直接將該變量的所有字節寫入EEPROM中,讀取的時候,也是將相應的字節都讀取出來,不用任何類型換算。

????當然理解這部分內容需要對于指針和地址,要有一點點的了解。不懂也沒關系,會用就可以。

寫函數

void EEPROM_Write(uint8_t add,uint8_t * array,uint8_t n) {I2CStart();I2CSendByte(0xa0);//寫操作I2CWaitAck();I2CSendByte(add);//片內單元地址I2CWaitAck();while(n--)//進行n次循環,寫入n個數據,每次寫入進行一次等待。{I2CSendByte(*array++);I2CWaitAck();}I2CStop(); }

讀函數:

void EEPROM_Read(uint8_t add,uint8_t * array,uint8_t n) {I2CStart();I2CSendByte(0xa0);I2CWaitAck();I2CSendByte(add);I2CWaitAck();I2CStop();I2CStart();I2CSendByte(0xa1);I2CWaitAck();while(n--){*array++=I2CReceiveByte();//讀取if(n)//如果還有數據要讀取{I2CSendAck();}else//如果沒有數據要讀取{I2CSendNotAck();}}I2CStop();}

延時問題

????無論是單字節的讀寫方式,還是多字節的讀寫方式,向EEPROM寫入數據的時候都要進行相應的延時,建議延時10ms,這個問題前面有講到。主要是因為EEPROM的速度跟不上stm32的速度。

更加詳細的eeprom講解請參考:(72條消息) 藍橋杯嵌入式(G431RBT6): EEPROM進階學習_電子鸚鵡的博客-CSDN博客

總結

以上是生活随笔為你收集整理的六、【STM32】eeprom的使用 以13届省赛为例的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。