久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4105|回復: 31
收起左側

EEPROM掉電存儲功能放MCU程序哪里比較好?

[復制鏈接]
ID:956872 發表于 2021-8-31 16:13 | 顯示全部樓層 |閱讀模式
我現在按鍵控制燈的狀態及亮度,想要存儲狀態變量及PWM變量,EEPROM的擦寫放在程序哪部分比較好?是放在按鍵中斷里面好呢還是放在主程序里面好。還有怎么做延時存儲,比如按鍵完后10S才自動存儲,還不影響主程序的運行。而不是每次按鍵都要是擦寫EEPROM。
回復

使用道具 舉報

ID:161164 發表于 2021-8-31 16:48 | 顯示全部樓層
開機時
Your_Data = IapReadByte(0x2000);//詳細可參考STC_ISP

在while(1)內
if(!Key_In)
{
if(Key_Down_Count>1200000)//時間隨你改
{
IapEraseSector(0x2000);//詳細可參考STC_ISP
IapProgramByte(0x2000, Your_Data);//詳細可參考STC_ISP
}else{
++Key_Down_Count;
}
}else{
Key_Down_Count = 0;
}
回復

使用道具 舉報

ID:887371 發表于 2021-8-31 16:49 | 顯示全部樓層
變化比較頻繁的在斷電瞬間保存。
變化很少的在每次更改時保存。
回復

使用道具 舉報

ID:956872 發表于 2021-8-31 17:04 | 顯示全部樓層
datouyuan 發表于 2021-8-31 16:49
變化比較頻繁的在斷電瞬間保存。
變化很少的在每次更改時保存。

斷電瞬間保存的話,那還得做硬件電路加電容吧。
感覺沒必要,考慮的就是要不更改后就擦寫,要不就操作完后延時擦寫
回復

使用道具 舉報

ID:956872 發表于 2021-8-31 17:20 | 顯示全部樓層
lkc8210 發表于 2021-8-31 16:48
開機時
Your_Data = IapReadByte(0x2000);//詳細可參考STC_ISP

我放在主程序里,這樣只要修改變量參數后要等執行完該分支才進行擦寫,感覺也可以。不知道怎么去判斷EEPROM里的值是否為分支對應的num值。如果IAP_ADDRESS里的值等于num就不再重復擦寫了,只有在不等于的時候才進行擦寫
void main()
{
        init();
        num=IapReadByte(IAP_ADDRESS);
        while(1)
        {
                 
               
                        switch(num)
                        {
                         case(0):lsd0();
                                       P1=0xfe;
                                     
               IapEraseSector(IAP_ADDRESS);             // 擦除扇區
               IapProgramByte(IAP_ADDRESS,0);                               
                                      break;
                         case(1):lsd1();
               P1=0xfd;
               IapEraseSector(IAP_ADDRESS);             // 擦除扇區
               IapProgramByte(IAP_ADDRESS,1);                                       
                                      break;
                         case(2):lsd2();
                                       P1=0xfb;
                                       IapEraseSector(IAP_ADDRESS);             // 擦除扇區
               IapProgramByte(IAP_ADDRESS,2);       
                                       break;//num++;
                         case(3):lsd3();
                                       P1=0xf7;
                                       IapEraseSector(IAP_ADDRESS);             // 擦除扇區
               IapProgramByte(IAP_ADDRESS,3);       
                                        break;
                         
                        }
回復

使用道具 舉報

ID:624769 發表于 2021-8-31 18:35 | 顯示全部樓層
掉電存儲功能,放在掉電中斷里。
掉電檢測點定的高一點,比如,3.7V,  這樣你能用15毫秒左右的時間,儲存東西,足夠了。
回復

使用道具 舉報

ID:956872 發表于 2021-8-31 19:17 | 顯示全部樓層
188610329 發表于 2021-8-31 18:35
掉電存儲功能,放在掉電中斷里。
掉電檢測點定的高一點,比如,3.7V,  這樣你能用15毫秒左右的時間,儲存 ...

這樣純軟件能搞定嗎,是得需要硬件電路支持吧
回復

使用道具 舉報

ID:624769 發表于 2021-8-31 19:41 | 顯示全部樓層
PEB188 發表于 2021-8-31 19:17
這樣純軟件能搞定嗎,是得需要硬件電路支持吧

不需要,我實測過,當外部電容為47uf時,3.7V低壓檢測的情況下,發現掉電后有大約15毫秒處理時間,其中10毫秒左右,是Eeprom安全操作時間,足夠了,你Eeprom 寫一個字節最多7微妙,你可以寫將近1000個字節,時間足夠了,要是還覺得時間不夠,可以適當調大單片機的外部電容,而如果用比較器檢測掉電,大約能比掉電檢測早發現3毫秒,意義不大。

最后,最關鍵一點,掉電檢測中斷一觸發進去后,第一件事情是,先關閉所有的輸出,不然如果你有強推挽輸出點一個LED的話,剩下的電撐不了多久。
回復

使用道具 舉報

ID:161164 發表于 2021-8-31 19:44 來自觸屏版 | 顯示全部樓層
PEB188 發表于 2021-8-31 17:20
我放在主程序里,這樣只要修改變量參數后要等執行完該分支才進行擦寫,感覺也可以。不知道怎么去判斷EEPR ...

正常不會這樣寫的吧?
不知道lsd()里寫的是什么
如果num是0
不就不斷在Case 0擦寫同一地址嗎?
還沒有延時!  EEProm很快壞吧~

先比較再寫入可以這樣
if(!Key_In)
{
if(Key_Down_Count>1200000)//時間隨你改
{Key_Down_Count = 0;
if(num !=IapReadByte(EEProm_Addr))
{
IapEraseSector(EEProm_Addr);//詳細可參考STC_ISP
IapProgramByte(EEProm_Addr, num);//詳細可參考STC_ISP
}
}else{
++Key_Down_Count;
}
}else{
Key_Down_Count = 0;
}
回復

使用道具 舉報

ID:956872 發表于 2021-8-31 19:48 | 顯示全部樓層
188610329 發表于 2021-8-31 19:41
不需要,我實測過,當外部電容為47uf時,3.7V低壓檢測的情況下,發現掉電后有大約15毫秒處理時間,其中10 ...

這個還是需要硬件電容支持啊。我現在這只是改變燈的狀態,這不是頻繁操作的數據,還是純軟件直接擦寫好了
回復

使用道具 舉報

ID:624769 發表于 2021-8-31 19:57 | 顯示全部樓層
PEB188 發表于 2021-8-31 19:48
這個還是需要硬件電容支持啊。我現在這只是改變燈的狀態,這不是頻繁操作的數據,還是純軟件直接擦寫好了

你可別跟我說你搭建單片機電路的時候沒有用47uf電解電容,+ 0.1 uf 濾波電容,就跑起來了哈?這算需要額外硬件支持么?不是標配么?
最后,你的問題是“掉電存儲功能”,那么自然是放到掉電中斷里面羅。
你要是狀態改變后存儲,就放在改變狀態的函數里,或者函數后面。
另外,建議你,Eeprom不要盯著一個地方寫,容易壞,每次移動一個地址寫,寫滿后格式化,再從頭寫。
回復

使用道具 舉報

ID:883242 發表于 2021-8-31 20:07 | 顯示全部樓層
IAP什么的函數是操作flash的吧?不像是操作eeprom的代碼。
回復

使用道具 舉報

ID:624769 發表于 2021-8-31 20:13 | 顯示全部樓層
Hephaestus 發表于 2021-8-31 20:07
IAP什么的函數是操作flash的吧?不像是操作eeprom的代碼。

STC, 就是把 Flash 當 Eeprom 用,對外號稱Eeprom, 所以一擦一個扇區,賊不方便。
回復

使用道具 舉報

ID:956872 發表于 2021-8-31 20:24 | 顯示全部樓層
188610329 發表于 2021-8-31 19:57
你可別跟我說你搭建單片機電路的時候沒有用47uf電解電容,+ 0.1 uf 濾波電容,就跑起來了哈?這算需要額 ...

我就一個STC芯片跑的,啥電容晶振復位電路都沒有,供電用穩壓管。也不會搭建多余的電路,還剛開始學
要是多個變量參數非同時變更的話還是要分頁存儲到EEPROM吧(EPROM有5K,差不多10頁吧),這樣擦除只擦一頁也不會擦掉其它頁的數據,對吧
回復

使用道具 舉報

ID:956872 發表于 2021-8-31 20:25 | 顯示全部樓層
188610329 發表于 2021-8-31 20:13
STC, 就是把 Flash 當 Eeprom 用,對外號稱Eeprom, 所以一擦一個扇區,賊不方便。

不是挺方便的嗎,哪個什么IIC的,學的糊里糊涂,感覺這個簡單就放棄學那個了
回復

使用道具 舉報

ID:624769 發表于 2021-8-31 20:57 | 顯示全部樓層
PEB188 發表于 2021-8-31 20:24
我就一個STC芯片跑的,啥電容晶振復位電路都沒有,供電用穩壓管。也不會搭建多余的電路,還剛開始學[em01 ...

不分頁高地址不變,低地址每次存儲 +1 ,加到255以后 擦除扇區從0開始寫
回復

使用道具 舉報

ID:401564 發表于 2021-8-31 21:00 | 顯示全部樓層
看實際情況,如果條件允許,加硬件電路執行斷電寫入,這樣的話就是關機每次都會保存
不想搞的話,那就按鍵長按或者是多個按鍵按下保存,反正,保存設置是非常規操作就可以了
沒什么好糾結的
回復

使用道具 舉報

ID:624769 發表于 2021-8-31 21:04 | 顯示全部樓層
PEB188 發表于 2021-8-31 20:25
不是挺方便的嗎,哪個什么IIC的,學的糊里糊涂,感覺這個簡單就放棄學那個了

寫碼而言是簡單了,但在架構方面來講,是麻煩。因為實際應用中,不會像你那樣就一個數據盯著一個地方寫,必須考慮均勻使用,寫滿以后,擦除一個扇區需要將近21毫秒,對系統影響還是比較大的。所以經常改的數據,比如鬧鐘數據,我寧可往DS1302,和DS1307里面存,也不往IAP里面存。只有一年都改不了幾次的才存IAP

評分

參與人數 1黑幣 +60 收起 理由
admin + 60 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:956872 發表于 2021-9-1 06:49 | 顯示全部樓層
188610329 發表于 2021-8-31 20:57
不分頁高地址不變,低地址每次存儲 +1 ,加到255以后 擦除扇區從0開始寫

從0開始寫,但我好像寫不進1啊,寫1的話掉電后上電無法保存掉電前的狀態,寫2.3.4都沒問題
回復

使用道具 舉報

ID:398219 發表于 2021-9-1 08:06 | 顯示全部樓層
我常用的方式是計數,一般我是計10次后寫入EEPROM,然后清空計數。掉電還要寫AD檢測電壓,感覺有點麻煩就沒做。
回復

使用道具 舉報

ID:390416 發表于 2021-9-1 08:28 | 顯示全部樓層
簡單  開機時  讀取EEPROM

然后計數 設定時間 比如100ms  

100ms 判斷一次  如果某數據的值 發生了改變 那么執行EEPROM擦除整個扇區+寫入該字節保存
如果數據保持不變 不執行EEPROM擦寫
回復

使用道具 舉報

ID:624769 發表于 2021-9-1 20:18 | 顯示全部樓層
herui2128 發表于 2021-9-1 08:06
我常用的方式是計數,一般我是計10次后寫入EEPROM,然后清空計數。掉電還要寫AD檢測電壓,感覺有點麻煩就沒 ...

掉電壓根不用寫什么檢測電壓,直接 ELVD = 1; 然后寫中斷
void Power_Lost(void)        interrupt  6;
{
    ;//此處存儲Eeprom 代碼
     PCON  &= 0xDF; // 清掉電標志
     delay50ms();    //如 50ms 還沒有關機,說明是誤判,返回主程序。
}
就那么簡單一件事。
回復

使用道具 舉報

ID:956872 發表于 2021-9-2 11:45 | 顯示全部樓層
人人學會單片機 發表于 2021-9-1 08:28
簡單  開機時  讀取EEPROM

然后計數 設定時間 比如100ms  

這樣怎么跟主程序同時運行啊
回復

使用道具 舉報

ID:161164 發表于 2021-9-2 11:59 | 顯示全部樓層
PEB188 發表于 2021-9-2 11:45
這樣怎么跟主程序同時運行啊

不用你那套while循環嵌套法就可以了
while(1){
  while(1){
    while(1){
      while(1){
        if(xxx)break;  ​
     ​}
   ​}
​}
}
回復

使用道具 舉報

ID:956872 發表于 2021-9-2 17:15 | 顯示全部樓層
lkc8210 發表于 2021-8-31 19:44
正常不會這樣寫的吧?
不知道lsd()里寫的是什么
如果num是0

lsd()里就是簡單的流水燈測試,case我從2開始寫,加入了判斷讀取的值與當前值是否一致。不過這樣還有問題,就是在按鍵連續按下調光的時候,這里就有問題了,會連續擦寫,因為擦寫需要較長的時間,對PWM調光也產生干擾了
回復

使用道具 舉報

ID:956872 發表于 2021-9-2 17:24 | 顯示全部樓層
lkc8210 發表于 2021-9-2 11:59
不用你那套while循環嵌套法就可以了
while(1){
  while(1){

我沒這樣寫過。雖然小白一個,但也不至于白成這樣。同時運行程序51單片機好像做不到,那應該是用定時器了,這樣就得長期占用一個定時器。本來定時器就不多
回復

使用道具 舉報

ID:161164 發表于 2021-9-2 17:27 | 顯示全部樓層
PEB188 發表于 2021-9-2 17:15
lsd()里就是簡單的流水燈測試,case我從2開始寫,加入了判斷讀取的值與當前值是否一致。不過這樣還有問題 ...

你不是要按著10秒才去擦寫嗎?
怎么又變成了連續按下會連續擦寫?
回復

使用道具 舉報

ID:956872 發表于 2021-9-2 19:48 | 顯示全部樓層
lkc8210 發表于 2021-9-2 17:27
你不是要按著10秒才去擦寫嗎?
怎么又變成了連續按下會連續擦寫?

之前是執行完分支程序的最后才判斷變量與EEPROM存儲的值是否一致,不一致才去擦寫。后來加了PWM調光就有問題了,按鍵按下變量從一直加到100,相當擦寫一百次,還對PWM產生干擾。主要這款型號定時器才兩個,太少了,現在只能用PCA當定時器,按鍵按下打開PCA定時器,設一個變量計數,每次按鍵按下計數清0,一定時間內沒有按鍵操作了再判斷參數變量,最后決定是否擦寫。這樣應該能解決之前的問題吧
回復

使用道具 舉報

ID:956872 發表于 2021-9-2 21:20 | 顯示全部樓層
188610329 發表于 2021-9-1 20:18
掉電壓根不用寫什么檢測電壓,直接 ELVD = 1; 然后寫中斷
void Power_Lost(void)        interrupt  6;
...

這樣是每次進入掉電模式前保存一次數據嗎。那要是剛修改了數據,斷電一次不就沒來得及保存了。還要電路上加大的電容跟電壓檢測判斷吧
回復

使用道具 舉報

ID:161164 發表于 2021-9-2 22:26 | 顯示全部樓層
PEB188 發表于 2021-9-2 17:24
我沒這樣寫過。雖然小白一個,但也不至于白成這樣。同時運行程序51單片機好像做不到,那應該是用定 ...

這不是你寫的嗎? 2021-09-02_222102.png
2021-09-02_222050.png


其實只用一個定時器
分時工作
已經等同于同時運行了
因為人跟本分不出幾毫秒的差別

回復

使用道具 舉報

ID:161164 發表于 2021-9-2 22:40 | 顯示全部樓層
PEB188 發表于 2021-9-2 19:48
之前是執行完分支程序的最后才判斷變量與EEPROM存儲的值是否一致,不一致才去擦寫。后來加了PWM調光就有 ...

那是你的寫法有基本上的問題
所以每加一個新功能時就會與舊邏輯有沖突
然后又用一些另辟蹊徑的邏輯來解決
結果越寫越亂

12T的單片機只用一個定時器已足夠協調五個工作模塊+一個慢速PWM
回復

使用道具 舉報

ID:624769 發表于 2021-9-3 22:08 | 顯示全部樓層
PEB188 發表于 2021-9-2 21:20
這樣是每次進入掉電模式前保存一次數據嗎。那要是剛修改了數據,斷電一次不就沒來得及保存了。還要電路上 ...

你還是看一下手冊吧……
interrupt 6 不是什么掉電模式, 是給單片機斷電了,單片機在發現你掐了電源,簡單點說,打比方說:發現你給他拔管子后,他在短期前利用還剩下的最后一口氣,寫下死亡訊息。 噢不是,把變量存Eeprom。
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一区二区三区在线 | 欧美日韩国产不卡 | 91精品91久久久| 成人免费视频 | 日本精品在线一区 | 精品视频在线观看 | 国产午夜精品久久 | 国产精品美女在线观看 | 欧美日韩视频在线第一区 | 成人免费视频网站在线观看 | 日韩在线中文 | 国产aaaaav久久久一区二区 | 一区二区三区在线免费观看 | 日本啊v在线 | www.五月婷婷.com | 久久久九九| 国产精品a久久久久 | 久久精品久久久久久 | 亚洲国产成人精品女人久久久 | 成人黄色电影在线观看 | 亚洲一区二区三区在线播放 | 日日做夜夜爽毛片麻豆 | 成人性生交a做片 | 日本精品一区二区三区视频 | 日韩综合在线 | 欧美视频一级 | 天天操,夜夜爽 | 最新91在线 | 中文字幕在线一区 | 交专区videossex农村 | 中文字幕免费视频 | 日本不卡一区二区三区在线观看 | 华丽的挑战在线观看 | 91精品国产色综合久久 | 欧美三级成人理伦 | 国产一区免费 | jizz中国日本 | 96av麻豆蜜桃一区二区 | 亚洲精品一区二区三区中文字幕 | 亚洲精品免费在线观看 | 精品一区二区三区中文字幕 |