eeprom程序不管用,高手指点一下
#include "stc8g.h"#include <intrins.h>
#define uint8 unsigned char
#define uint16 unsigned int
#define STORAGE_SECTOR 0 // 使用第一个扇区存储数据
#define EEPROM_START_ADDR 0x0400 // 起始地址
#define DATA_ADDR_HIGH (EEPROM_START_ADDR) // 数据高字节地址
#define DATA_ADDR_LOW (EEPROM_START_ADDR +1)// 数据低字节地址
/* 引脚定义 */
sbit TM1637_CLK = P1^1;
sbit TM1637_DIO = P1^0;
sbit KEY1 = P1^2;
sbit KEY2 = P1^3;
sbit KEY3 = P3^7;
sbit KEY4 = P3^6;
sbit KEY5 = P1^5;
/* 数码管编码表 */
static const uint8 digit_encode[] = {
0x3F, 0x06, 0x5B, 0x4F,
0x66, 0x6D, 0x7D, 0x07,
0x7F, 0x6F/* 0-9 */
};
uint8 display_digits; /* 显示缓冲区 */
uint8 selected_digit = 0; /* 当前选中的数码管位 */
uint8 setting_mode = 0; /* 设置模式标志 */
uint16 stored_value = 0; /* 存储值 */
uint8 blink_state = 0; /* 闪烁状态 */
/* 微秒级延时函数 */
void delay_us(uint8 us) {
while(us--) {
_nop_(); _nop_(); _nop_();
}
}
void Delay(unsigned int xms) //@11.0592MHz
{
unsigned char i, j;
while(xms--)
{ _nop_();
_nop_();
_nop_();
i = 11;
j = 190;
do
{
while (--j);
} while (--i);
}
}
/* TM1637通信协议 */
void tm1637_start(void) {
TM1637_CLK = 1;
TM1637_DIO = 1;
delay_us(2);
TM1637_DIO = 0;
}
void tm1637_ask(void)
{
TM1637_CLK = 0;
delay_us(5);
while (TM1637_DIO);
TM1637_CLK = 1;
delay_us(2);
TM1637_CLK = 0;
}
void tm1637_stop(void) {
TM1637_CLK = 0;
delay_us(2);
TM1637_DIO = 0;
delay_us(2);
TM1637_CLK = 1;
delay_us(2);
TM1637_DIO = 1;
}
void tm1637_write(uint8 Data) {
uint8 i;
for(i = 0; i < 8; i++)
{
TM1637_CLK = 0;
if(Data&0x01)
{
TM1637_DIO = 1;
}
else{
TM1637_DIO = 0;
}
delay_us(3);
Data=Data>>1;
TM1637_CLK = 1;
delay_us(3);
}
}
/**iic函数*****/
void Iapldle()
{
IAP_CONTR = 0;//关闭IAP 功能
IAP_CMD = 0;//清除命令寄存器
IAP_TRIG = 0;//清除触发寄存器
IAP_ADDRH = 0x80;//将地址设置到非IAP区域
IAP_ADDRL = 0;
}
void IAP_Wait(void)
{
IAP_CONTR = 0x80; // 使能IAP
IAP_TPS = 12; // 时钟分频(主频11.0592MHz)
_nop_();
}
/* 扇区擦除(所有扇区大小512字节) */
void EEPROM_EraseSector(uint16 addr)
{
IAP_Wait();
IAP_CMD = 0x03; // 写命令:擦除
IAP_ADDRL = addr ;
IAP_ADDRH = addr >> 8;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5; // 触发操作
_nop_();
IapIdle(); // 清除命令
}
/* 写一个字节 */
void EEPROM_WriteByte(uint16 addr, uint8 dat)
{
IAP_Wait();
IAP_CMD = 2; // 设置IAP写命令
IAP_ADDRL = addr; // 设置低地址位
IAP_ADDRH = addr >> 8; // 设置高地址位
IAP_DATA = dat; // 写入数据
IAP_TRIG = 0x5a; // 触发命令第一步
IAP_TRIG = 0xa5; // 触发命令第二步
_nop_(); // 空操作等待
IapIdle();
}
/* 读一个字节 */
uint8 EEPROM_ReadByte(uint16 addr)
{
uint8 dat;
IAP_Wait();
IAP_CMD = 0x01; // 读命令
IAP_ADDRL = addr ;
IAP_ADDRH = addr >> 8;
IAP_TRIG = 0x5A;
IAP_TRIG = 0xA5; // 触发操作
_nop_();
dat = IAP_DATA;
Iapldle(); // 清除命令
return dat;
}
/* 安全存储数值 */
void Save_Stored_Value(uint16 val) {
static uint16 last_saved = 0xFFFF;
// 仅当数值变化时存储
if(val != last_saved) {
EEPROM_EraseSector(STORAGE_SECTOR); // 擦除整个扇区
EEPROM_WriteByte(DATA_ADDR_HIGH, (val >> 8) & 0xFF); // 高字节
EEPROM_WriteByte(DATA_ADDR_LOW,val & 0xFF); // 低字节
last_saved = val; // 更新最近保存值
}
}
uint16 Load_Stored_Value(void) {
uint8 high = EEPROM_ReadByte(DATA_ADDR_HIGH);
uint8 low= EEPROM_ReadByte(DATA_ADDR_LOW);
uint16 val = (high << 8) | low;
// 首次运行检测(全FF则重置为0)
if(val == 0xFFFF) {
val = 0;
Save_Stored_Value(val);
}
return val;
}
/* 显示更新函数 */
void update_display(void) {
uint8 i;
tm1637_start();
tm1637_write(0x40);/* 自动地址增加模式 */
tm1637_ask();
tm1637_stop();
tm1637_start();
tm1637_write(0xC0);/* 起始地址 */
tm1637_ask();
for(i = 0; i < 4; i++) {
if(setting_mode && (i == selected_digit) && blink_state) {
tm1637_write(0x00);/* 闪烁显示 */
tm1637_ask();
} else {
tm1637_write(digit_encode]);
tm1637_ask();
}
}
tm1637_stop();
tm1637_start();
tm1637_write(0x8F);/* 显示开,最大亮度 */
tm1637_ask();
tm1637_stop();
}
/* 改进的按键处理函数 */
void process_keys(void) {
static uint16 key1_timer = 0;
static uint8 key1_last = 1;
static uint8 key2_state = 0;
static uint8 key3_cnt = 0;
// KEY1: 长按/短按
uint8 key_current = KEY1;
if (key_current != key1_last) {
if (!key_current) { // 按下
key1_timer = 0;
} else { // 释放
if (key1_timer >1000) { // 约1秒长按
setting_mode = !setting_mode;
if (setting_mode) {
// 进入设置模式,加载存储值
display_digits = (stored_value / 1000) % 10;
display_digits = (stored_value / 100) % 10;
display_digits = (stored_value / 10) % 10;
display_digits = stored_value % 10;
// EEPROM_WriteByte(0x00, (uint8)(stored_value & 0xFF)); // 低字节
// EEPROM_WriteByte(0x01, (uint8)(stored_value >> 8));
} else {
stored_value = display_digits*1000 + display_digits*100
+ display_digits*10 + display_digits;
}
} else if (key1_timer > 10) { // 约0.1秒短按
if (setting_mode) {
selected_digit = (selected_digit + 1) % 4;
}
}
}
key1_last = key_current;
}
if (!key_current) key1_timer++;
// KEY2: 数值增加
switch (key2_state) {
case 0:
if (!KEY2) {
Delay(10);
key2_state = 1;
}
break;
case 1:
if (!KEY2) {
if (setting_mode) {
display_digits = (display_digits + 1) % 10;
}
key2_state = 2;
} else {
key2_state = 0;
}
break;
case 2:
if (KEY2) key2_state = 0;
break;
}
/* 按键3检测(带防抖) */
if(!KEY3) {
if(++key3_cnt > 3) { // 30ms防抖
key3_cnt = 0;
while(!KEY3); // 等待释放
if(KEY4) {
stored_value++;
} else {
if (stored_value > 0)
{
stored_value--;}
if (!KEY4&& (stored_value == 1)) {
KEY5 = 0; // 设置P1.5为高电平
}
}
Save_Stored_Value(stored_value);
// 更新显示
display_digits = (stored_value / 1000) % 10;
display_digits = (stored_value / 100) % 10;
display_digits = (stored_value / 10) % 10;
display_digits = stored_value % 10;
// EEPROM_EraseSector(0X000) ;
// EEPROM_WriteByte(0x0200, stored_value); // 低字节
// EEPROM_WriteByte(0x0200, (stored_value >> 8)); // 高字节
}
} else {
key3_cnt = 0;
}
}
/* 主函数 */
void main(void) {
P1M0 = 0x00; P1M1 = 0x00;
P3M0 = 0x00; P3M1 = 0x00;
/* 初始化显示 */
display_digits = 0;
display_digits = 1;
display_digits = 2;
display_digits = 3;
while(1) {
static uint16 blink_counter = 0;
process_keys();
update_display();
/* 闪烁控制(约500ms周期) */
if(++blink_counter >= 300)
{
blink_counter = 0;
blink_state = !blink_state;
}
Delay (1);/* 主循环延时 */
}设置eeprom 的那一项也不见 ,不知是不是那设置错误了,放在一运行就复位了
型号选错或者该型号没eeprom吧,或者eeprom固定的 MCU什么型号 {:4_167:}
页:
[1]