標(biāo)題: 請教各位關(guān)于單片機(jī)內(nèi)部存儲的平衡寫入 [打印本頁]

作者: ttmax3    時(shí)間: 2021-7-20 18:03
標(biāo)題: 請教各位關(guān)于單片機(jī)內(nèi)部存儲的平衡寫入
我們在做項(xiàng)目的時(shí)候,難免會遇到掉電的問題,一掉電,ram里面的內(nèi)容全部都清空了。一般來說都會附加一個(gè)eeprom,好的eeprom可以寫入千萬次的數(shù)據(jù),但是外帶一個(gè)是要成本的,且占用接口io,一般的單片機(jī)都帶有eeprom,但很多都是flash改成eeprom的。雖然對外宣傳是eeprom,實(shí)際按特性來看就是flash,flash的寫入次數(shù)要遠(yuǎn)低于eeprom,一般是10w左右,我們能否利用flash量大且足的特性,將其充分利用起來,進(jìn)行平衡寫法。將其寫入次數(shù)最大化。以stc8a8k60s4a12單片機(jī)為列,里面有4keeprom,分成8個(gè)扇區(qū),每個(gè)扇區(qū)有512個(gè)字節(jié),我們再將扇區(qū)分成32份,每份有16個(gè)字節(jié)的數(shù)據(jù),用來存儲一般的變量應(yīng)該是足夠的,如果不夠,再將其擴(kuò)大就好了。劃成16份,32個(gè)字節(jié)每份。這里只是做比方,其中首字節(jié)用來做數(shù)據(jù)引索,填入aa,查找是也只需要按份來讀取aa就可以得出寫入指針在哪里了。下一次寫入的情況下將這次的首位寫為00即可。原理知道了。但是程序應(yīng)該怎么寫呢?由于不是科班出生,都是自學(xué)的。只知道簡單的判斷寫法,有大神能出個(gè)方便點(diǎn)的算法嗎?最好能給個(gè)程序?qū)嵙。我目前的寫法是這樣的。
                if(IapRead(0x0000)=0xaa){xrzz=0;}
                if(IapRead(0x0010)=0xaa){xrzz=1;}
                if(IapRead(0x0020)=0xaa){xrzz=2;}
                if(IapRead(0x0030)=0xaa){xrzz=3;}
                ......




作者: yzwzfyz    時(shí)間: 2021-7-22 09:39
能力有限,不能理解你所說的【平衡寫入】。
要結(jié)合考慮。寫入次數(shù)被你平衡了。也未必科學(xué)。
1、為了讀寫A,先要索引,如果A放在最末,索引時(shí)間就會加長。
2、整個(gè)區(qū)內(nèi),有一個(gè)單元不良時(shí)(假設(shè)其它很好,這個(gè)很差寫200次就不行了),你的【平衡寫入】,反而達(dá)不成目的。
3、為了【平衡寫入】,而使用程序復(fù)雜化,且大量占用CPU的時(shí)間,未必合算。
作者: Y_G_G    時(shí)間: 2021-7-22 19:27
平衡寫入是個(gè)什么東東?沒有聽說過
十萬次的擦寫我都覺得足夠用了
如果一個(gè)數(shù)據(jù)是經(jīng)常記錄保存,而且量還很大,那就不是一個(gè)單片機(jī)能保存的了,一般都是用外部的EEPROM,容量大的有64M的
而所謂的寫入,目前為止還不知道內(nèi)部是怎么操作的,在沒有驗(yàn)證之前,不要想當(dāng)然的覺得:每個(gè)地址都有十萬次的寫入壽命,這個(gè)地址我用得差不多了,在它沒壞之前,換一個(gè)地址,它又有十萬次的擦寫壽命了,感覺是這樣而已,目前我還沒有聽說有人驗(yàn)證過
與其想著這個(gè),還不如考慮一下算法,看一下能不能少用寫入操作
作者: angmall    時(shí)間: 2021-7-22 20:43
如果一個(gè)數(shù)據(jù)是經(jīng)常記錄保存,而且量還很大, 你可以用
NVRAM( Non-Volatile Random Access Memory) 是非易失性隨機(jī)訪問存儲器,即斷電之后,所存儲的數(shù)據(jù)不丟失的隨機(jī)訪問存儲器。

NVRAM 指斷電后仍能保持?jǐn)?shù)據(jù)的一種RAM。一般都是用電池,可以持續(xù)10年。

NVRAM 能夠保護(hù)數(shù)據(jù)(即便在掉電情況下),支持高速RAM寫操作,擦寫次數(shù)不受限制。

作者: lkc8210    時(shí)間: 2021-7-23 00:07
  1. 先建立一個(gè)EEPROM地址數(shù)列
  2. u16 code EEP_Addr[]={
  3. 0x0000, 0x0010, 0x0020, ...};
  4. 如你所說,每次寫入時(shí)都在索引字節(jié)填入aa
  5. 因?yàn)镋EPROM原始數(shù)值為0xFF
  6. 那么經(jīng)過幾次寫入后可得出以下列表
  7. (首地址)(字節(jié)0)(字節(jié)1)(字節(jié)2)...
  8. 0x0000   0xaa    0xXX    0xXX
  9. 0x0010   0xaa    0xXX    0xXX
  10. 0x0020   0xff     0xff      0xff
  11. ...
復(fù)制代碼



作者: robinsonlin    時(shí)間: 2021-7-23 09:43
這個(gè)想法很有建設(shè)性,而且很有可行性。最后特別提醒,可不能因?yàn)檫@個(gè)原因,就把ROM當(dāng)RAM用。   
作者: wulin    時(shí)間: 2021-7-23 10:37
樓主這個(gè)想法沒有實(shí)際意義。還以stc8a8k60s4a12單片機(jī)為列,讀flash中數(shù)據(jù)沒有壽命限制,擦寫flash次數(shù)有壽命限制。擦除是以扇區(qū)為單位,所以將扇區(qū)劃分若干份使用不會延長使用壽命。如果需要保存的數(shù)據(jù)不太多,可以通過軟件輪流使用8個(gè)扇區(qū)以延長使用壽命。其實(shí)這些方法基本都是多余的。只要增加簡單硬件就可以實(shí)現(xiàn)掉電和關(guān)機(jī)保存eeprom。你這設(shè)備總不至于每天掉電無數(shù)次吧?
作者: lkc8210    時(shí)間: 2021-7-23 14:57
wulin 發(fā)表于 2021-7-23 10:37
樓主這個(gè)想法沒有實(shí)際意義。還以stc8a8k60s4a12單片機(jī)為列,讀flash中數(shù)據(jù)沒有壽命限制,擦寫flash次數(shù)有壽 ...

軟件做到的事,為什要另加硬件?
作者: univers    時(shí)間: 2021-7-23 16:28
樓主所想說的平衡寫入,我理解應(yīng)該是這樣的吧,將扇區(qū)分成32份,每份有16個(gè)字節(jié)的數(shù)據(jù),寫入和擦除是從1到16輪流寫的,也就是排隊(duì)寫入數(shù)據(jù),第一次寫1區(qū),第二次寫2區(qū),第三次寫3區(qū),以此類推從頭到尾循環(huán)。如果停電了就以最后寫入的那個(gè)參數(shù)把她讀出來。
我認(rèn)為這樣利用也是很有創(chuàng)意的,就單單EEPROM使用壽命來說是16倍。其它這個(gè)寫數(shù)據(jù)也很簡單了,按上面的邏輯來,寫一個(gè)流水寫循環(huán)就可以了,讀的話,可以讀一個(gè)最后的標(biāo)志位即可。
作者: lkc8210    時(shí)間: 2021-7-23 17:46
lkc8210 發(fā)表于 2021-7-23 00:07

太可怕了,竟然吞了半個(gè)貼子
續(xù)上
每當(dāng)要再寫入數(shù)據(jù)時(shí)可用For循環(huán)找出未被寫入的地址
  1. for(i=0;i<32;i++){
  2. HeadAddr = EEP_Addr[i];
  3. if(IapRead(HeadAddr) == 0xFF){
  4. break;
  5. }
  6. }
  7. if(i<32){
  8. iapProgram(HeadAddr,0xaa);
  9. iapProgram(HeadAddr + 1,Data1);
  10. iapProgram(HeadAddr + 2,Data2);
  11. iapProgram(HeadAddr + 3,Data3);
  12. 下略
  13. }else{
  14. //i >= 32代表所有地址已被寫滿,需先擦除一次再寫入
  15. }
  16. 開機(jī)的時(shí)候先讀
  17. for(i=0;i<32;i++){
  18. HeadAddr = EEP_Addr[i];
  19. if(IapRead(HeadAddr) != 0xaa){
  20. break;
  21. }
  22. }
  23. if(i>0){
  24. Data1 = IapRead(HeadAddr + 1);
  25. Data2 = IapRead(HeadAddr + 2);
  26. Data3 = IapRead(HeadAddr + 3);
  27. 下略
  28. }else{
  29. //i = 0 代表沒有寫入過
  30. }
復(fù)制代碼





作者: dalaoshi    時(shí)間: 2021-7-23 20:13
克服斷電問題還是軟硬兼施來得好,現(xiàn)在的單片機(jī)耗電很小了,用個(gè)小的鋰電池,邊用邊充電,斷電后還可以運(yùn)作一兩天,真的沒電了才寫進(jìn)EEPROM,正如 wulin君所言,是整個(gè)扇區(qū)刪除重寫,所以扇區(qū)分部使用不會延長使用壽命的,依次使用每個(gè)扇區(qū)是能延長整體壽命。
作者: npn    時(shí)間: 2021-7-24 09:18
平衡寫入 就是所謂的 磨損均勻算法,EEPROM的寫扇區(qū)都是有壽命損耗的,寫入、擦除 都需要做效驗(yàn)。




歡迎光臨 (http://www.torrancerestoration.com/bbs/) Powered by Discuz! X3.1