日韩在线不卡免费视频一区,日韩欧美精品一区二区三区经典,日产精品码2码三码四码区,人妻无码一区二区三区免费,日本feerbbwdh少妇丰满

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

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

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

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

請大俠指點,程序哪里有問題,小菜感激不盡。。。。。。

0
回復
2017-01-06 22:55
@流淌的歌聲1104
下面把程序貼上來/**************************************************/#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; //將地址設置到非IAP區(qū)域IAP_ADDRL =0; //} /****************從EEPROM讀一字節(jié)**************************/ucharIAPReadByte(ucharaddr){uchardat; //數(shù)據(jù)緩沖區(qū)IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_READ; //設置IAP命令I(lǐng)AP_ADDRL =addr; //設置IAP底地址IAP_ADDRH =addr>>8; //設置IAP高地址IAP_TRIG  =0x5a; //寫觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成dat=IAP_DATA; //讀EEPROM數(shù)據(jù)IAPIdle(); //關(guān)閉IAPreturndat; //返回數(shù)據(jù)}/***************寫一字節(jié)到EEPROM**************************/void IAPProgramByte(ucharaddr,uchardat){IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_PROGRAM;//設置IAP命令I(lǐng)AP_ADDRL =addr; //設置IAP底地址IAP_ADDRH =addr>>8; //設置IAP高地址IAP_DATA=dat; //寫EEPROM數(shù)據(jù)IAP_TRIG  =0x5a; //寫觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成IAPIdle(); //關(guān)閉IAP}/**************扇區(qū)擦除**********************************/voidIAPEraseSector(uintaddr){IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_ERASE; //設置IAP命令I(lǐng)AP_ADDRL =addr; //設置IAP底地址IAP_ADDRH =addr>>8; //設置IAP高地址IAP_TRIG  =0x5a; //寫觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成IAPIdle(); //關(guān)閉IAP}/*******************延時程序1ms********************voiddelay1ms(uinta){uchari;while(--a!=0){for(i=0;i
單片機型號是STC15F104E或15W104,6個IO全部用完

0
回復
2017-01-08 16:53
@流淌的歌聲1104
單片機型號是STC15F104E或15W104,6個IO全部用完[圖片][圖片]

下面是掉電存儲測試程序

/*******************************************************
  STC15W104 掉電保存EEPROM測試
  測試芯片工作頻率為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;
/***************延時程序*********************************/
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;  //將地址設置到非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;  //設置IAP命令
IAP_ADDRL   =addr;  //設置IAP底地址
IAP_ADDRH   =addr>>8;  //設置IAP高地址
IAP_TRIG    =0x5a;  //寫觸發(fā)命令0x5a
IAP_TRIG    =0xa5;  //寫觸發(fā)命令0xa5
_nop_();  //等待EEPROM操作完成
dat=IAP_DATA;  //讀EEPROM數(shù)據(jù)
IAPIdle();  //關(guān)閉IAP
return dat;  //返回數(shù)據(jù)
}
/***************寫一字節(jié)到EEPROM**************************/
void  IAPProgramByte(uint addr,uchar dat)
{
IAP_CONTR   =ENABLE_IAP;  //使能IAP
IAP_CMD     =CMD_PROGRAM; //設置IAP命令
IAP_ADDRL   =addr;  //設置IAP底地址
IAP_ADDRH   =addr>>8;  //設置IAP高地址
IAP_DATA=dat;  //寫EEPROM數(shù)據(jù)
IAP_TRIG    =0x5a;  //寫觸發(fā)命令0x5a
IAP_TRIG    =0xa5;  //寫觸發(fā)命令0xa5
_nop_();  //等待EEPROM操作完成
IAPIdle();  //關(guān)閉IAP
}
/**************扇區(qū)擦除**********************************/
void IAPEraseSector(uint addr)
{
IAP_CONTR   =ENABLE_IAP;  //使能IAP
IAP_CMD     =CMD_ERASE;  //設置IAP命令
IAP_ADDRL   =addr;  //設置IAP底地址
IAP_ADDRH   =addr>>8;  //設置IAP高地址
IAP_TRIG    =0x5a;  //寫觸發(fā)命令0x5a
IAP_TRIG    =0xa5;  //寫觸發(fā)命令0xa5
_nop_();  //等待EEPROM操作完成
IAPIdle();  //關(guān)閉IAP
}
/**************主函數(shù)***********************************/
void main()
{
//   Delay(10);
PCON = PCON & ~(1<<5); //低壓檢測標志清0
ELVD = 1; //低壓監(jiān)測中斷允許
PLVD = 1; //低壓中斷 優(yōu)先級高
EA  = 1;
bright=IAPReadByte(IAP_ADDRESS);
if(bright != 0xf2) bright = 0x00;
IAPEraseSector(IAP_ADDRESS); //扇區(qū)擦除
P3=bright; //1111,1110系統(tǒng)OK
Delay(10); //延時
while(1);
/**********************************************/
void LVD_Routine(void) interrupt 6
{
bright = 0xf2;
IAPProgramByte(IAP_ADDRESS,bright ); //掉電保存值
}
/*************************************************/

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

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

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

}

#define IAP_ADDRESS  0x00這個地址是不是應該為0X0000;

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

用掉電偵測來保存EEPROM 是非常不科學的,不知道你測量過從掉電開始到MCU停止大概要多長時間,而EERPOM的寫又需要多長時間,即便時間夠我也是不推薦這種寫法的

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

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

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

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

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

根本就沒必要掉電存儲,我都是先把存儲的值和設定值做比較,不相等再存。比如:

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

 {

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

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

}

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

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

通過實驗,掉電存儲是可行的,因為EEPROM操作需要較長時間,影響其他程序運行,另外存儲次數(shù)也是有限的,如果變量操作頻繁,一天幾百上千次,那就用不了多長時間了,所以,這個實驗還是有意義的

0
回復
2017-01-19 22:48
@流淌的歌聲1104
下面把程序貼上來/**************************************************/#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; //將地址設置到非IAP區(qū)域IAP_ADDRL =0; //} /****************從EEPROM讀一字節(jié)**************************/ucharIAPReadByte(ucharaddr){uchardat; //數(shù)據(jù)緩沖區(qū)IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_READ; //設置IAP命令I(lǐng)AP_ADDRL =addr; //設置IAP底地址IAP_ADDRH =addr>>8; //設置IAP高地址IAP_TRIG  =0x5a; //寫觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成dat=IAP_DATA; //讀EEPROM數(shù)據(jù)IAPIdle(); //關(guān)閉IAPreturndat; //返回數(shù)據(jù)}/***************寫一字節(jié)到EEPROM**************************/void IAPProgramByte(ucharaddr,uchardat){IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_PROGRAM;//設置IAP命令I(lǐng)AP_ADDRL =addr; //設置IAP底地址IAP_ADDRH =addr>>8; //設置IAP高地址IAP_DATA=dat; //寫EEPROM數(shù)據(jù)IAP_TRIG  =0x5a; //寫觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成IAPIdle(); //關(guān)閉IAP}/**************扇區(qū)擦除**********************************/voidIAPEraseSector(uintaddr){IAP_CONTR =ENABLE_IAP; //使能IAPIAP_CMD  =CMD_ERASE; //設置IAP命令I(lǐng)AP_ADDRL =addr; //設置IAP底地址IAP_ADDRH =addr>>8; //設置IAP高地址IAP_TRIG  =0x5a; //寫觸發(fā)命令0x5aIAP_TRIG  =0xa5; //寫觸發(fā)命令0xa5_nop_(); //等待EEPROM操作完成IAPIdle(); //關(guān)閉IAP}/*******************延時程序1ms********************voiddelay1ms(uinta){uchari;while(--a!=0){for(i=0;i

void main (void){

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

    以下省略

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