|
1、EEPROM扇區(qū)擦除或讀寫(xiě)的時(shí)候不能與其他的程序同時(shí)跑。要解決EEPROM擦除或讀寫(xiě)的時(shí)候不影響數(shù)碼管動(dòng)態(tài)掃描需要學(xué)會(huì)統(tǒng)籌調(diào)度,這要結(jié)合具體應(yīng)用處理,不是三言兩語(yǔ)說(shuō)的清的。
2、讀取128以上數(shù)據(jù)顯示出錯(cuò)多為數(shù)據(jù)類型使用不當(dāng)。想寫(xiě)入6666需要拆分為兩個(gè)字節(jié),讀取后再合并還原。
測(cè)試程序:
- //測(cè)試條件:STC8H實(shí)驗(yàn)板,MCU型號(hào)STC8H3K48S2
- //注意:測(cè)試本示例時(shí),需在ISP下載時(shí)將【允許低壓復(fù)位(禁止低壓中斷)】關(guān)閉
- #include <STC8H.H>
- #include <intrins.h> //庫(kù)頭文件
- #define uint unsigned int //宏定義數(shù)據(jù)類型uint
- #define uchar unsigned char //宏定義數(shù)據(jù)類型uchar
- #define IAP_ADDRESS 0x0000 //測(cè)試地址
- //順序共陰極數(shù)碼管段碼表,段碼a-h順序接PX0-PX7
- uchar code table[]={//共陰數(shù)碼管段碼"0~f-."
- 0x3f,0x06,0x5b,0x4f,
- 0x66,0x6d,0x7d,0x07,
- 0x7f,0x6f,0x77,0x7c,
- 0x39,0x5e,0x79,0x71,0x40,0x80};
- uchar data dis_buf[8]; //緩存數(shù)組
- uint num,sec;
- uchar i;
- uint sign;
- void Timer0Init(); //定時(shí)器初始化聲明
- void IapIdle(); //關(guān)閉IAP/EEPROM
- uchar IapRead(uint addr); //讀取EEPROM數(shù)據(jù)
- void IapProgram(uint addr, uchar dat);//寫(xiě)入EEPROM數(shù)據(jù)
- void IapErase(uint addr); //擦除EEPROM扇區(qū)
- //初始化單片機(jī)端口
- void McuInit()
- {
- P0M0 = 0xff; P0M1 = 0x00;
- P1M0 = 0x00; P1M1 = 0x00;
- P2M0 = 0x00; P2M1 = 0x00;
- P3M0 = 0x00; P3M1 = 0x00;
- P4M0 = 0x00; P4M1 = 0x00;
- P5M0 = 0x00; P5M1 = 0x00;
- P6M0 = 0x00; P6M1 = 0x00;
- P7M0 = 0x00; P7M1 = 0x00;
- }
- //關(guān)閉單片機(jī)端口
- void McuSleep()
- {
- P0M0 = 0x00; P0M1 = 0xff;
- P1M0 = 0x00; P1M1 = 0xff;
- P2M0 = 0x00; P2M1 = 0xff;
- P3M0 = 0x00; P3M1 = 0xff;
- P4M0 = 0x00; P4M1 = 0xff;
- P5M0 = 0x00; P5M1 = 0xff;
- P6M0 = 0x00; P6M1 = 0xff;
- P7M0 = 0x00; P7M1 = 0xff;
- }
- void main()
- {
- McuInit();
- if(IapRead(IAP_ADDRESS)==0xff)//如果沒(méi)有保存過(guò)數(shù)據(jù)
- {
- IapProgram(IAP_ADDRESS, 0);//扇區(qū)首地址寫(xiě)0
- sec=0;
- sign=1;
- }
- else
- {
- // for(i=1;i<12;i++) //測(cè)試寫(xiě)10次
- for(i=1;i<511;i++) //測(cè)試寫(xiě)滿510個(gè)字節(jié)
- {
- if(IapRead(IAP_ADDRESS+i)==0xff)//如果遇到?jīng)]有保存數(shù)據(jù)的單元
- {
- sec=IapRead(IAP_ADDRESS+i-1);//讀取前一個(gè)字節(jié)保存的數(shù)據(jù)
- sign=i; //地址緩存
- break; //跳出循環(huán)
- }
- }
- }
- // if(sign==11) //測(cè)試寫(xiě)10次
- if(sign==510) //如果寫(xiě)滿510
- {
- IapErase(IAP_ADDRESS); //擦除扇區(qū)
- IapProgram(IAP_ADDRESS, 0);//首地址寫(xiě)0
- sign=1;
- }
- PCON &= 0xDF; //清0掉電標(biāo)志
- ELVD = 1; //開(kāi)低壓中斷
- EA = 1; //開(kāi)總中斷
- Timer0Init(); //初始化定時(shí)器
- while(1)
- {
- if(TF0) //查詢T0中斷請(qǐng)求標(biāo)志
- {
- TF0=0; //T0中斷請(qǐng)求標(biāo)志清0
- if(++num>=1000) //1秒
- {
- num=0;
- sec=++sec%250;
- }
- dis_buf[0]=table[sec/100%10];
- dis_buf[1]=table[sec/10%10];
- dis_buf[2]=table[sec%10];
- P0=0x00; //段消隱
- P2=~(0x01<<i); //送段碼
- P0=dis_buf[i]; //送位碼
- i=++i%3; //循環(huán)計(jì)數(shù)
- }//耗時(shí)569us
- }
- }
- void PowerLost() interrupt 6 //低壓中斷
- {
- EA = 0; //關(guān)閉總中斷
- McuSleep(); //關(guān)閉所有端口(停止所有耗電電路)
- IapProgram(IAP_ADDRESS+sign,sec);//寫(xiě)數(shù)據(jù)到EEPROM
- while((PCON & 0x20) != 0) //復(fù)查低壓標(biāo)志
- {
- PCON &= 0xDF; //清除低壓標(biāo)志
- _nop_();
- _nop_(); //坐等掉電
- }
- IAP_CONTR = 0x20; //發(fā)現(xiàn)是誤報(bào),重啟單片機(jī),恢復(fù)正常工作
- }
- void Timer0Init(void) //1毫秒@11.0592MHz
- {
- AUXR |= 0x80; //定時(shí)器時(shí)鐘1T模式
- TMOD &= 0xF0; //設(shè)置定時(shí)器模式
- TL0 = 0xCD; //設(shè)置定時(shí)初始值
- TH0 = 0xD4; //設(shè)置定時(shí)初始值
- TF0 = 0; //清除TF0標(biāo)志
- TR0 = 1; //定時(shí)器0開(kāi)始計(jì)時(shí)
- }
- //關(guān)閉IAP/EEPROM
- void IapIdle()
- {
- IAP_CONTR = 0; //關(guān)閉IAP功能
- IAP_CMD = 0; //清除命令寄存器
- IAP_TRIG = 0; //清除觸發(fā)寄存器
- IAP_ADDRH = 0x80; //將地址設(shè)置到非IAP區(qū)域
- IAP_ADDRL = 0;
- }
- //讀取EEPROM數(shù)據(jù)
- uchar IapRead(uint addr)
- {
- uchar dat;
- IAP_CONTR = 0x80; //使能IAP
- IAP_TPS = 12; //設(shè)置等待參數(shù)12MHz
- IAP_CMD = 1; //設(shè)置IAP讀命令
- IAP_ADDRL = addr; //設(shè)置IAP低地址
- IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
- IAP_TRIG = 0x5a; //寫(xiě)觸發(fā)命令(0x5a)
- IAP_TRIG = 0xa5; //寫(xiě)觸發(fā)命令(0xa5)
- _nop_();
- dat = IAP_DATA; //讀IAP數(shù)據(jù)
- IapIdle(); //關(guān)閉IAP功能
- return dat;
- }
- //寫(xiě)入EEPROM數(shù)據(jù)
- void IapProgram(uint addr, uchar dat)
- {
- IAP_CONTR = 0x80; //使能IAP
- IAP_TPS = 12; //設(shè)置等待參數(shù)12MHz
- IAP_CMD = 2; //設(shè)置IAP寫(xiě)命令
- IAP_ADDRL = addr; //設(shè)置IAP低地址
- IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
- IAP_DATA = dat; //寫(xiě)IAP數(shù)據(jù)
- IAP_TRIG = 0x5a; //寫(xiě)觸發(fā)命令(0x5a)
- IAP_TRIG = 0xa5; //寫(xiě)觸發(fā)命令(0xa5)
- _nop_();
- IapIdle(); //關(guān)閉IAP功能
- }
- void IapErase(uint addr)
- {
- IAP_CONTR = 0x80; //使能IAP
- IAP_TPS = 12; //設(shè)置等待參數(shù)12MHz
- IAP_CMD = 3; //設(shè)置IAP擦除命令
- IAP_ADDRL = addr; //設(shè)置IAP低地址
- IAP_ADDRH = addr >> 8; //設(shè)置IAP高地址
- IAP_TRIG = 0x5a; //寫(xiě)觸發(fā)命令(0x5a)
- IAP_TRIG = 0xa5; //寫(xiě)觸發(fā)命令(0xa5)
- _nop_(); //
- IapIdle(); //關(guān)閉IAP功能
- }
復(fù)制代碼
|
評(píng)分
-
查看全部評(píng)分
|