六、【STM32】eeprom的使用 以13届省赛为例
題目要求:
?
首先將下面兩個(gè)函數(shù)加到程序中(記住),比賽時(shí)應(yīng)該需要自己寫:在文章末尾會(huì)有一點(diǎn)說明。
//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(); }接下來就是稍微麻煩的地方了,就是判斷是否為第一次上電,其實(shí)以后比賽記住這種模式就可以:稍微解釋一下:我們可以隨便讀取EEPROM里的任意單元地址(不要和我們需要保存的數(shù)據(jù)地址相同)里的數(shù)據(jù)。對(duì)該數(shù)據(jù)進(jìn)行判斷,是否等于一個(gè)0x27(等于別的也可以),如果不等于0x27,則讀取到的是EEPROM原本存儲(chǔ)的值,說明是第一次上電,將0xf8寫進(jìn)該單元,此時(shí)該單元的值等于0x27。如果等于0x27,則說明不是第一次上電。其實(shí)這種方法也有一點(diǎn)點(diǎn)誤差1/256%,也可以忽略不計(jì)了吧。產(chǎn)生誤差的原因是第一次上電eeprom讀取的數(shù)據(jù)有可能和原來相應(yīng)位置存儲(chǔ)的數(shù)據(jù)相同,這就為會(huì)產(chǎn)生錯(cuò)誤了。
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);} }題目中要求每次修改庫存數(shù)量和價(jià)格時(shí)都要更新eeprom存儲(chǔ)的值,那我們就在按鍵相應(yīng)部分加上一條更新語句就可以啦!如下圖所示>>>
EEPROM單字節(jié)讀取方式
寫函數(shù)
void EEPROM_Write(uint8_t add,uint8_t date) {I2CStart();//起始I2CSendByte(0xa0);//控制字,寫I2CWaitAck();I2CSendByte(add);//片內(nèi)單元地址I2CWaitAck();I2CSendByte(date);//寫入的字節(jié)I2CWaitAck();I2CStop(); //停止 }讀函數(shù):
uint8_t EEPROM_Read(uint8_t add) {uint8_t temp;I2CStart();//起始I2CSendByte(0xa0);//控制字,告訴EEPROM進(jìn)行寫字節(jié)操作I2CWaitAck();I2CSendByte(add);//片內(nèi)單元地址I2CWaitAck();I2CStop();//停止I2CStart();//起始I2CSendByte(0xa1);//控制字,告訴EEPROM進(jìn)行讀字節(jié)操作I2CWaitAck();temp=I2CReceiveByte();//讀取字節(jié)I2CSendNotAck();I2CStop(); //停止return temp; }AT24C02(EEPROM)片內(nèi)地址從0x00到0xff共256個(gè)地址單元,每個(gè)地址單元可以存放一個(gè)字節(jié)。需要注意的是,連續(xù)多個(gè)字節(jié)寫入EEPROM要進(jìn)行10ms的延時(shí),這是因?yàn)镋EPROM處理數(shù)據(jù)的速度遠(yuǎn)小于單片機(jī)的速度,為了防止數(shù)據(jù)丟失,所以需要延時(shí)。
????上述代碼中的add即為EEPROM的片內(nèi)地址,上述代碼中的date即為寫入EEPROM的數(shù)據(jù)。
????以上代碼就是單字節(jié)的讀寫函數(shù),每次只能讀寫一個(gè)字節(jié)。這些代碼比賽是需要我們自行編寫的。
讀寫舉例:
uint8_t date=26;
EEPROM_Write(0x00,date);//寫入EEPROM的0x00單元,數(shù)據(jù)大小為26的uint8_t類型數(shù)據(jù)。
date=19;
date=EEPROM_Read(0x00);//讀取EEPROM的0x00單元數(shù)據(jù),當(dāng)前date大小為26
?
?EEPROM多字節(jié)讀取方式
多字節(jié)讀寫函數(shù)
優(yōu)點(diǎn):
????EEPROM不但可以單字節(jié)讀寫,還可以按頁一次性多個(gè)字節(jié)讀寫,每頁8個(gè)字節(jié),所以最多可以連續(xù)讀寫8個(gè)字節(jié),非常的方便。我們只需要向EEPROM傳遞EEPROM每頁的首地址,就可以連續(xù)讀寫多個(gè)字節(jié)。
????除此之外,多字節(jié)讀寫方式對(duì)于多字節(jié)的基本數(shù)據(jù)類型的讀寫也非常簡單。有效的解決了前面的問題。例如8個(gè)字節(jié)的double,4個(gè)字節(jié)的float,2個(gè)字節(jié)的uint16_t,很多同學(xué)都會(huì)進(jìn)行相應(yīng)的換算,這樣著實(shí)麻煩。
????我們知道在相同的平臺(tái)上,相同的數(shù)據(jù)類型,在內(nèi)存中所占的字節(jié)大小是固定的,而且單個(gè)數(shù)據(jù)變量的字節(jié)在內(nèi)存上的排布是連續(xù)的,所以,我們可以直接將該變量的所有字節(jié)寫入EEPROM中,讀取的時(shí)候,也是將相應(yīng)的字節(jié)都讀取出來,不用任何類型換算。
????當(dāng)然理解這部分內(nèi)容需要對(duì)于指針和地址,要有一點(diǎn)點(diǎn)的了解。不懂也沒關(guān)系,會(huì)用就可以。
寫函數(shù)
void EEPROM_Write(uint8_t add,uint8_t * array,uint8_t n) {I2CStart();I2CSendByte(0xa0);//寫操作I2CWaitAck();I2CSendByte(add);//片內(nèi)單元地址I2CWaitAck();while(n--)//進(jìn)行n次循環(huán),寫入n個(gè)數(shù)據(jù),每次寫入進(jìn)行一次等待。{I2CSendByte(*array++);I2CWaitAck();}I2CStop(); }讀函數(shù):
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)//如果還有數(shù)據(jù)要讀取{I2CSendAck();}else//如果沒有數(shù)據(jù)要讀取{I2CSendNotAck();}}I2CStop();}延時(shí)問題
????無論是單字節(jié)的讀寫方式,還是多字節(jié)的讀寫方式,向EEPROM寫入數(shù)據(jù)的時(shí)候都要進(jìn)行相應(yīng)的延時(shí),建議延時(shí)10ms,這個(gè)問題前面有講到。主要是因?yàn)镋EPROM的速度跟不上stm32的速度。
更加詳細(xì)的eeprom講解請(qǐng)參考:(72條消息) 藍(lán)橋杯嵌入式(G431RBT6): EEPROM進(jìn)階學(xué)習(xí)_電子鸚鵡的博客-CSDN博客
總結(jié)
以上是生活随笔為你收集整理的六、【STM32】eeprom的使用 以13届省赛为例的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: WLAN配置三层直连直接转发
- 下一篇: ps +pxcook切图 后转移到 ax