请教,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(); // 报警判断
}
}
|