找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

帖子
查看: 2936|回復(fù): 11
打印 上一主題 下一主題
收起左側(cè)

請教各位關(guān)于單片機(jī)內(nèi)部存儲的平衡寫入

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:510170 發(fā)表于 2021-7-20 18:03 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
我們在做項目的時候,難免會遇到掉電的問題,一掉電,ram里面的內(nèi)容全部都清空了。一般來說都會附加一個eeprom,好的eeprom可以寫入千萬次的數(shù)據(jù),但是外帶一個是要成本的,且占用接口io,一般的單片機(jī)都帶有eeprom,但很多都是flash改成eeprom的。雖然對外宣傳是eeprom,實際按特性來看就是flash,flash的寫入次數(shù)要遠(yuǎn)低于eeprom,一般是10w左右,我們能否利用flash量大且足的特性,將其充分利用起來,進(jìn)行平衡寫法。將其寫入次數(shù)最大化。以stc8a8k60s4a12單片機(jī)為列,里面有4keeprom,分成8個扇區(qū),每個扇區(qū)有512個字節(jié),我們再將扇區(qū)分成32份,每份有16個字節(jié)的數(shù)據(jù),用來存儲一般的變量應(yīng)該是足夠的,如果不夠,再將其擴(kuò)大就好了。劃成16份,32個字節(jié)每份。這里只是做比方,其中首字節(jié)用來做數(shù)據(jù)引索,填入aa,查找是也只需要按份來讀取aa就可以得出寫入指針在哪里了。下一次寫入的情況下將這次的首位寫為00即可。原理知道了。但是程序應(yīng)該怎么寫呢?由于不是科班出生,都是自學(xué)的。只知道簡單的判斷寫法,有大神能出個方便點的算法嗎?最好能給個程序?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;}
                ......



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復(fù)

使用道具 舉報

沙發(fā)
ID:123289 發(fā)表于 2021-7-22 09:39 | 只看該作者
能力有限,不能理解你所說的【平衡寫入】。
要結(jié)合考慮。寫入次數(shù)被你平衡了。也未必科學(xué)。
1、為了讀寫A,先要索引,如果A放在最末,索引時間就會加長。
2、整個區(qū)內(nèi),有一個單元不良時(假設(shè)其它很好,這個很差寫200次就不行了),你的【平衡寫入】,反而達(dá)不成目的。
3、為了【平衡寫入】,而使用程序復(fù)雜化,且大量占用CPU的時間,未必合算。
回復(fù)

使用道具 舉報

板凳
ID:401564 發(fā)表于 2021-7-22 19:27 | 只看該作者
平衡寫入是個什么東東?沒有聽說過
十萬次的擦寫我都覺得足夠用了
如果一個數(shù)據(jù)是經(jīng)常記錄保存,而且量還很大,那就不是一個單片機(jī)能保存的了,一般都是用外部的EEPROM,容量大的有64M的
而所謂的寫入,目前為止還不知道內(nèi)部是怎么操作的,在沒有驗證之前,不要想當(dāng)然的覺得:每個地址都有十萬次的寫入壽命,這個地址我用得差不多了,在它沒壞之前,換一個地址,它又有十萬次的擦寫壽命了,感覺是這樣而已,目前我還沒有聽說有人驗證過
與其想著這個,還不如考慮一下算法,看一下能不能少用寫入操作
回復(fù)

使用道具 舉報

地板
ID:155507 發(fā)表于 2021-7-22 20:43 | 只看該作者
如果一個數(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ù)不受限制。
回復(fù)

使用道具 舉報

5#
ID:161164 發(fā)表于 2021-7-23 00:07 | 只看該作者
  1. 先建立一個EEPROM地址數(shù)列
  2. u16 code EEP_Addr[]={
  3. 0x0000, 0x0010, 0x0020, ...};
  4. 如你所說,每次寫入時都在索引字節(jié)填入aa
  5. 因為EEPROM原始數(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ù)制代碼


回復(fù)

使用道具 舉報

6#
ID:451718 發(fā)表于 2021-7-23 09:43 | 只看該作者
這個想法很有建設(shè)性,而且很有可行性。最后特別提醒,可不能因為這個原因,就把ROM當(dāng)RAM用。   
回復(fù)

使用道具 舉報

7#
ID:213173 發(fā)表于 2021-7-23 10:37 | 只看該作者
樓主這個想法沒有實際意義。還以stc8a8k60s4a12單片機(jī)為列,讀flash中數(shù)據(jù)沒有壽命限制,擦寫flash次數(shù)有壽命限制。擦除是以扇區(qū)為單位,所以將扇區(qū)劃分若干份使用不會延長使用壽命。如果需要保存的數(shù)據(jù)不太多,可以通過軟件輪流使用8個扇區(qū)以延長使用壽命。其實這些方法基本都是多余的。只要增加簡單硬件就可以實現(xiàn)掉電和關(guān)機(jī)保存eeprom。你這設(shè)備總不至于每天掉電無數(shù)次吧?
回復(fù)

使用道具 舉報

8#
ID:161164 發(fā)表于 2021-7-23 14:57 來自觸屏版 | 只看該作者
wulin 發(fā)表于 2021-7-23 10:37
樓主這個想法沒有實際意義。還以stc8a8k60s4a12單片機(jī)為列,讀flash中數(shù)據(jù)沒有壽命限制,擦寫flash次數(shù)有壽 ...

軟件做到的事,為什要另加硬件?
回復(fù)

使用道具 舉報

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

使用道具 舉報

10#
ID:161164 發(fā)表于 2021-7-23 17:46 | 只看該作者

太可怕了,竟然吞了半個貼子
續(xù)上
每當(dāng)要再寫入數(shù)據(jù)時可用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ī)的時候先讀
  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ù)制代碼




回復(fù)

使用道具 舉報

11#
ID:283954 發(fā)表于 2021-7-23 20:13 | 只看該作者
克服斷電問題還是軟硬兼施來得好,現(xiàn)在的單片機(jī)耗電很小了,用個小的鋰電池,邊用邊充電,斷電后還可以運(yùn)作一兩天,真的沒電了才寫進(jìn)EEPROM,正如 wulin君所言,是整個扇區(qū)刪除重寫,所以扇區(qū)分部使用不會延長使用壽命的,依次使用每個扇區(qū)是能延長整體壽命。
回復(fù)

使用道具 舉報

12#
ID:57657 發(fā)表于 2021-7-24 09:18 | 只看該作者
平衡寫入 就是所謂的 磨損均勻算法,EEPROM的寫扇區(qū)都是有壽命損耗的,寫入、擦除 都需要做效驗。
回復(fù)

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表