找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3|回复: 0
收起左侧

EEPROM存储的数据,断电后再上电,数据发生变化

[复制链接]
ID:74143 发表于 2026-4-11 09:27 | 显示全部楼层 |阅读模式
请教,EEPROM存储的数据,断电后再上电,数据发生变化的原因。

#include"STC8G.H"
#include"intrins.H"
#include"ADC.h"
#include"NTC.h"
#include"GPIO.h"
#include"TIMER.h"
#include"HC595_DISPLAY.h"

//==================== 引脚定义 ====================
sbit KEY_ADD  = P3^2;   // 加键
sbit KEY_SUB  = P1^4;   // 减键
sbit KEY_OK   = P1^7;   // 确认键

sbit BEEP     = P1^5;   // 蜂鸣器

sbit ADC_TEMP = P1^1;   

unsigned int temp_real;    // 实际温度值
unsigned int temp_high;     // 高温阈值
unsigned int temp_low;      // 低温阈值
unsigned char set_mode = 0;        // 设置模式标志:0=正常模式,1=设置高温,2=设置低温

// EEPROM 地址定义
#define EEPROM_ADDR_H 0x0000  
#define EEPROM_ADDR_L 0x0001  
#define EEPROM_ADDR   0x0000

void IAP_IDLE(void);
unsigned char IAP_Read(unsigned int addr);
void IAP_Write(unsigned int addr,unsigned char dat);
void IAP_Erase(unsigned int addr);

// 延时函数
void Delay_ms(unsigned int ms)
{
        unsigned int i,j;
                for(i=0;i<ms;i++)
                        for(j=0;j<24*85;j++);
}


void IAP_IDLE(void)
{
        IAP_CONTR = 0;   
        IAP_CMD = 0;      
        IAP_TRIG = 0;     
        IAP_ADDRH = 0x80;
        IAP_ADDRL = 0;   
}

// 单字节读
unsigned char IAP_Read(unsigned int addr)
{
        char dat;
        IAP_CONTR = 0x80;   
        IAP_TPS = 24;
        IAP_CMD = 0x01;   
        IAP_ADDRL = addr;   
        IAP_ADDRH = addr >> 8;
        IAP_TRIG = 0x5a;     
        IAP_TRIG = 0xa5;   
        _nop_();            
        dat = IAP_DATA;             
        IAP_IDLE();         
        return dat;
}

// 单字节写
void IAP_Write(unsigned int addr,unsigned char dat)
{
        IAP_CONTR = 0x80;      
        IAP_TPS = 24;
        IAP_CMD = 0x02;     
        IAP_ADDRL = addr;   
        IAP_ADDRH = addr >> 8;
        IAP_DATA = dat;             
        IAP_TRIG = 0x5a;     
        IAP_TRIG = 0xa5;      
        _nop_();           
        IAP_IDLE();
}

void IAP_Erase(unsigned int addr)
{
        IAP_CONTR = 0x80;   
        IAP_TPS = 24;
        IAP_CMD   = 0x03;   
        IAP_ADDRL = addr;
        IAP_ADDRH = addr >> 8;
        IAP_TRIG  = 0x5A;
        IAP_TRIG  = 0xA5;
        _nop_();              
        IAP_IDLE();
}


void Key_Scan(void)
{
  if(KEY_OK == 0)  // 确认键按下
  {
    Delay_ms(20);
    if(KEY_OK == 0)
    {
      set_mode++;
      if(set_mode > 2) set_mode = 0;
      
      // 退出设置模式时,保存参数到EEPROM
      if(set_mode == 0)
      {
        IAP_Erase(EEPROM_ADDR);  // 先擦除片区
                                IAP_Write(EEPROM_ADDR_H, temp_high);   // 保存高温
                                IAP_Write(EEPROM_ADDR_L, temp_low);  // 保存低温      }
      
      while(KEY_OK == 0); // 等待松开
    }
  }
  
  if(set_mode != 0) // 设置模式下才响应加减键
  {
    if(KEY_ADD == 0)
    {
      Delay_ms(20);
      if(KEY_ADD == 0)
      {
        if(set_mode == 1) temp_high++;  // 设置高温
        if(set_mode == 2) temp_low++;   // 设置低温
        while(KEY_ADD == 0);
      }                                                 
    }
   
    if(KEY_SUB == 0)
    {
      Delay_ms(20);
      if(KEY_SUB == 0)
      {
        if(set_mode == 1 && temp_high > 0) temp_high--;
        if(set_mode == 2 && temp_low > 0) temp_low--;
        while(KEY_SUB == 0);
      }
    }
  }
}

// 报警判断函数
void Alarm_Check(void)
{
  if(set_mode == 0) // 正常模式才报警
  {
    if(temp_real > temp_high || temp_real < temp_low)
                        BEEP = 0;  // 超阈值,蜂鸣器响
    else
                        BEEP = 1;  // 正常,蜂鸣器关
  }
  else
  {
                BEEP = 1; // 设置模式关闭报警
  }
}

// 主函数
void main(void)
{
  unsigned char        i;
        unsigned int        j;
       
        // 初始化
  GPIO_Init();         
  ADC_Init();// ADC初始化
        Timer0_Init();

        BEEP = 1;

        for(i=0; i<8; i++)        DisplayBuff [i] = 0xff;        //上电消隐        1111 1111
  

  temp_high = IAP_Read(EEPROM_ADDR_H);
        temp_low  = IAP_Read(EEPROM_ADDR_L);

  
  // 上电默认值(防止首次使用EEPROM无数据)
  if(temp_high == 0xFF || temp_high == 0) temp_high = 300;
  if(temp_low  == 0xFF || temp_low  == 0) temp_low  = 50;

  while(1)
  {
    if(!AUTO_ISP) IAP_CONTR = 0x60;

                Key_Scan();        // 按键扫描

                while(!g_bSystemTime1Ms)        ;        //等待1ms到
                g_bSystemTime1Ms = 0;
               
                if(++j >= 40)                //40ms到
                {
                        j = 0;

                        temp_real = Get_temperature(ADC_Read_Oversample(1)); // 采集实际温度

                        if(temp_real >= 0)
                        {
                                F0 = 0;       
        temp_real = temp_real;      
            }
                        else               
            {
        F0 = 1;       
        temp_real = -temp_real;   
            }
                       
                        DisplayBuff[7] = (temp_real / 1000);     //显示数值
      DisplayBuff[6] = (temp_real / 100) % 10;
      DisplayBuff[5] = (temp_real / 10) % 10 + DIS_DOT;        //十位 + 小数点(带小数点显示)
      DisplayBuff[4] = temp_real % 10;                                       

                        // 千位为 0 时不显示(消零),显示黑位(不亮)
            if(DisplayBuff[7] == 0)   
      DisplayBuff[7] = DIS_BLACK;

           
            if(F0 == 1)  
      DisplayBuff[7] = DIS_;

                        if((temp_real > 1200) && (temp_real < TEMP_MIN*10))
                        {
                                for(i=0; i<4; i++)        DisplayBuff[i] = DIS_;
                        }


                        if(temp_high >= 0)
                        {
                                F0 = 0;       
        temp_high = temp_high;      
            }
                        else               
            {
        F0 = 1;       
        temp_high = -temp_high;   
            }
                        DisplayBuff[3] = (temp_high / 1000);     //显示数值
      DisplayBuff[2] = (temp_high / 100) % 10;
      DisplayBuff[1] = (temp_high / 10) % 10 + DIS_DOT;        //十位 + 小数点(带小数点显示)
      DisplayBuff[0] = temp_high % 10;                                               

                       
            if(DisplayBuff[3] == 0)   
      DisplayBuff[3] = DIS_BLACK;

           
            if(F0 == 1)  
      DisplayBuff[3] = DIS_;

                        if((temp_high > 1200) && (temp_high < TEMP_MIN*10))
                        {
                                for(i=0; i<4; i++)        DisplayBuff[i] = DIS_;
                        }   
                }
    Alarm_Check();        // 报警判断
  }
}
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表