EEPROM知識點總結
- 要點1—驅動代碼撰寫
- 要點2:
- (1)有符號6位數的存取
- (2)16位有符號數的存盤
- 要點3——必須加延時
- 要點4——幾乎每屆省賽都會遇到的問題(重要)
要點1—驅動代碼撰寫
藍橋杯比賽時會給模擬的iic驅動代碼,也就是下面這兩個.c和.h檔案,我們需要做的是,根據它提供的AT24C02資料手冊中的時序圖撰寫兩個函式來實作對EEPROM的讀寫操作,

我建議大家能夠理解這兩個時序圖,看著時序圖來撰寫讀寫函式,輕松的多,完全不需要背過下面這兩個函式,(時序圖就在資料手冊中)

在資料手冊中找到這兩個時序圖,


要點2:
(1)有符號6位數的存取
上面那兩個讀寫函式是對 unsigned char 型別資料,也就是8位無符號數操作的,有時候我們需要存盤16位無符號數的時候,可以采取這樣的方法:
void write_16(unsigned char add,u16 data)
{
unsigned char a,b;
a=data/256;
b=data%256;
i2c_write(add,b);Delay_Ms(5);
i2c_write(add+1,a);
}
u16 read_16(unsigned char add)
{
u16 a;
unsigned char c,b;
c=i2c_read(add);Delay_Ms(5);
b=i2c_read(add+1);
a=c+b*256;
return a;
}
(2)16位有符號數的存盤
需要先明白一點,有符號數和無符號數在存盤器里面都是由0和1組成的,有符號數只不過是把最高位用做符號位(1代表復數,0代表正數),所以,我想說的是,存盤16位有符號數時也可以用16位無符號數的存盤方法,只需要在讀取時加一個強制轉換即可,
short tem_up; //定義一個16位有符號數
......//沒有必要展示的代碼就略過了
......
......
tem_up=(short)read_16(0x03);//加個強制轉換 ,妥妥的
要點3——必須加延時
每兩個讀取或者寫入函式之間必須加5毫秒延時,是必須加,如果不加的話,資料非常容易亂(親身體驗),
原因是,EEPROM外設的讀取速度是跟不上MCU的運行速度的,需要讓MCU停下來等待一會兒,5ms咱們看著不起眼,對于CPU來說,已經是很長一段時間了,
要點4——幾乎每屆省賽都會遇到的問題(重要)
以第七屆省賽做一個分析(只關注EEPROM部分):

可以看到,題目要求,設備第一次上電,從EEPROM中讀取到的初始值為30、50、70,之后每次修改這三個數值,都將具體值存入EEPROM,設備再次上電,就可以從EEPROM中讀取具體值,
后半句話是沒問題的,可以通程序式來實作,只要在程式的最前面加一個讀取EEPROM的函式就好了,
問題在前面,題目規定了讀取的初值,可是,怎么才能夠保證你讀取到的數值是“30、50、70”呢?要知道,把程式下載到一塊新板子上,EEPROM中存盤的數值是不確定的,
有小伙伴可能會想,這還不簡單,在程式最前面加一個寫入函式不就好了,把“30、50、70”給提前寫到新板子上,先寫好,再讀取,可是這就會導致,之后每次上電復位,讀取到的都是“30、50、70”,這就與題目要求的“再次上電,讀取到修改值”不符了,
針對這個問題,這里我提供一個程式上的解決方案:
- 代碼的具體思路
要想實作,第一次讀取到的是自己設定的初值,之后讀取到的是修改值,那就需要加一個判斷陳述句,如果判斷為真,就將初始值“30、50、70”寫入到板子上,判斷為假,就不寫入初始值,而且,這個判斷陳述句只需要執行一次, - 具體代碼:
int main()
{
char string[20];
ADC_init();
LED_Init();
SysTickInit();
Buzzer_Init();
i2c_init();
Usart2_init();
key_init();
STM3210B_LCD_Init();
LCD_Clear(Blue);
LCD_SetBackColor(Blue);
LCD_SetTextColor(White);
if(Read_AT24c02(0x06)!=2) //判斷
{
Write_AT24c02(0x01,30); DelayMS(5);
Write_AT24c02(0x02,50); DelayMS(5);
Write_AT24c02(0x03,70); DelayMS(5);
Write_AT24c02(0x06,2); //加了這個陳述句之后,就可以讓這個判斷只執行一次
DelayMS(5);
}
Level[0]=Read_AT24c02(0x01);DelayMS(5);
Level[1]=Read_AT24c02(0x02);DelayMS(5);
Level[2]=Read_AT24c02(0x03);DelayMS(5);
關鍵是判斷條件的確定,我采取的是隨遍讀取一個EEPROM的地址,他只有256分之一的概率等于2,就意味著這段代碼,可以成功的概率是256分之255,當然,如果覺得256分之一還是太大的話,可以這樣寫:
if(Read_AT24c02(0x06)!=2&&Read_AT24c02(0xaa)!=15) //地址和數值都是瞎寫的
{
Write_AT24c02(0x01,30); DelayMS(5);
Write_AT24c02(0x02,50); DelayMS(5);
Write_AT24c02(0x03,70); DelayMS(5);
Write_AT24c02(0x06,2); //加了這個陳述句之后,就可以讓這個判斷只執行一次
DelayMS(5);
Write_AT24c02(0xaa,15);
DelayMS(5);
}
這樣,概率就變成了256的平方分之一,(意義不大,抖個機靈而已)
這些都是我一點點總結的知識點,要是有對您有幫助的話,就給點個贊吧,球球了!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/253546.html
標籤:其他
