性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

  • 回復(fù)
  • 收藏
  • 點(diǎn)贊
  • 分享
  • 發(fā)新帖

STC15系列內(nèi)部EEPROM怎樣應(yīng)用

最近想用STC單片機(jī)做一個(gè)LED調(diào)光臺(tái)燈,采用PWM調(diào)光,用內(nèi)部EEPROM做掉電記憶。參考了STC官網(wǎng)上的EEPROM測(cè)試程序,測(cè)試了一下,一切正常,可是加到自己的程序里,編譯沒(méi)問(wèn)題,就是存儲(chǔ)不正常表現(xiàn)是不論關(guān)機(jī)前調(diào)到任何亮度,關(guān)機(jī)后再開(kāi)都是最大亮度。已經(jīng)調(diào)試2天了,就是無(wú)法存儲(chǔ)求各位大俠指點(diǎn)一二,不勝感激
全部回復(fù)(21)
正序查看
倒序查看
2017-01-06 22:19
下面把程序貼上來(lái)
/**************************************************/
#include
#include
#define uchar unsigned char  
#define uint unsigned  int 
#define CMD_IDLE     0 //空閑模式
#define CMD_READ     1 //IAP字節(jié)讀命令
#define CMD_PROGRAM  2 //IAP字節(jié)編程命令
#define CMD_ERASE    3 //IAP扇區(qū)擦除命令
#define ENABLE_IAP  0x82
#define IAP_ADDRESS  0x00
sbit led0=P3^4;
sbit led1=P3^5;
sbit add=P3^3;
sbit wsw=P3^2;
sbit doc=P3^1;
sbit footsw=P3^0;
uchar bright;
uchar flag=0;
uint i=0;
/****************關(guān)閉IAP********************************/
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讀一字節(jié)**************************/
uchar IAPReadByte(uchar addr)
{
uchar dat;  //數(shù)據(jù)緩沖區(qū)
IAP_CONTR   =ENABLE_IAP;  //使能IAP
IAP_CMD     =CMD_READ;  //設(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_();  //等待EEPROM操作完成
dat=IAP_DATA;  //讀EEPROM數(shù)據(jù)
IAPIdle();  //關(guān)閉IAP
return dat;  //返回?cái)?shù)據(jù)
}
/***************寫(xiě)一字節(jié)到EEPROM**************************/
void  IAPProgramByte(uchar addr,uchar dat)
{
IAP_CONTR   =ENABLE_IAP;  //使能IAP
IAP_CMD     =CMD_PROGRAM; //設(shè)置IAP命令
IAP_ADDRL   =addr;  //設(shè)置IAP底地址
IAP_ADDRH   =addr>>8;  //設(shè)置IAP高地址
IAP_DATA=dat;  //寫(xiě)EEPROM數(shù)據(jù)
IAP_TRIG    =0x5a;  //寫(xiě)觸發(fā)命令0x5a
IAP_TRIG    =0xa5;  //寫(xiě)觸發(fā)命令0xa5
_nop_();  //等待EEPROM操作完成
IAPIdle();  //關(guān)閉IAP
}
/**************扇區(qū)擦除**********************************/
void IAPEraseSector(uint addr)
{
IAP_CONTR   =ENABLE_IAP;  //使能IAP
IAP_CMD     =CMD_ERASE;  //設(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_();  //等待EEPROM操作完成
IAPIdle();  //關(guān)閉IAP
}
/*******************延時(shí)程序1ms********************
void delay1ms(uint a){
uchar i;
while(--a !=0){
for(i=0;i<600;i++);
}
}
/*************************************************/
void delay(uchar z)
{
        TMOD=0x02; //定時(shí)器0工作方式2,8位自動(dòng)重裝
        TH0=256-60;
    AUXR |= (1<<7); //T0設(shè)為1T 
        EA=1;
        ET0=1;
        TR0=1;
        while(i
        i = 0;
}
/*******************驅(qū)動(dòng)程序**********************/
void drive (void){
uchar a;
if(footsw==0){
a=0x10;
}
else{
a=bright;
}
   switch(flag){
    case 0:
led0=led1=0;
delay(a);
a=~a;
led0=led1=1;
delay(a);
a=~a;
break;
         case 1:
led0=1;
led1=0;
delay(a);
a=~a;
led0=led1=1;
delay(a);
a=~a;
break;
  case 2:
led0=0;
led1=1;
delay(a);
a=~a;
led0=led1=1;
delay(a);
a=~a;
break;
 }
}
/*******************亮度加程序********************/
void Add (void){
if(add==0){
bright++;
if(bright>0xfe){
bright=0xfe;
}
IAPProgramByte(IAP_ADDRESS,bright); //掉電保存標(biāo)志
}
}
/*******************亮度減程序*********************/
void Doc (void){
if(doc==0){
bright--;
if(bright<0x05){
bright=0x05;
}
IAPProgramByte(IAP_ADDRESS,bright); //掉電保存標(biāo)志
}
}
/*******************主程序**************************/
void main (void){
PCON = PCON & ~(1<<5); //低壓檢測(cè)標(biāo)志清0
ELVD = 1; //低壓監(jiān)測(cè)中斷允許
PLVD = 1; //低壓中斷 優(yōu)先級(jí)高
EA  = 1;
IE=0x81;
IT0=1;
bright= IAPReadByte(IAP_ADDRESS);
IAPEraseSector(IAP_ADDRESS);
add=1;
while(1){
drive();
Add();
Doc();
// IAPProgramByte(IAP_ADDRESS,bright); //掉電保存值
}
}
/****************************************************/
void timer0() interrupt 1
{
      i++;
}
/***************************************************/
void INT0() interrupt 0
{
EX0=0;
flag++;   
if(flag>=3){
flag=0 ;
}
EX0=1;
}
/****************掉電檢測(cè)服務(wù)程序*******************/
void LVD_Routine(void) interrupt 6
{
IAPProgramByte(IAP_ADDRESS,bright); //掉電保存值
  while(PCON & (1<<5))                        //檢測(cè)是否仍然低電壓
        {
                PCON = PCON & ~(1<<5);                //低壓檢測(cè)標(biāo)志清0
                for(i=0; i<100; i++)        ;        //延時(shí)一下
        }
}

/*************************************************/

請(qǐng)大俠指點(diǎn),程序哪里有問(wèn)題,小菜感激不盡。。。。。。

0
回復(fù)
2017-01-06 22:55
@流淌的歌聲1104
下面把程序貼上來(lái)/**************************************************/#include#include#defineucharunsignedchar #defineuintunsigned int #defineCMD_IDLE  0//空閑模式#defineCMD_READ  1//IAP字節(jié)讀命令#defineCMD_PROGRAM 2//IAP字節(jié)編程命令#defineCMD_ERASE  3//IAP扇區(qū)擦除命令#defineENABLE_IAP 0x82#defineIAP_ADDRESS 0x00sbitled0=P3^4;sbitled1=P3^5;sbitadd=P3^3;sbitwsw=P3^2;sbitdoc=P3^1;sbitfootsw=P3^0;ucharbright;ucharflag=0;uinti=0;/****************關(guān)閉IAP********************************/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讀一字節(jié)**************************/ucharIAPReadByte(ucharaddr){uchardat; //數(shù)據(jù)緩沖區(qū)IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_READ; //設(shè)置IAP命令I(lǐng)AP_ADDRL =addr; //設(shè)置IAP底地址IAP_ADDRH =addr>>8; //設(shè)置IAP高地址IAP_TRIG  =0x5a; //寫(xiě)觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫(xiě)觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成dat=IAP_DATA; //讀EEPROM數(shù)據(jù)IAPIdle(); //關(guān)閉IAPreturndat; //返回?cái)?shù)據(jù)}/***************寫(xiě)一字節(jié)到EEPROM**************************/void IAPProgramByte(ucharaddr,uchardat){IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_PROGRAM;//設(shè)置IAP命令I(lǐng)AP_ADDRL =addr; //設(shè)置IAP底地址IAP_ADDRH =addr>>8; //設(shè)置IAP高地址IAP_DATA=dat; //寫(xiě)EEPROM數(shù)據(jù)IAP_TRIG  =0x5a; //寫(xiě)觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫(xiě)觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成IAPIdle(); //關(guān)閉IAP}/**************扇區(qū)擦除**********************************/voidIAPEraseSector(uintaddr){IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_ERASE; //設(shè)置IAP命令I(lǐng)AP_ADDRL =addr; //設(shè)置IAP底地址IAP_ADDRH =addr>>8; //設(shè)置IAP高地址IAP_TRIG  =0x5a; //寫(xiě)觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫(xiě)觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成IAPIdle(); //關(guān)閉IAP}/*******************延時(shí)程序1ms********************voiddelay1ms(uinta){uchari;while(--a!=0){for(i=0;i
單片機(jī)型號(hào)是STC15F104E或15W104,6個(gè)IO全部用完

0
回復(fù)
2017-01-08 16:53
@流淌的歌聲1104
單片機(jī)型號(hào)是STC15F104E或15W104,6個(gè)IO全部用完[圖片][圖片]

下面是掉電存儲(chǔ)測(cè)試程序

/*******************************************************
  STC15W104 掉電保存EEPROM測(cè)試
  測(cè)試芯片工作頻率為11.0592MHz
/********************************************************/
#include
#include
#define uchar unsigned char  
#define uint unsigned  int
#define ENABLE_IAP  0x82
#define IAP_ADDRESS  0x0000
#define CMD_IDLE    0   //空閑模式
#define CMD_READ    1   //IAP字節(jié)讀命令
#define CMD_PROGRAM 2   //IAP字節(jié)編程命令
#define CMD_ERASE 3   //IAP扇區(qū)擦除命令
uchar bright;
sbit P30 = P3^0;
/***************延時(shí)程序*********************************/
void  Delay(uchar n)
{
uint x;
while(n--)
{
x=0;
while(++x);
}
}
/****************關(guān)閉IAP********************************/
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讀一字節(jié)**************************/
uchar IAPReadByte(uint addr)
{
uchar dat;  //數(shù)據(jù)緩沖區(qū)
IAP_CONTR   =ENABLE_IAP;  //使能IAP
IAP_CMD     =CMD_READ;  //設(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_();  //等待EEPROM操作完成
dat=IAP_DATA;  //讀EEPROM數(shù)據(jù)
IAPIdle();  //關(guān)閉IAP
return dat;  //返回?cái)?shù)據(jù)
}
/***************寫(xiě)一字節(jié)到EEPROM**************************/
void  IAPProgramByte(uint addr,uchar dat)
{
IAP_CONTR   =ENABLE_IAP;  //使能IAP
IAP_CMD     =CMD_PROGRAM; //設(shè)置IAP命令
IAP_ADDRL   =addr;  //設(shè)置IAP底地址
IAP_ADDRH   =addr>>8;  //設(shè)置IAP高地址
IAP_DATA=dat;  //寫(xiě)EEPROM數(shù)據(jù)
IAP_TRIG    =0x5a;  //寫(xiě)觸發(fā)命令0x5a
IAP_TRIG    =0xa5;  //寫(xiě)觸發(fā)命令0xa5
_nop_();  //等待EEPROM操作完成
IAPIdle();  //關(guān)閉IAP
}
/**************扇區(qū)擦除**********************************/
void IAPEraseSector(uint addr)
{
IAP_CONTR   =ENABLE_IAP;  //使能IAP
IAP_CMD     =CMD_ERASE;  //設(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_();  //等待EEPROM操作完成
IAPIdle();  //關(guān)閉IAP
}
/**************主函數(shù)***********************************/
void main()
{
//   Delay(10);
PCON = PCON & ~(1<<5); //低壓檢測(cè)標(biāo)志清0
ELVD = 1; //低壓監(jiān)測(cè)中斷允許
PLVD = 1; //低壓中斷 優(yōu)先級(jí)高
EA  = 1;
bright=IAPReadByte(IAP_ADDRESS);
if(bright != 0xf2) bright = 0x00;
IAPEraseSector(IAP_ADDRESS); //扇區(qū)擦除
P3=bright; //1111,1110系統(tǒng)OK
Delay(10); //延時(shí)
while(1);
/**********************************************/
void LVD_Routine(void) interrupt 6
{
bright = 0xf2;
IAPProgramByte(IAP_ADDRESS,bright ); //掉電保存值
}
/*************************************************/

0
回復(fù)
2017-01-08 22:08
@流淌的歌聲1104
下面是掉電存儲(chǔ)測(cè)試程序/******************************************************* STC15W104掉電保存EEPROM測(cè)試 測(cè)試芯片工作頻率為11.0592MHz/********************************************************/#include#include#defineucharunsignedchar #defineuintunsigned int#defineENABLE_IAP 0x82#defineIAP_ADDRESS 0x0000#defineCMD_IDLE  0 //空閑模式#defineCMD_READ  1 //IAP字節(jié)讀命令#defineCMD_PROGRAM2 //IAP字節(jié)編程命令#defineCMD_ERASE3 //IAP扇區(qū)擦除命令ucharbright;sbitP30=P3^0;/***************延時(shí)程序*********************************/void Delay(ucharn){uintx;while(n--){x=0;while(++x);}}/****************關(guān)閉IAP********************************/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讀一字節(jié)**************************/ucharIAPReadByte(uintaddr){uchardat; //數(shù)據(jù)緩沖區(qū)IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_READ; //設(shè)置IAP命令I(lǐng)AP_ADDRL =addr; //設(shè)置IAP底地址IAP_ADDRH =addr>>8; //設(shè)置IAP高地址IAP_TRIG  =0x5a; //寫(xiě)觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫(xiě)觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成dat=IAP_DATA; //讀EEPROM數(shù)據(jù)IAPIdle(); //關(guān)閉IAPreturndat; //返回?cái)?shù)據(jù)}/***************寫(xiě)一字節(jié)到EEPROM**************************/void IAPProgramByte(uintaddr,uchardat){IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_PROGRAM;//設(shè)置IAP命令I(lǐng)AP_ADDRL =addr; //設(shè)置IAP底地址IAP_ADDRH =addr>>8; //設(shè)置IAP高地址IAP_DATA=dat; //寫(xiě)EEPROM數(shù)據(jù)IAP_TRIG  =0x5a; //寫(xiě)觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫(xiě)觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成IAPIdle(); //關(guān)閉IAP}/**************扇區(qū)擦除**********************************/voidIAPEraseSector(uintaddr){IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_ERASE; //設(shè)置IAP命令I(lǐng)AP_ADDRL =addr; //設(shè)置IAP底地址IAP_ADDRH =addr>>8; //設(shè)置IAP高地址IAP_TRIG  =0x5a; //寫(xiě)觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫(xiě)觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成IAPIdle(); //關(guān)閉IAP}/**************主函數(shù)***********************************/voidmain(){// Delay(10);PCON=PCON&~(1
你用的是掉電時(shí)低壓檢測(cè)再保存數(shù)據(jù)
0
回復(fù)
2017-01-09 11:10
已經(jīng)被添加到社區(qū)經(jīng)典圖庫(kù)嘍
http://www.e-ticket.cn/bbs/classic/
0
回復(fù)
曾兵
LV.2
7
2017-01-10 11:21
@流淌的歌聲1104
單片機(jī)型號(hào)是STC15F104E或15W104,6個(gè)IO全部用完[圖片][圖片]
你好,我個(gè)人認(rèn)為是你的設(shè)計(jì)思路出問(wèn)題了,你采用掉點(diǎn)檢測(cè)存儲(chǔ),EEPROM在電壓下是不建議對(duì)其進(jìn)行讀寫(xiě)操作的,如果要采用掉點(diǎn)再存儲(chǔ),應(yīng)該留一個(gè)端口對(duì)電源電壓進(jìn)行檢測(cè),把單片兩端的電容加大是電源電壓掉電后單片機(jī)要維持工作一段時(shí)間來(lái)對(duì)數(shù)據(jù)進(jìn)行處理?;蛘呙看握{(diào)光的數(shù)據(jù)都要優(yōu)先保存在EEPROM里面,然后再讀出操作然后再保存。
0
回復(fù)
2017-01-12 16:34
@曾兵
你好,我個(gè)人認(rèn)為是你的設(shè)計(jì)思路出問(wèn)題了,你采用掉點(diǎn)檢測(cè)存儲(chǔ),EEPROM在電壓下是不建議對(duì)其進(jìn)行讀寫(xiě)操作的,如果要采用掉點(diǎn)再存儲(chǔ),應(yīng)該留一個(gè)端口對(duì)電源電壓進(jìn)行檢測(cè),把單片兩端的電容加大是電源電壓掉電后單片機(jī)要維持工作一段時(shí)間來(lái)對(duì)數(shù)據(jù)進(jìn)行處理?;蛘呙看握{(diào)光的數(shù)據(jù)都要優(yōu)先保存在EEPROM里面,然后再讀出操作然后再保存。

你好,曾老師,我仔細(xì)研究了STC15系列的官方資料,它內(nèi)部有一個(gè)低壓中斷,檢測(cè)到VCC下降到某一電壓,比如3.82V時(shí)會(huì)產(chǎn)生中斷。另外,EEPROM官方資料只是不建議低壓時(shí)操作,并不是不能操作。官方下載軟件上有低壓時(shí)禁止操作EEPROM選項(xiàng),不勾選就可以了。這樣我就可以利用低壓中斷來(lái)存儲(chǔ)數(shù)據(jù)了。我的測(cè)試程序就是就是掉電存儲(chǔ)。EEPROM可以操作10000次以上,也許我的燈用壞了,EEPROM也不會(huì)壞,可是現(xiàn)在是不用掉電中斷,每次調(diào)光都存儲(chǔ)也不行

0
回復(fù)
2017-01-12 16:37
@lihui710884923
你用的是掉電時(shí)低壓檢測(cè)再保存數(shù)據(jù)
是的,旅長(zhǎng)
0
回復(fù)
2017-01-12 16:40
@電源網(wǎng)-fqd
已經(jīng)被添加到社區(qū)經(jīng)典圖庫(kù)嘍http://www.e-ticket.cn/bbs/classic/
謝謝!
0
回復(fù)
曾兵
LV.2
11
2017-01-13 10:34
@流淌的歌聲1104
你好,曾老師,我仔細(xì)研究了STC15系列的官方資料,它內(nèi)部有一個(gè)低壓中斷,檢測(cè)到VCC下降到某一電壓,比如3.82V時(shí)會(huì)產(chǎn)生中斷。另外,EEPROM官方資料只是不建議低壓時(shí)操作,并不是不能操作。官方下載軟件上有低壓時(shí)禁止操作EEPROM選項(xiàng),不勾選就可以了。這樣我就可以利用低壓中斷來(lái)存儲(chǔ)數(shù)據(jù)了。我的測(cè)試程序就是就是掉電存儲(chǔ)。EEPROM可以操作10000次以上,也許我的燈用壞了,EEPROM也不會(huì)壞[圖片],可是現(xiàn)在是不用掉電中斷,每次調(diào)光都存儲(chǔ)也不行[圖片]
曾老師這個(gè)稱呼我可受不起啊,我也是懂點(diǎn)皮毛而已,要學(xué)習(xí)的東西還很多,只看你的程序有一點(diǎn)需要修改一下void Add (void){
if(add==0){
bright++; 按鍵程序后面應(yīng)該加防抖延時(shí)void Add (void){
if(add==0){ delay();if(add==0){
bright++;

}

#define IAP_ADDRESS  0x00這個(gè)地址是不是應(yīng)該為0X0000;

0
回復(fù)
2017-01-13 17:25
@曾兵
曾老師這個(gè)稱呼我可受不起啊,我也是懂點(diǎn)皮毛而已,要學(xué)習(xí)的東西還很多,只看你的程序有一點(diǎn)需要修改一下voidAdd(void){if(add==0){bright++; 按鍵程序后面應(yīng)該加防抖延時(shí)voidAdd(void){if(add==0){ delay();if(add==0){bright++;}#defineIAP_ADDRESS 0x00這個(gè)地址是不是應(yīng)該為0X0000;
0
回復(fù)
yorkhu
LV.1
13
2017-01-16 18:03

用掉電偵測(cè)來(lái)保存EEPROM 是非常不科學(xué)的,不知道你測(cè)量過(guò)從掉電開(kāi)始到MCU停止大概要多長(zhǎng)時(shí)間,而EERPOM的寫(xiě)又需要多長(zhǎng)時(shí)間,即便時(shí)間夠我也是不推薦這種寫(xiě)法的

如果一定要這樣做可以如下:

1.你可以在供電上加個(gè)外部電源檢測(cè)電路比如分壓,來(lái)檢測(cè)外部是否斷電,這個(gè)比MCU的低壓中斷來(lái)得早得多

2.MCU供電用二極管與外部電源隔開(kāi),并加大電容,當(dāng)外部掉電之后,確保MCU還有足夠的電執(zhí)行EEPROM操作

3.每次EEPROM操作前都是需要先擦除,再寫(xiě)入

0
回復(fù)
2017-01-16 22:30
@曾兵
曾老師這個(gè)稱呼我可受不起啊,我也是懂點(diǎn)皮毛而已,要學(xué)習(xí)的東西還很多,只看你的程序有一點(diǎn)需要修改一下voidAdd(void){if(add==0){bright++; 按鍵程序后面應(yīng)該加防抖延時(shí)voidAdd(void){if(add==0){ delay();if(add==0){bright++;}#defineIAP_ADDRESS 0x00這個(gè)地址是不是應(yīng)該為0X0000;
三人行,必有我?guī)?!何況您確實(shí)比我懂得多。感謝老師與我一菜鳥(niǎo)討論。您說(shuō)的Add==0后面需不需要延時(shí),我是這么想的:后面的變量bright是自加1,后面去掉了while(Add==0),不需要等待Add彈起,這樣的效果是按鍵按下后接著抬手,變量bright可能加1,也可能加2或更多,這對(duì)brightL來(lái)說(shuō)不重要,因?yàn)槲揖拖胍B加。如果按下Add不放,bright就會(huì)連加,直到放手。如果嫌他加的速度過(guò)快,可以加一點(diǎn)延時(shí)。如果想讓他乖乖的每按一次只加1,那延時(shí)是必須的,而且后面必須加上等按鍵彈起的語(yǔ)句while(Add==0)。
0
回復(fù)
2017-01-16 22:32
@yorkhu
用掉電偵測(cè)來(lái)保存EEPROM是非常不科學(xué)的,不知道你測(cè)量過(guò)從掉電開(kāi)始到MCU停止大概要多長(zhǎng)時(shí)間,而EERPOM的寫(xiě)又需要多長(zhǎng)時(shí)間,即便時(shí)間夠我也是不推薦這種寫(xiě)法的如果一定要這樣做可以如下:1.你可以在供電上加個(gè)外部電源檢測(cè)電路比如分壓,來(lái)檢測(cè)外部是否斷電,這個(gè)比MCU的低壓中斷來(lái)得早得多2.MCU供電用二極管與外部電源隔開(kāi),并加大電容,當(dāng)外部掉電之后,確保MCU還有足夠的電執(zhí)行EEPROM操作3.每次EEPROM操作前都是需要先擦除,再寫(xiě)入
說(shuō)的對(duì),我只是想試驗(yàn)一下
0
回復(fù)
曾兵
LV.2
16
2017-01-17 10:12
@流淌的歌聲1104
三人行,必有我?guī)?!何況您確實(shí)比我懂得多。感謝老師與我一菜鳥(niǎo)討論。您說(shuō)的Add==0后面需不需要延時(shí),我是這么想的:后面的變量bright是自加1,后面去掉了while(Add==0),不需要等待Add彈起,這樣的效果是按鍵按下后接著抬手,變量bright可能加1,也可能加2或更多,這對(duì)brightL來(lái)說(shuō)不重要,因?yàn)槲揖拖胍B加。如果按下Add不放,bright就會(huì)連加,直到放手。如果嫌他加的速度過(guò)快,可以加一點(diǎn)延時(shí)。如果想讓他乖乖的每按一次只加1,那延時(shí)是必須的,而且后面必須加上等按鍵彈起的語(yǔ)句while(Add==0)。
大家都是相互學(xué)習(xí),共同進(jìn)步,
0
回復(fù)
lanming77
LV.1
17
2017-01-17 16:50
為什么要掉電儲(chǔ)存呢? 可以在按鍵按下加或減就存儲(chǔ)一次bright 值 ,開(kāi)機(jī)先讀取EEPROM內(nèi)bright值就可以復(fù)原了。
0
回復(fù)
cxflbh
LV.3
18
2017-01-18 09:42
@lanming77
為什么要掉電儲(chǔ)存呢?可以在按鍵按下加或減就存儲(chǔ)一次bright值,開(kāi)機(jī)先讀取EEPROM內(nèi)bright值就可以復(fù)原了。

根本就沒(méi)必要掉電存儲(chǔ),我都是先把存儲(chǔ)的值和設(shè)定值做比較,不相等再存。比如:

if(power_set!=IapReadByte(POWER_IAP_ADDRESS))  //功率保存       

 {

POWER_write(); //保存功率設(shè)定值

 jizun_voltage(power_set);  //輸出基準(zhǔn)電壓

}

0
回復(fù)
2017-01-18 21:55
@cxflbh
根本就沒(méi)必要掉電存儲(chǔ),我都是先把存儲(chǔ)的值和設(shè)定值做比較,不相等再存。比如:if(power_set!=IapReadByte(POWER_IAP_ADDRESS)) //功率保存     {POWER_write();//保存功率設(shè)定值 jizun_voltage(power_set); //輸出基準(zhǔn)電壓}
數(shù)據(jù)改變一次就寫(xiě)一次eeprom,
0
回復(fù)
2017-01-19 22:38
@lihui710884923
數(shù)據(jù)改變一次就寫(xiě)一次eeprom,

感謝大家的熱心幫助,我的程序終于調(diào)試成功了!不成功的原因是每次開(kāi)機(jī)或復(fù)位后要加一定的延時(shí),比如100ms,甚至10ms有時(shí)都可以,比如上面的掉電測(cè)試程序。今天閑來(lái)無(wú)事翻看一本雜志,看到一篇關(guān)于EEPROM應(yīng)用的文章,其中有一句話說(shuō)上電后一定要延時(shí)幾百毫秒待電源穩(wěn)定后再進(jìn)行EEPROM操作,否則極易操作失敗。我趕緊打開(kāi)電腦,在main函數(shù)最前面加上了100ms延時(shí)后,編譯,下載到單片機(jī),哈哈,操作成功!心中不免有些感慨,想起杜洋老師在他著的《愛(ài)上單片機(jī)》一書(shū)中的一句話:我和單片機(jī)一起玩耍,我玩它時(shí),它總能給我?guī)?lái)幸福和成就感。它玩我的時(shí)候,我總會(huì)煩躁,不知所措,可是耐心研究之后發(fā)現(xiàn)過(guò)錯(cuò)總是出在我的馬虎大意。我早應(yīng)該發(fā)現(xiàn)我的測(cè)試程序里有一個(gè)10ms的延時(shí)程序有需要的親們可以在樓上程序里加上100ms延時(shí)后直接用!

通過(guò)實(shí)驗(yàn),掉電存儲(chǔ)是可行的,因?yàn)镋EPROM操作需要較長(zhǎng)時(shí)間,影響其他程序運(yùn)行,另外存儲(chǔ)次數(shù)也是有限的,如果變量操作頻繁,一天幾百上千次,那就用不了多長(zhǎng)時(shí)間了,所以,這個(gè)實(shí)驗(yàn)還是有意義的

0
回復(fù)
2017-01-19 22:48
@流淌的歌聲1104
下面把程序貼上來(lái)/**************************************************/#include#include#defineucharunsignedchar #defineuintunsigned int #defineCMD_IDLE  0//空閑模式#defineCMD_READ  1//IAP字節(jié)讀命令#defineCMD_PROGRAM 2//IAP字節(jié)編程命令#defineCMD_ERASE  3//IAP扇區(qū)擦除命令#defineENABLE_IAP 0x82#defineIAP_ADDRESS 0x00sbitled0=P3^4;sbitled1=P3^5;sbitadd=P3^3;sbitwsw=P3^2;sbitdoc=P3^1;sbitfootsw=P3^0;ucharbright;ucharflag=0;uinti=0;/****************關(guān)閉IAP********************************/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讀一字節(jié)**************************/ucharIAPReadByte(ucharaddr){uchardat; //數(shù)據(jù)緩沖區(qū)IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_READ; //設(shè)置IAP命令I(lǐng)AP_ADDRL =addr; //設(shè)置IAP底地址IAP_ADDRH =addr>>8; //設(shè)置IAP高地址IAP_TRIG  =0x5a; //寫(xiě)觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫(xiě)觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成dat=IAP_DATA; //讀EEPROM數(shù)據(jù)IAPIdle(); //關(guān)閉IAPreturndat; //返回?cái)?shù)據(jù)}/***************寫(xiě)一字節(jié)到EEPROM**************************/void IAPProgramByte(ucharaddr,uchardat){IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_PROGRAM;//設(shè)置IAP命令I(lǐng)AP_ADDRL =addr; //設(shè)置IAP底地址IAP_ADDRH =addr>>8; //設(shè)置IAP高地址IAP_DATA=dat; //寫(xiě)EEPROM數(shù)據(jù)IAP_TRIG  =0x5a; //寫(xiě)觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫(xiě)觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成IAPIdle(); //關(guān)閉IAP}/**************扇區(qū)擦除**********************************/voidIAPEraseSector(uintaddr){IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_ERASE; //設(shè)置IAP命令I(lǐng)AP_ADDRL =addr; //設(shè)置IAP底地址IAP_ADDRH =addr>>8; //設(shè)置IAP高地址IAP_TRIG  =0x5a; //寫(xiě)觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫(xiě)觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成IAPIdle(); //關(guān)閉IAP}/*******************延時(shí)程序1ms********************voiddelay1ms(uinta){uchari;while(--a!=0){for(i=0;i

void main (void){

    DELAY_MS(100);//在此處加入100ms延時(shí)就OK!

    以下省略

0
回復(fù)
2017-02-14 08:55
之前我用的STC11F01看了數(shù)據(jù)手冊(cè)很簡(jiǎn)單,eeprom是死的,先調(diào)試出來(lái)可以調(diào)光的,然后在調(diào)光的后邊加保存到rom的語(yǔ)句,這樣每調(diào)一次保存一次。燒進(jìn)去。在把程序開(kāi)始讀取改為讀取之前的地址,再燒進(jìn)去就可以了。
0
回復(fù)
發(fā)