1. 程式人生 > >EEPROM讀寫及資料管理

EEPROM讀寫及資料管理

http://bbs.elecfans.com/jishu_452559_1_1.html

有關E2PROM操作、保護、失效等一些問題,(才疏學淺,路過的英雄記得補刀1)有關 晶片內部自帶的E2PROM
有的資深的工程師可能不是很願意用MCU自帶的E2PROM,大概是這些傢伙上過什麼當、受過騙還是什麼的。簡單說一下優缺點吧:
(1)片內整合的感覺挺便宜的,和MCU一起賣的,對成本要求嚴格的,寫次數很少的場合一般會考慮,至少能省個2、3毛錢吧;(2)缺點的話,可能擦寫次數、穩定性沒有外掛的專用晶片厲害;
2)有關常用的外掛E2PROM
如果是學生或者剛從學生時代走來的人們,大概也就知道ATMEL 24C0X系列吧,就好像我畢業的時候以為世界只有51和AVR,開個玩笑!工程師主要考察E2PROM的引數無非就是擦寫次數、功耗、穩定性、價格,其中10萬次擦寫次數和 100萬次擦寫次數正在較量,至於從工程師的角度考慮 擦寫次數自然是沒有上限最好,太低的擦寫次數會讓程式設計師死很多腦細胞。3)
有關E2PROM的資料管理
(1)操作注意事項:分頁操作需要有5ms延遲等待時間才可以(以類AT24C04的產品為例),也就是模組化程式設計中,在寫資料之前、寫資料完畢後、度資料之前、讀資料之後都需要考慮加5ms的延時時間。本來IIC的讀寫速率就不是很高,外加這些延遲一定會勢必影響系統設計的實時性,但也不得不從讀寫效能的角度出發。

(2)上拉電阻的選擇:出於穩定性考慮,WP、SDA、SCL引腳都會設定上拉電阻,常用的電阻值為 4.7K 、10K電阻,個人比較推薦4.7K。
(3)硬體IIC與軟體模擬IIC的比較:對MCU資源不是很敏感的應用,都會考慮軟體模擬的方式,畢竟這個移植起來真的很方便,只有第一做軟體部分的時序、保護性設計作為足夠好,後面拿過來修改時鐘就可以直接,確實方便。
(4)預設引數的寫入
:設定新E2PROM的時間戳標誌,每次系統啟動時檢查這個時間戳和MCU自身儲存的時間戳是否一致,不一致則初始化整個E2PROM為預設引數;當然軟體程式的升級,這個時間戳表示也有必要做更改。
(5)資料容錯和管理:把資料以有意義的資料塊作分類管理,在資料的塊的頭、位加固定標識和CS/CRC校驗 模式,格式如
  資料塊開始字  資料長度資料校驗結束
0xA5LengthByte0---ByteNCS/CRC0x5A

實際用於產品中,可以挑選這個格式內容裡面的部分內容使用,比如去掉結束符等。個人之所以建立寫入開始字、結束字,原因是方便最好讀出來的資料做資料格式檢查,確認寫入、讀出的資料可靠性最高。   為增強實際的可靠性,在需要寫入的時候,可以在寫入後,再讀出來進行資料的比對,確認寫入是否正確;或者在需要讀出的時候,讀兩次、或者多次,檢查每次的資料是否一致。   對於出現異常的資料,最好有容錯機制,可以回到預設狀態值,不至於系統此時因為某個引數改變的崩潰。
(6)實際底層操作是否需要關閉主程式的中斷
:一般按照上述(5)操作,有多次冗餘操作設計,可以不關閉主程式中斷。而且,IIC為等待型操作,一般不會因為系統延遲導致時鐘脈寬拉長,影響位元組寫入、讀出。
(7)E2PROM擦寫次數的延長: 如果現在手上的E2PROM的擦鞋次數是10萬次,專案要求為100萬次,且E2PROM內有很多空閒位元組的沒有使用。
可以這樣操作,將資料整理好,以資料塊的方式儲存,一組資料分10個塊地址儲存,每次寫完後轉移到下一塊寫,即10次寫操作中每個物理的資料儲存地址只操作了1次。 注意此時的寫塊資料的指標不能單獨存、操作,不然這個位元組的操作頻率高,也就受到10萬次的限制,這個關鍵的鏈子在10萬次的時候掉了,其他位元組也就掛了。這個表徵操作哪個塊的指標或者說標示符,當然也需要是移動的,至於具體怎麼實現,就是見仁見智的事了。轉自:http://blog.chinaunix.net/uid-20589269-id-1622153.html

最近用Mega16做一個步進電機的專案,以後把專案全部的內容貼上來跟大家分享呵呵,現在討論一個防止EEPROM讀寫出錯的小辦法,我編寫熔絲位是用AVRstudio裡面的Jtag下載功能來燒熔絲位的,連上Jtag,AVRstudio的Jtag功能fuse選項裡,把熔絲位中的Preserve EEPROM memory through the Chip Erase cycle鉤上,Brown-out detection level at VCC=4.0V鉤上,Brown-out detection enabled鉤上,就可以解決讀寫EEPROM時出錯的機會了。

      如果再加上用直接地址訪問法,而不用變數定義法,會更好的避免EEPROM讀寫問題,例如我就定義了
//定義eeprom變數的地址
#define eeprom_step_num 0xA0
#define eeprom_step_r_max 0xB0
#define eeprom_step_l_max 0xC0
然後程式就沒有再跑飛了!^_^

      在其它論壇上還有一些討論EEPROM讀寫錯誤的貼,我節選了一些,留作參考:

EEPROM掉電丟資料這個特點可不是AVR獨有的。很多年前在89C51+24C02的系統裡面就遇到過,我不知道鐵電有什麼比24C02更牛的地方,居然能保證不丟資料。原因很簡單,就是掉電過程中,電壓降低到MCU無法正常工作的程度,程式跑飛了,微控制器引腳狀態完全不可控,某次掉電就可能發出錯誤的寫24C02的指令。上電的時候因為RESET處於有效狀態,MCU引腳狀態完全確定(對於51來說就是全1),是不可能誤操作24C02的。解決方案很簡單,加一片MAX813L,當電壓低於4.6V就鎖定89C51,問題徹底解決。這麼多年也沒見24C02被誤改寫。 

最早的一批AVR內建了EEPROM卻沒有BOD,所以EEPROM被誤改寫是家常便飯,ATMEL很快發現了這個問題,新推出的AVR全都含有BOD樂。AVR的情況比較複雜,振盪方式和復位方式都有多種,所以不僅掉電會改寫EEPROM(原因同上),上電也會!RESET過程結束前,必須有若干XTAL,MCU內部暫存器(包括軟體不可見的)才會清零,如果RESET結束了才來時鐘,上電就是程式亂飛,同樣有可能改寫EEPROM。用RC振盪方式問題不大,有電就能振起來,用石英晶體就會出問題,我測過89C51的,上電後20ms才振起來,如果電源上有大的濾波電容,VCC的上升斜率變小,晶體起振時間會變得更長!有儲存示波器的朋友可以自己測一下,對晶振的起振有個感性認識。

我遇到過的問題,m8裡面有寫eeprom的程式段,資料已經寫入到eeprom了。 
不停的開關電,eeprom裡的值有可能隨機改變,不見得是0x00,0xFF 
原因是不是上電時,程式指標跑飛到寫eeprom那段,導致往eeprom隨機地址寫了隨機數。 
後來,採用isp下載2次程式,最後版本的程式是刪除了寫eeprom程式段,保留讀eeprom段。 
這樣的話,開關電很多次,裡面的eeprom沒見有改動。 
如果系統實際執行時,需要對eeprom寫操作,可考慮存多幾次資料,用校驗方法來處理資料改變。

偶的應用一般要用到EEPROM儲存的資料比較少,一般採取反碼冗餘備份校驗的方式,需要儲存的資料按照原碼和反碼存兩份,需要讀取時分別讀取原碼和反碼,進行校驗,若校驗不通過,則根據一定的演算法恢復資料或者採取預設值.

我遇到過的問題,m8裡面有寫eeprom的程式段,資料已經寫入到eeprom了。 
不停的開關電,eeprom裡的值有可能隨機改變,不見得是0x00,0xFF   

我也是一樣BOD使能   就OK了 不過我還是不放心,我用兩份資料,最後加校驗,啟動的時候讀eeprom資料   如果有異常 檢測出錯誤資料組,然後用正確的恢復。如果兩組資料均遭毒手,用flash裡面的預設資料覆蓋。

一般我在eeprom裡間三分拷貝,位置隔的比較遠

以下是馬潮老師的解決辦法:

作為一個正式的系統或產品,當系統基本功能除錯完成後,一旦進行現場測試階段,請注意馬上改寫熔絲位的配置,啟用AVR的電源檢測(BOD)功能。 

對於5V系統,設定BOD電平為4.0V;對於3V系統,設定BOD電平為2.7V。然後允許BOD檢測。 

這樣,一旦AVR的供電電壓低於BOD電平,AVR進入RESET(不執行程式了)。而當電源恢復到BOD電平以上,AVR才正式開始從頭執行程式。保證了系統的可靠性! 

原因分析如下: 
AVR是寬電壓工作的晶片,當電壓跌至2.5V,系統程式還能工作。這是有2個可怕的現象可能出現, 
1。外圍晶片工作已經混亂,AVR讀到的東西不正確,造成程式的執行發生邏輯錯誤(不是AVR本身的原因)。 
2。當電源低到臨界點,如2.4V時,並且在此互上互下的,AVR本身的程式執行也不正常,取指令、讀資料都可能發生錯誤,或程式亂飛、不穩定(AVR本身的原因,實際任何的微控制器都是這樣的),非常容易造成EEPROM、FALSH的破壞。有人問51怎麼不會?實際上51也是這樣,只是51內部沒有直接寫EEPROM、FLASH的指令,它的程式亂飛留不下痕跡。還有人有疑問:外掛EEPROM,掉電時怎麼不會改寫?實際是外掛EEPROM,當電壓低於4V(2.7V)時,它已經不工作了,程式去改內容也改不了。而AVR內部的東西在臨界電壓時都能工作,但非常不穩定。 

AVR的BOD功能必須要使用,我早期使用51時,凡是產品外部都要使用電源監測晶片,現在AVR自己本身就有該功能,一定要使用。