找回密码
 立即注册
查看: 173|回复: 3

eeprom程序不管用,高手指点一下

[复制链接]
  • 打卡等级:偶尔看看III
  • 打卡总天数:34
  • 最近打卡:2025-03-16 18:14:50

6

主题

6

回帖

228

积分

中级会员

积分
228
发表于 2025-2-18 23:34:10 | 显示全部楼层 |阅读模式
#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[4];      /* 显示缓冲区 */
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[display_digits]);
                        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[0] = (stored_value / 1000) % 10;
                    display_digits[1] = (stored_value / 100) % 10;
                    display_digits[2] = (stored_value / 10) % 10;
                    display_digits[3] = stored_value % 10;
//                                        EEPROM_WriteByte(0x00, (uint8)(stored_value & 0xFF));       // 低字节
//            EEPROM_WriteByte(0x01, (uint8)(stored_value >> 8));
                } else {
                    stored_value = display_digits[0]*1000 + display_digits[1]*100
                                 + display_digits[2]*10 + display_digits[3];
                }
            } 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[selected_digit] = (display_digits[selected_digit] + 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[0] = (stored_value / 1000) % 10;
            display_digits[1] = (stored_value / 100) % 10;
            display_digits[2] = (stored_value / 10) % 10;
            display_digits[3] = 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] = 0;
    display_digits[1] = 1;
    display_digits[2] = 2;
    display_digits[3] = 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);  /* 主循环延时 */
    } 截图202502182333165222.jpg 设置eeprom 的那一项也不见 ,不知是不是那设置错误了,放在一运行就复位了

回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:423
  • 最近打卡:2025-05-02 07:55:56
已绑定手机

19

主题

3190

回帖

4870

积分

论坛元老

积分
4870
发表于 2025-2-18 23:52:05 | 显示全部楼层
型号选错或者该型号没eeprom吧,或者eeprom固定的
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:424
  • 最近打卡:2025-05-02 14:37:11
已绑定手机

77

主题

4846

回帖

8376

积分

超级版主

DebugLab

积分
8376
发表于 2025-2-19 09:09:34 | 显示全部楼层
MCU什么型号
DebugLab
回复 支持 反对

使用道具 举报 送花

  • 打卡等级:常住居民III
  • 打卡总天数:108
  • 最近打卡:2025-04-28 08:34:00
已绑定手机

5

主题

118

回帖

674

积分

高级会员

积分
674
发表于 2025-2-19 09:22:50 | 显示全部楼层
高级软件工程师-唐工
回复

使用道具 举报 送花

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

本版积分规则

QQ|手机版|小黑屋|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

GMT+8, 2025-5-2 15:42 , Processed in 0.151484 second(s), 69 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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