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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4715|回復(fù): 21
打印 上一主題 下一主題
收起左側(cè)

stc8g1k08a單片機(jī)掉電存儲問題

  [復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
感覺程序沒有問題但是掉電之后不能重新讀取上次保存到eeprom 不知道是沒有保存到內(nèi)部還是讀取不行

//STC8G1K08A工作電壓范圍1.9~5.5V
//測試工作頻率為11.0592MHz
//S_ADC基準(zhǔn)值由調(diào)試后確定
//此程序?yàn)榛A(chǔ)構(gòu)架,需經(jīng)調(diào)試完善
//#include "reg51.h"
#include "STC8.H"
#include "intrins.h"
#define ADCTIM  (*(unsigned char volatile xdata *)0xfea8)
#define WT_12M   0x83
typedef unsigned char uchar;
typedef unsigned int uint;
//端口定義
sbit LED=P3^2;
sbit OUT=P3^3;
sbit ADC=P5^4;
sbit KEY=P5^5;
//全局變量
uchar S_ADC,M_ADC;                                                                //ADC采樣值
/*----------------------------
        初始化定時器
----------------------------*/
void Timer0Init()                                                                //2毫秒@11.0592MHz
{
        AUXR |= 0x80;                                                                //定時器時鐘1T模式
        TMOD &= 0xF0;                                                                //設(shè)置定時器自動重裝模式
        TL0 = 0x9A;                                                                        //設(shè)置定時初值
        TH0 = 0xA9;                                                                        //設(shè)置定時初值
        TF0 = 0;                                                                        //清除TF0標(biāo)志
        TR0 = 1;                                                                        //定時器0開始計(jì)時
}
/*----------------------------
        讀取ADC結(jié)果
----------------------------*/
uchar GetADCResult()
{        //ADC 控制器  電源  啟動  完成  --   15通道模擬選擇位
        //ADC_CONTR    B7    B6    B5   B4   B3   B2   B1   B0
        ADC_CONTR|= 0x44;                                       //啟動AD轉(zhuǎn)換,P5.4 ADC輸入
        _nop_();_nop_();                                                //延時2個時鐘
        while (!(ADC_CONTR & 0x20));                //查詢ADC完成標(biāo)志
        ADC_CONTR &= ~0x20;                                                //清完成標(biāo)志
        return ADC_RES;                                 //返回8位ADC結(jié)果
}

void IapIdle()
{
    IAP_CONTR = 0;                     //關(guān)閉IAP功能
    IAP_CMD = 0;                       //清除命令寄存器
    IAP_TRIG = 0;                      //清除觸發(fā)寄存器
    IAP_ADDRH = 0x80;                  //將地址設(shè)置到非IAP區(qū)域
    IAP_ADDRL = 0;
}

char IapRead(int addr)
{
    char dat;

    IAP_CONTR = WT_12M;                //使能IAP
    IAP_CMD = 1;                       //設(shè)置IAP讀命令
    IAP_ADDRL = addr;                  //設(shè)置IAP低地址
    IAP_ADDRH = addr >> 8;             //設(shè)置IAP高地址
    IAP_TRIG = 0x5a;                   //寫觸發(fā)命令(0x5a)
    IAP_TRIG = 0xa5;                   //寫觸發(fā)命令(0xa5)
    _nop_();
    dat = IAP_DATA;                    //讀IAP數(shù)據(jù)
    IapIdle();                         //關(guān)閉IAP功能

    return dat;
}

void IapProgram(int addr, char dat)
{
    IAP_CONTR = WT_12M;                //使能IAP
    IAP_CMD = 2;                       //設(shè)置IAP寫命令
    IAP_ADDRL = addr;                  //設(shè)置IAP低地址
    IAP_ADDRH = addr >> 8;             //設(shè)置IAP高地址
    IAP_DATA = dat;                    //寫IAP數(shù)據(jù)
    IAP_TRIG = 0x5a;                   //寫觸發(fā)命令(0x5a)
    IAP_TRIG = 0xa5;                   //寫觸發(fā)命令(0xa5)
    _nop_();
    IapIdle();                         //關(guān)閉IAP功能
}

void IapErase(int addr)
{
    IAP_CONTR = WT_12M;                //使能IAP
    IAP_CMD = 3;                       //設(shè)置IAP擦除命令
    IAP_ADDRL = addr;                  //設(shè)置IAP低地址
    IAP_ADDRH = addr >> 8;             //設(shè)置IAP高地址
    IAP_TRIG = 0x5a;                   //寫觸發(fā)命令(0x5a)
    IAP_TRIG = 0xa5;                   //寫觸發(fā)命令(0xa5)
    _nop_();                           //
    IapIdle();                         //關(guān)閉IAP功能
}

void keys_can()                                                                //按鍵掃描
{
        static uint count=0;                                        //長按計(jì)數(shù)變量
        static bit sign=0;                                                //狀態(tài)標(biāo)志
        if(!KEY)                                                                   //按鍵按下
        {  
                if(++count>=500)                                        //長按計(jì)數(shù)1s
                {
                        sign=1;                                                        //狀態(tài)標(biāo)志置1
                        S_ADC=GetADCResult();                        //讀取ADC
                        IapErase(0x0000);                                //擦除第0扇區(qū)
                        IapProgram(0x0000,S_ADC);                //寫入數(shù)據(jù)
                        LED=0;                                                        //保存成功指示
                }
        }  
        else                                                                        //按鍵抬起
        {  
                if(sign)                                                        //判斷狀態(tài)標(biāo)志
                {
                        LED=1;                                                        //指示燈復(fù)位
                        sign=0;                                                        //狀態(tài)標(biāo)志清0
                }
                count=0;                                                        //長按計(jì)數(shù)變量清0
        }   
}

void main()
{
//配置端口模式寄存器
        P3M0 = 0x00;                                                        //設(shè)置P3準(zhǔn)雙向口
        P3M1 = 0x00;                                                        //設(shè)置P3準(zhǔn)雙向口
        P5M0 = 0x00;                                                        //設(shè)置P5.4為ADC口
        P5M1 = 0x10;                                                        //設(shè)置P5.4為ADC口
        OUT  = 0;                                                                //輸出口低電平
//配置ADC寄存器 --  -- 格式控制位 --   速度控制位
//   ADCCFG     B7  B6     B5     B4   B3 B2 B1 B0
        P_SW2 |= 0x80;                                                        //打開外設(shè)寄存器
        ADCTIM = 0x3f;                                                        //設(shè)置 ADC 內(nèi)部時序
        P_SW2 &= 0x7f;                                                        //關(guān)閉外設(shè)寄存器
        ADCCFG = 0x0f;                                                        //設(shè)置 ADC 時鐘為系統(tǒng)時鐘/2/16
        ADC_CONTR = 0x80;                                                //使能 ADC 模塊
//EEPROM初始操作
        S_ADC=IapRead(0x0000);                                        //讀取EEPROM保存的數(shù)據(jù)
        //if(S_ADC<50||S_ADC>150)                                        //判斷超出合適范圍,初次使用EEPROM全為0xff
                //S_ADC=100;                                                        //預(yù)設(shè)基準(zhǔn)值

        Timer0Init();                                                        //初始化定時器

        while (1)
        {
                if(TF0)                                                                //中斷請求周期2ms
                {
                        TF0=0;                                                        //中斷請求標(biāo)志清0
                        keys_can();                                                //按鍵掃描
                        M_ADC=GetADCResult();                        //讀取ADC
                        if(M_ADC < S_ADC)                                //比較
                        {
                                OUT = 1;                                        //輸出高電平
                                LED = 1;                                        //輸出指示亮
                        }
                        else         
                        {
                                OUT = 0;                                        //輸出低電平
                                LED = 0;                                        //輸出指示熄
                        }
                }
        }
}

51黑論壇_急停測試程序.zip

19.82 KB, 下載次數(shù): 15

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

使用道具 舉報(bào)

沙發(fā)
ID:94031 發(fā)表于 2021-9-9 14:38 | 只看該作者
可以先把 IapProgram(int addr, char dat)(寫),char IapRead(int addr)(讀) 單獨(dú)測試一下,看正常嗎。
回復(fù)

使用道具 舉報(bào)

板凳
ID:123289 發(fā)表于 2021-9-9 16:05 | 只看該作者
先證明一下,是否寫進(jìn)去了。
當(dāng)然,當(dāng)?shù)綦姲l(fā)重在寫數(shù)據(jù)期間,會發(fā)生寫失敗的,不過這是個概率問題。
回復(fù)

使用道具 舉報(bào)

地板
ID:792404 發(fā)表于 2021-9-9 18:10 | 只看該作者
IapErase(0);                    //擦除第0扇區(qū)
IapProgram(1,S_ADC);     //寫入數(shù)據(jù)
S_ADC=IapRead(1);        //讀取EEPROM保存的數(shù)據(jù)
這樣改一下就可以了,我之前有個程序也是按照官網(wǎng)提供的代碼寫的不行,這樣改一下就沒問題了,你試一下
回復(fù)

使用道具 舉報(bào)

5#
ID:716660 發(fā)表于 2021-9-9 18:28 | 只看該作者
YUANYUXING 發(fā)表于 2021-9-9 18:10
IapErase(0);                    //擦除第0扇區(qū)
IapProgram(1,S_ADC);     //寫入數(shù)據(jù)
S_ADC=IapRead( ...

還是不行呀
回復(fù)

使用道具 舉報(bào)

6#
ID:94031 發(fā)表于 2021-9-9 19:48 | 只看該作者
不知你是如何得到 “掉電之后不能重新讀取” 結(jié)論的。
回復(fù)

使用道具 舉報(bào)

7#
ID:716660 發(fā)表于 2021-9-9 20:07 | 只看該作者
xuyaqi 發(fā)表于 2021-9-9 19:48
不知你是如何得到 “掉電之后不能重新讀取” 結(jié)論的。

重新上電,之前保存到eeprom的adc值沒了
回復(fù)

使用道具 舉報(bào)

8#
ID:814525 發(fā)表于 2021-9-9 22:46 | 只看該作者
是不是IAP_CONTR = WT_12M;       //使能IAP  這句有問題。以下是驗(yàn)證沒問題的
sfr IAP_TPS = 0xF5;
#define  IAP_EN     (1<<7)
#define  IAP_ENABLE()        IAP_CONTR = IAP_EN; IAP_TPS = MAIN_Fosc / 1000000
回復(fù)

使用道具 舉報(bào)

9#
ID:624769 發(fā)表于 2021-9-9 23:00 | 只看該作者
你把:
                        S_ADC=GetADCResult();                        //讀取ADC
                         IapErase(0x0000);                                //擦除第0扇區(qū)
                        IapProgram(0x0000,S_ADC);                //寫入數(shù)據(jù)
                        LED=0;                                                        //保存成功指示
這里的 LED = 0;  改成:
if((IAP_CONTR & 0x10) == 0x00)    LED=0;                                                        //保存成功指示
來確定, 是不是真的保存成功了, 比較好。
回復(fù)

使用道具 舉報(bào)

10#
ID:401564 發(fā)表于 2021-9-10 08:30 | 只看該作者
這不是很簡單的東西嗎?
1,開發(fā)板上連接一個能顯示數(shù)據(jù)的,數(shù)碼管,OLED都行
2,寫一段開機(jī)就讀取指定EEPROM地址的程序,再寫一段按下按鍵就寫入指定地址EEPROM的,不要ADC,也不要什么串口,直接就是向一個地址寫入數(shù)據(jù):123,代碼越少越好
3,寫完之后,拔下電,然后上電,只要顯示的是123,就說明讀寫程序是對的

像你這個,又是ADC,又是比較的,總之就是結(jié)果不如意,但并不能確定問題出現(xiàn)在哪一步
回復(fù)

使用道具 舉報(bào)

11#
ID:716660 發(fā)表于 2021-9-10 09:27 | 只看該作者
確實(shí)保存了,但是重新上電 數(shù)據(jù)就變成11111111沒有之前的數(shù)了咋回事
回復(fù)

使用道具 舉報(bào)

12#
ID:716660 發(fā)表于 2021-9-10 15:26 | 只看該作者
Y_G_G 發(fā)表于 2021-9-10 08:30
這不是很簡單的東西嗎?
1,開發(fā)板上連接一個能顯示數(shù)據(jù)的,數(shù)碼管,OLED都行
2,寫一段開機(jī)就讀取指定EEPROM ...

試了 ,只能讀不能寫
回復(fù)

使用道具 舉報(bào)

13#
ID:170318 發(fā)表于 2021-9-10 16:18 | 只看該作者
讀寫程序有問題,STC8與STC15的EEPROM有點(diǎn)不一樣,詳細(xì)看手冊
回復(fù)

使用道具 舉報(bào)

14#
ID:401564 發(fā)表于 2021-9-10 18:25 | 只看該作者

晚上有空我?guī)湍銓懸粋看一下
回復(fù)

使用道具 舉報(bào)

15#
ID:716660 發(fā)表于 2021-9-10 19:01 | 只看該作者
Y_G_G 發(fā)表于 2021-9-10 18:25
晚上有空我?guī)湍銓懸粋看一下

好的謝謝哥
回復(fù)

使用道具 舉報(bào)

16#
ID:401564 發(fā)表于 2021-9-11 06:59 | 只看該作者
Stc8g1k17_GPS時鐘.rar (143.73 KB, 下載次數(shù): 50)
我這個是在自己以前的一個工程中測試的,運(yùn)行的結(jié)果是可以寫入和讀取的,掉電之后兩次讀取的結(jié)果是正確的
在EEPROM.c中,你可以
我手頭上沒有08a的,所以,我用的是STC8G1k17的,其實(shí)也是一樣的,STC8g系列是一樣的
要注意幾個點(diǎn):
1,這個型號的EEPROM只能把"1"寫成"0"!!!!!!!!!!這個很重要,也很扯,所以,每次寫入你要保存的數(shù)據(jù)之前,一定要先進(jìn)行"擦除"操作,而每次擦除卻是以扇區(qū)進(jìn)行的,這一點(diǎn)一定要理解!!!!!數(shù)據(jù)手冊中有說明,要認(rèn)真看
比如,你要保存5個地址的數(shù)據(jù),但你盲區(qū)還有這5個數(shù)據(jù)以外的其它數(shù)據(jù),那么,你就要先把這整個扇區(qū)數(shù)據(jù)先讀取出來,保存好,然后改動你要保存的5個地址的數(shù)據(jù),進(jìn)行整個扇區(qū)的擦除(全部寫入1),然后,再把之前改動過的一起寫入
2,下載器有一個"本次下載程序時擦除用戶EEPROM區(qū)"選項(xiàng),不要打鉤!
回復(fù)

使用道具 舉報(bào)

17#
ID:716660 發(fā)表于 2021-9-11 22:41 | 只看該作者
Y_G_G 發(fā)表于 2021-9-11 06:59
我這個是在自己以前的一個工程中測試的,運(yùn)行的結(jié)果是可以寫入和讀取的,掉電之后兩次讀取的結(jié)果是正確的
...

,好了
回復(fù)

使用道具 舉報(bào)

18#
ID:65956 發(fā)表于 2022-11-9 08:47 | 只看該作者
看你這程序要寫入內(nèi)部EEPROM數(shù)據(jù)要滿足按鍵按下一秒才會寫入,這樣掉電1秒才寫入是來不及寫入的,如果要確保掉電時寫入數(shù)據(jù),就要用到掉電中斷,可以在中斷里直接寫入,但字節(jié)要越少越好,不然要用一個AD功能讀電源輸入,當(dāng)電源低于一定值后就把數(shù)據(jù)寫入,否則按你這程序是不行的。僅供參考
回復(fù)

使用道具 舉報(bào)

19#
ID:483092 發(fā)表于 2025-1-4 11:32 | 只看該作者
Y_G_G 發(fā)表于 2021-9-11 06:59
我這個是在自己以前的一個工程中測試的,運(yùn)行的結(jié)果是可以寫入和讀取的,掉電之后兩次讀取的結(jié)果是正確的
...

厲害,太詳細(xì)了。
回復(fù)

使用道具 舉報(bào)

20#
ID:1006638 發(fā)表于 2025-1-22 20:38 | 只看該作者
我用這個小東西做了好多小玩意很好用,帶掉電保存數(shù)據(jù)功能也都很可靠。我是這樣做的:1,用較大的電源濾波電容680UF到1000UF(掉電后提供較多的能量)。2,上電后先擦除好EEPROM,斷電后光寫就行了,節(jié)省擦除時間,這對數(shù)據(jù)量較大情況尤為重要。3,我不用掉電中斷寫數(shù)據(jù),因?yàn)橛|發(fā)它已經(jīng)是電壓低了,低壓寫EEPROM不可靠(它數(shù)據(jù)手冊里說的)。我用穩(wěn)壓器前的電壓低于7v觸發(fā)外部中斷來寫的(不用ADC讀取,直接硬件比較器實(shí)現(xiàn))。針對你我建議先如樓上所言做一個極簡程序,上電先讀取EEPROM一個字節(jié)用LED顯示,再按下按鍵改變顯示值并寫進(jìn)EEPROM(注意先擦后寫),再斷電上電驗(yàn)證程序的基本功能是否正常(第一次不準(zhǔn)全是1,看第二次以后斷、上電LED狀態(tài)).正常后按我所做,應(yīng)該差不離。
回復(fù)

使用道具 舉報(bào)

21#
ID:1109793 發(fā)表于 2025-1-23 09:08 | 只看該作者
大IGBT 發(fā)表于 2025-1-22 20:38
我用這個小東西做了好多小玩意很好用,帶掉電保存數(shù)據(jù)功能也都很可靠。我是這樣做的:1,用較大的電源濾波 ...

一個1000UF的在12V端的電容,可以提供很長時間了。別說擦除一個扇區(qū)了,兩個三個也不在華夏吧。
回復(fù)

使用道具 舉報(bào)

22#
ID:161164 發(fā)表于 2025-1-26 23:18 | 只看該作者
大IGBT 發(fā)表于 2025-1-22 20:38
我用這個小東西做了好多小玩意很好用,帶掉電保存數(shù)據(jù)功能也都很可靠。我是這樣做的:1,用較大的電源濾波 ...

我用這種接法


回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 成人精品在线观看 | 精品一区二区在线视频 | 日本欧美国产在线观看 | 欧美日韩亚洲国产 | 日本韩国电影免费观看 | 99re热这里只有精品视频 | 日本一区二区三区四区 | 日韩欧美一级 | 久久国产激情视频 | a黄视频 | 日韩欧美在线精品 | 罗宾被扒开腿做同人网站 | 亚洲三区视频 | 国久久 | 9久9久9久女女女九九九一九 | 亚洲综合色 | 精品国产青草久久久久福利 | 久久毛片 | 色综合一区 | 久久久久久国产精品 | 一区二视频 | 一级片免费视频 | 国产一区二区三区视频 | 欧美一级观看 | 视频三区 | 亚洲精品2| 午夜无码国产理论在线 | 精品国产欧美 | 日韩中文字幕久久 | 亚州精品天堂中文字幕 | 午夜电影网站 | 久久九九99 | av一区二区在线观看 | 中文字幕在线一 | 亚洲精品一区中文字幕 | 一区二区三区久久久 | 一级在线 | 亚洲一区二区三区国产 | 午夜资源 | 亚洲视频在线一区 | 正在播放国产精品 |