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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 591|回復: 2
打印 上一主題 下一主題
收起左側

使用STC8H1K08內部EEPROM保存數值,求大佬講出問題所在

[復制鏈接]
跳轉到指定樓層
樓主
ID:622606 發表于 2025-2-20 16:20 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
使用STC8H1K08單片機做一個電機定時控制程序,想著使用內部EEPROM保存電機工作時間和停止時間,結果按鍵設置好數值之后斷電重啟顯示又變為000,保存不到值。一直找不錯原因,發帖尋求幫助,希望得到解決,謝謝!
下面是我寫的完整程序,麻煩大家指出我調用不了EEPROM的原因:
#include<STC8H.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
//#include "reg51.h"
#include "intrins.h"
/*sfr     IAP_DATA    =   0xC2;
sfr     IAP_ADDRH   =   0xC3;
sfr     IAP_ADDRL   =   0xC4;
sfr     IAP_CMD     =   0xC5;
sfr     IAP_TRIG    =   0xC6;
sfr     IAP_CONTR   =   0xC7;
sfr     IAP_TPS     =   0xF5;*/
#define uchar unsigned char
#define uint unsigned int
#define Offset 0x2000
sbit L1=P1^1;//定義千位
sbit L2=P1^2;// 百位
sbit L3=P1^3;// 十位

sbit KEY_CH=P1^5; //模式設置
sbit KEY_ADD=P1^6;  //加
sbit KEY_DEC=P1^7;  //減
sbit INB=P5^4;
sbit INA=P1^4;
//定義變量
uchar code smgduan[13]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0xff,0x89,0x92};//共陽極,顯示段碼值0~9,空,H,S;
bit ch;//定義上下限設置
uchar d1,d2,d3,mode;//顯示數據各位暫存變量
uint day ,out;//關停天數,啟動時間
unsigned long int time,second,minute,hour;
void init_IO()
{
                P1M0 = 0x1f;                                //設置P1.1為ADC口
    P1M1 = 0x00;
    P3M0 = 0x00;                                //設置P3.0~P3.7為開漏模式
    P3M1 = 0x00;       
    P5M0 = 0x10;                                //設置P3.0~P3.7為開漏模式
    P5M1 = 0x00;       
}

/*------------------------------------------------
mS延時函數,含有輸入參數 unsigned char t,無返回值
unsigned char 是定義無符號字符變量,其值的范圍是
0~255 這里使用晶振12M,精確延時請使用匯編
------------------------------------------------*/
void DelayMs(uchar n)//12M
{     
        uchar i, j;
         while (n--)
         {
                 for(i=0;i<10;i++);
                 for(j=0;j<105;j++);
                 
         }
}

/*內部EEPROM*/
//單片機內部EEPROM不使能
void IapIdle()
{
    IAP_CONTR = 0;                              //關閉IAP功能
    IAP_CMD = 0;                                //清除命令寄存器
    IAP_TRIG = 0;                               //清除觸發寄存器
    IAP_ADDRH         = 0x80;                           //將地址設置到非IAP區域
    IAP_ADDRL = 0;
//          IAP_DATA=0;                              //清除數據
}

//從單片機內部EEPROM讀一個字節,從0x0000地址開始
uchar EEPROM_Read(uint addr)
{
    uchar dat;
    IAP_CONTR = 0x80;                           //使能IAP,SYSCLK<24MHz  0x81  SYSCLK<=24
    IAP_TPS = 12;                               //設置等待參數12MHz
    IAP_CMD = 1;                                //設置IAP讀命令
          IAP_ADDRH = addr >> 8;                      //設置IAP高地址
    IAP_ADDRL = addr & 0xff;                           //設置IAP低地址
    IAP_TRIG = 0x5a;                            //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                            //寫觸發命令(0xa5)
    _nop_();
    dat = IAP_DATA;                             //讀IAP數據
    IapIdle();                                  //關閉IAP功能

    return dat;
}

//往單片機內部EEPROM寫一個字節
void EEPROM_Write(uint addr, uchar dat)
{
    IAP_CONTR = 0x80;                           //使能IAP
    IAP_TPS = 12;                               //設置等待參數12MHz
    IAP_CMD = 2;                                //設置IAP寫命令
          IAP_ADDRH = addr >> 8;                     //設置IAP高地址
    IAP_ADDRL = addr & 0xff;                          //設置IAP低地址
    IAP_DATA = dat;                             //寫IAP數據
    IAP_TRIG = 0x5a;                            //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                            //寫觸發命令(0xa5)
    _nop_();

    IapIdle();                                  //關閉IAP功能
}
//擦除單片機內部EEPROM的一個扇區
//寫8個扇區中隨便一個的地址,便擦除該扇區,寫入前要先擦除
void EEPROM_Erase(uint addr)
{
    IAP_CONTR = 0x80;                           //使能IAP
    IAP_TPS = 12;                               //設置等待參數12MHz
    IAP_CMD = 3;                                //設置IAP擦除命令
    IAP_ADDRH = addr >> 8;                      //設置IAP高地址
    IAP_ADDRL = addr & 0xff;                          //設置IAP低地址
    IAP_TRIG = 0x5a;                            //寫觸發命令(0x5a)
    IAP_TRIG = 0xa5;                            //寫觸發命令(0xa5)
     _nop_();   
    IapIdle();                                  //關閉IAP功能
}

/*------------------------------------------------
* 函數名         : DigDisplay()
* 函數功能                   : 數碼管顯示函數
* 輸入           : 無
* 輸出                  : 無
------------------------------------------------*/
void Display()
{
                L1=1;
           P3=smgduan[d1];
          DelayMs(1);
          L1=0;

                L2=1;
           P3=smgduan[d2];
          DelayMs(1);       
                L2=0;

          L3=1;
           P3=smgduan[d3];
          DelayMs(1);       
                L3=0;
       
}
/*------------------------------------------------
                    按鍵掃描程序
------------------------------------------------*/
void keyscan()
{
        if(!KEY_CH)
                {
                                DelayMs(100);
                if(!KEY_CH)       
                        ch=!ch;
                while(!KEY_CH);       
                }
               
        if(ch==1)
        {
                d1 =11;  //H,停限定
                d2= day/10;
                d3= day%10;
                Display();
               
                if(!KEY_ADD)
                {
                        DelayMs(20);
                        if(!KEY_ADD)
                        {
                                day+=5;
                                if(day>=100)
                                        day=99;  //最大加到100
                        }
                                while(!KEY_ADD);
                        }
                                if(!KEY_DEC)
                {
                        DelayMs(50);
                        if(!KEY_DEC)
                        {
                                if(day<=0)
        {day=0;}
                                else
                                day-=1;
                               
                        }
                                while(!KEY_DEC);
                        }       
                }
       
                if(ch==0)
        {
                d1 =12;  //S ,啟限定
                d2= out/10;
                d3 =out%10;
        Display();       
                if(!KEY_ADD)
                {
                        DelayMs(20);
                        if(!KEY_ADD)
                        {
                                out+=5;
                                if(out>=99)  //上下限3度區間
                                        out=99;
                        }
                                while(!KEY_ADD);
                        }
                                if(!KEY_DEC)
                {
                        DelayMs(50);
                        if(!KEY_DEC)
                        {
                                        if(out<=0)
                                        {out=0;}
                                        else
                                out-=1;

                        }
                                while(!KEY_DEC);
                        }       
                }
}
/*------------------------------------------------
                    定時器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
AUXR &= 0x7f;                //定時器時鐘12T模式
TMOD |= 0xf0;          //使用模式1,16位定時器,使用"|"符號可以在使用多個定時器時不受影響                     
TH0=0xb0;              //給定初值,這里使用定時器最大值從0開始計數一直到65535溢出
TL0=0x3c;        //50ms
EA=1;            //總中斷打開
ET0=1;           //定時器中斷打開
TF0=0;          //清除TF0標志
TR0=1;           //定時器開關打開

}
/*------------------------------------------------
                 定時器中斷子程序 12MHZ 12T
------------------------------------------------*/
void Timer0_isr(void) interrupt 1 using 1
{
  int n;
TH0=0xb0;              //給定初值,這里使用定時器最大值從0開始計數一直到65535溢出
TL0=0x3c;     //50ms
        if(mode==0 && out!=0)
        {
                n++;
        if(n==49)//一秒后
        {
                n=0;
                second++;
        }
        if(second==2)//等2秒
        {
                INA=1;//啟動水泵               
        }
        if(second==(out+2)) //out+2秒后
          {
                INA=0;//關閉
          }
         if(second==2+out+3600*day)        //2+out+day后time清零
                {
                second=0;
                }
        }
        else if(mode==1)
        {
                n=0;
                second=0;
                INA=0;
        }
}


/*------------------------------------------------
                    主函數
------------------------------------------------*/
void main (void)
{  
                int c;
  init_IO();
                mode=0;
                INA=0;
           day=EEPROM_Read(0x2000);  //天數
          out=EEPROM_Read(0x2001);
        Init_Timer0();
    while (1)
    {
                while ( mode==0)         //不按按鍵時
    {
//                Init_Timer0();
         d1=day/100; d2=(day%100)/10; d3=(day%100)%10;
                Display();
                if(!KEY_CH ||!KEY_ADD || !KEY_DEC)
                {
                        mode=1;
                }
   }
          while ( mode==1)         //按按鍵時
    {                       
                keyscan();       
                          EEPROM_Erase(0x2000); //存儲前必須先擦除
                     EEPROM_Write(0x2000, day); //
                    EEPROM_Write(0x2001, out);
                        if(KEY_CH && KEY_ADD && KEY_DEC)
                {
                        c++;
                        DelayMs(10);
                        if(c==9000)//停留9秒
                {
                        c=0;                       
                        mode=0;
                }               
                }
          }
          }
}

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

使用道具 舉報

沙發
ID:1133081 發表于 2025-2-20 21:41 | 只看該作者
STC8H1K08單片機的EEPROM只有4K,8個扇區,每個扇區512字節。各扇區首地址0x0000、0x0200、0x0400......0x0e00,你讀寫0x2000的地址根本不存在。

評分

參與人數 1黑幣 +10 收起 理由
wpppmlah + 10 回帖助人的獎勵!

查看全部評分

回復

使用道具 舉報

板凳
ID:68189 發表于 2025-2-21 08:16 | 只看該作者
EEPROM 地址從0x0000 開始計算,大小由ISP軟件下載時決定,,,,另外,把寫EEPROM的語句,不要放在這個WHILE循環中,,,,,,不然你按下鍵不放,就會一直重寫,不科學啊
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲精品久久久久久久久久久久久 | 亚洲一区二区三区免费在线观看 | a级片在线 | 国产精品毛片久久久久久 | 久久久久精 | 免费的av网站 | 视频二区国产 | 污片在线免费观看 | 精品一区久久 | 日韩成人精品在线观看 | 婷婷久久久久 | 欧美激情精品久久久久久 | aa级毛片毛片免费观看久 | 国产一级片一区二区 | 成人aaa视频 | 欧美在线观看一区二区 | 亚洲免费一区二区 | 久久久精品综合 | 一区二区三区在线 | 天天草天天| 午夜电影福利 | 国产免费一区二区 | 久草网址| 一级黄色片免费在线观看 | 久久久久久久久国产精品 | 国产精品自产拍 | 欧美一区二区激情三区 | 91热爆在线观看 | 久久精品亚洲 | 综合久久99| 国产精品日本一区二区不卡视频 | 亚洲国产aⅴ成人精品无吗 国产精品永久在线观看 | 欧美日韩精品国产 | 亚洲一区二区视频在线播放 | 伊人免费在线观看 | 天堂一区 | 99亚洲精品视频 | 亚洲性视频 | 亚洲国产精品人人爽夜夜爽 | 欧美五月婷婷 | 狠狠伊人|