avr EEPROM 數(shù)據(jù)丟失問(wèn)題 原因與解決方案
1.程序問(wèn)題;
2.程序跑飛;
3.EEPROM相關(guān)寄存器因強(qiáng)磁場(chǎng)、高壓靜電等外部干擾出錯(cuò)所產(chǎn)生的寫(xiě)入動(dòng)作;
4.系統(tǒng)有很大的感性負(fù)載,在斷電的時(shí)候會(huì)產(chǎn)生一個(gè)反向高壓,EEPROM有可能會(huì)自擦除。
……(還有什么原因,歡迎大家繼續(xù)列舉,以便完善及想辦法解決)
針對(duì)問(wèn)題1,程序問(wèn)題不再該文討論范圍內(nèi)。
針對(duì)問(wèn)題2,程序跑飛,這個(gè)因該是引起EEPROM數(shù)據(jù)丟失的主要原因。但是引起程序跑飛的原因卻是多方面的。
第一.電壓不正常,工作不穩(wěn)定,程序跑飛。針對(duì)這個(gè)問(wèn)題,可以開(kāi)啟內(nèi)部BOD、或者外加復(fù)位芯片解決,在低功耗場(chǎng)合,外部復(fù)位是有必
要的,畢竟BOD功耗太高。
第二,晶體振蕩受干擾,頻率不穩(wěn)定,程序跑飛。針對(duì)這個(gè)問(wèn)題,建議晶體使用全幅振蕩,并且走線的時(shí)候盡量短,并且使用地線隔離。
第三系統(tǒng)受外界環(huán)境干擾,修改了PC等寄存器,程序跑飛。針對(duì)這個(gè)干擾問(wèn)題,這個(gè)引起程序跑飛的可能性應(yīng)該不大,如果環(huán)境實(shí)在惡劣
,那么就應(yīng)該想到做電磁屏蔽,ESD保護(hù)等,如果還不行,那么只能建議換換別的單片機(jī)試試看了。
針對(duì)問(wèn)題3,我們只能優(yōu)化電路設(shè)置,盡量避免,比如加屏蔽罩,加ESD保護(hù),加TVS保護(hù),電源加電容退耦等等。
針對(duì)問(wèn)題4,如果系統(tǒng)真的具有很大的感性負(fù)載,那么請(qǐng)注意加續(xù)流二極管、濾波電容等做保護(hù),不要讓這種反向高壓產(chǎn)生,無(wú)論如何,這
種因?yàn)楦行载?fù)載突然斷電自激產(chǎn)生的高壓,不僅僅會(huì)對(duì)EEPROM有影響,而是對(duì)整個(gè)系統(tǒng)都存在威脅。
==============================================================================================================
經(jīng)過(guò)上面硬件上的一些處理,雖然EEPROM數(shù)據(jù)丟
失的可能已經(jīng)很小了,但是我們?nèi)匀徊荒鼙WCEEPROM數(shù)據(jù)就不會(huì)丟失了。這時(shí)EEPROM數(shù)據(jù)的可*性,那就得從軟件上去考慮了,接著我們從
軟件的方面繼續(xù)討論。
我的做法是,數(shù)據(jù)分塊,分區(qū),校驗(yàn),備份。當(dāng)然這里講的處理方法,僅僅是提供一種想法,你可以做不同數(shù)據(jù)長(zhǎng)度的分塊,不同大小的
分區(qū),采用不同的地址映射方法,以及采用更多次的數(shù)據(jù)備份。下面以Mega168為例繼續(xù)討論。
1.Mega168EEPROM512字節(jié),把EEPROM分為兩個(gè)區(qū),每個(gè)區(qū)256個(gè)字節(jié),然后以8個(gè)字節(jié)為一個(gè)段,那么每個(gè)區(qū)就有32段。
數(shù)據(jù)區(qū):0x000-0x0FF
0段:0x000-0x007
1段:0x008-0x00F
……
31段:0x0F8-0x0FF
備份區(qū):0x100-0x1FF
每個(gè)段8個(gè)字節(jié),其中前6個(gè)字節(jié)為有效數(shù)據(jù),后2個(gè)字節(jié)為CRC16校驗(yàn),數(shù)據(jù)格式下圖所示:
2.EEPROM讀寫(xiě)操作
EEPROM的操作以段為單位,
段寫(xiě)入函數(shù):寫(xiě)數(shù)據(jù)到數(shù)據(jù)區(qū)時(shí),先計(jì)算數(shù)據(jù)CRC16校驗(yàn),然后同時(shí)把數(shù)據(jù)寫(xiě)入到數(shù)據(jù)區(qū)和備份區(qū);
段讀取函數(shù):讀取數(shù)據(jù)時(shí),同時(shí)讀取數(shù)據(jù)區(qū)以及備份區(qū),如果數(shù)據(jù)區(qū)校驗(yàn)有誤,備份區(qū)數(shù)據(jù)校驗(yàn)正確,就用備份區(qū)數(shù)據(jù)恢復(fù)數(shù)據(jù)區(qū)數(shù)據(jù);
如果備份區(qū)數(shù)據(jù)有誤,數(shù)據(jù)區(qū)數(shù)據(jù)正確,那么數(shù)據(jù)寫(xiě)入備份區(qū)重新備份;如果數(shù)據(jù)區(qū)備份區(qū)數(shù)據(jù)都有誤,那么返回讀取失敗。
3.數(shù)據(jù)區(qū)與備份區(qū)的對(duì)應(yīng)關(guān)系
數(shù)據(jù)讀寫(xiě)操作以段進(jìn)行,內(nèi)部的數(shù)據(jù)區(qū)與備份區(qū)怎么映射呢?為了防治數(shù)據(jù)與備份同時(shí)被意外修改,那么數(shù)據(jù)與備份地址空間相隔不能太
近,并且數(shù)據(jù)與備份的地址,應(yīng)該盡量不同。假設(shè)數(shù)據(jù)地址為Data_Addr,備份地址為Bakup_Addr,我使用下面的函數(shù)映射地址:
Bakup_Addr=(Data_Addr+0x100)^0x03F
加0x100是把地址定義到備份區(qū),與0x03F異或,是把低6bits取反,這樣處理,數(shù)據(jù)與備份的地址空間較遠(yuǎn),并且地址有7bits的不同。
例如,第3段的地址:0x018-0x01F,
對(duì)應(yīng)的備份區(qū)為:0x127-0x120
如下圖所示:
4.讀寫(xiě)函數(shù)加入寫(xiě)保護(hù)判斷,在讀寫(xiě)EEPROM前關(guān)閉寫(xiě)保護(hù),讀寫(xiě)完畢后,立即開(kāi)啟寫(xiě)保護(hù),這樣可以有效防止程序跑飛造成的EEPROM意外修改
。
5.第0塊建議禁止使用。
評(píng)論