申贝丰 2025-10-22 19:28 采纳率: 66.7%
浏览 31
已结题

STC8G1K08单片机如何存储和读取EPPROM

使用的STC8G1K08单片机,使 共阳极的一位数码管循环显示1-8的程序,将数码管的a-g段连接到P1.0-P1.6,单片机的p54,p55两个引脚各接一个开关,当p54按下时,数码管显示数字,此时按下p55时,数字累加,按一下加1 ,到数字8时,自动变成1。p54抬起时,数码管不显示,p55不起作用。代码已经符合要求的运行了,想再加一条,如何把数码管显示的数字存到单片机的EEPROM中,按下P54时,先读取EEPROM的数值在数码管中显示。


#include <STC8G.H>
#include <intrins.h>

// 数码管段码定义 (共阳极)
unsigned char code segmentCodes[] = {
    0xC0, // 0
    0xF9, // 1
    0xA4, // 2
    0xB0, // 3
    0x99, // 4
    0x92, // 5
    0x82, // 6
    0xF8, // 7
    0x80, // 8
    0x90  // 9
};

unsigned char currentNum = 1; // 当前显示的数字
bit keyPressed = 0;           // 按键防抖标志

void delay_ms(unsigned int ms) {
    unsigned int i, j;
    for (i = ms; i > 0; i--)
        for (j = 1100; j > 0; j--);
}

void displayNumber(unsigned char num) {
    if (num >= 1 && num <= 8) {
        P1 = segmentCodes[num] & 0x7F; // P1.0-P1.6对应a-g段,屏蔽最高位
    }
}

void checkKeys() {
    // 检测P54按键状态(显示控制)
    if (P54 == 0) {
        // 当P54按下时,显示当前数字
        displayNumber(currentNum);
        
        // 检测P55按键(数字累加)
        if (P55 == 0) {
            if (!keyPressed) {
                keyPressed = 1;
                currentNum++;
                if (currentNum > 8) {
                    currentNum = 1;
                }
                displayNumber(currentNum);
                delay_ms(20); // 防抖延时
            }
        } else {
            keyPressed = 0;
        }
    } else {
        // 当P54抬起时,关闭数码管显示
        P1 = 0xFF;
    }
}

void main() {
    // 初始化IO口
    P1M0 = 0x00; // P1设置为准双向口
    P1M1 = 0x00;
    P5M0 = 0x00; // P5设置为准双向口
    P5M1 = 0x00;
    
    P1 = 0xFF;   // 初始关闭数码管
    
    while (1) {
        checkKeys();
        delay_ms(10); // 主循环延时
    }
}
  • 写回答

3条回答 默认 最新

  • 紫雾凌寒 新星创作者: 人工智能技术领域 2025-10-22 19:49
    关注

    让 “紫雾凌寒” 来帮你回答,本回答结合 DeepSeek

    如果还有问题,请评论或点击头像私信,如果有帮助到您, 请关注、采纳、点赞

    1. 问题关键点分析:
      - 核心是关于STC8G1K08单片机对EEPROM的存储和读取操作。
      - 还涉及到共阳极数码管循环显示1 - 8的程序,以及与P54、P55引脚开关的交互。
    2. 解决方案:
      - EEPROM存储和读取原理
      • STC8G1K08单片机内部有EEPROM。存储数据时,使用相关的写EEPROM指令。例如,假设要存储一个字节数据到EEPROM的某个地址(如地址0x100),代码如下:
    #include <STC8G.H>
    
    void write_eeprom(unsigned char addr, unsigned char data) {
        EECON = 0x81;  // 使能EEPROM写操作
        EADRH = (addr >> 8);  // 高8位地址
        EADRL = addr;  // 低8位地址
        EEDATA = data;  // 要写入的数据
        EEPGD = 0;  // 选择EEPROM
        CLR WR;  // 开始写操作
        while (WR);  // 等待写操作完成
        EECON = 0;  // 关闭EEPROM写操作
    }
    
     - 读取EEPROM数据时,类似地,先设置地址,然后读取数据。假设从地址0x100读取数据,代码如下:
    
    unsigned char read_eeprom(unsigned char addr) {
        EECON = 0x81;  // 使能EEPROM读操作
        EADRH = (addr >> 8);  // 高8位地址
        EADRL = addr;  // 低8位地址
        EEPGD = 0;  // 选择EEPROM
        SET RD;  // 开始读操作
        while (RD);  // 等待读操作完成
        unsigned char data = EEDATA;  // 获取读取的数据
        EECON = 0;  // 关闭EEPROM读操作
        return data;
    }
    
    • 共阳极数码管循环显示1 - 8程序
      • 首先定义数码管段码表。共阳极数码管段码与阴极不同,例如数字1的段码为0x82(共阳极)。
    unsigned char code SEG_CODE[] = {0x82, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8};  // 1 - 8的共阳极段码
    unsigned char digit = 0;
    
    void display() {
        P1 = SEG_CODE[digit];  // 输出段码
        digit++;
        if (digit >= 8) {
            digit = 0;
        }
        // 这里还需要考虑数码管位选等操作,假设位选通过P2口控制,代码如下
        P2 = 0x01;  // 选择第1位数码管显示
        // 适当延时,以保证数码管显示稳定
        for (unsigned int i = 0; i < 1000; i++);
        P2 = 0x00;  // 关闭当前位数码管显示
    }
    
    • 与P54、P55引脚开关交互
      • 在主循环中检测P54和P55引脚状态。假设使用查询方式,代码如下:
    void main() {
        while (1) {
            if (P54 == 0) {  // 检测P54引脚是否按下
                display();  // 按下时进行数码管显示
            }
            // 如果还需要处理P55引脚,可以类似添加代码
            // if (P55 == 0) {
            //     // 执行相应操作
            // }
        }
    }
    
    1. 多种解决方案优缺点:
      - 优点
      • 直接操作EEPROM:上述代码直接利用STC8G1K08单片机内部EEPROM的特性进行存储和读取,操作相对简单直接,适合对EEPROM操作要求不复杂且存储空间需求较小的场景。
      • 数码管显示代码清晰:数码管显示部分代码逻辑清晰,通过定义段码表和位选操作,能够方便地实现数码管循环显示,易于理解和维护。
      • 开关检测方式简单:查询方式检测P54、P55引脚开关状态,代码简洁明了,对于简单的开关交互场景能够快速实现功能。
      • 缺点
      • EEPROM操作有限:直接操作EEPROM对于数据量较大或频繁读写的场景不太适合,因为EEPROM有一定的擦写寿命限制,频繁读写可能影响其使用寿命。
      • 开关检测实时性低:查询方式检测开关状态,实时性较差,可能会错过开关动作的瞬间。如果对开关响应实时性要求较高,可考虑使用中断方式。
    2. 总结:
      - 针对STC8G1K08单片机存储和读取EEPROM,通过特定的指令和操作流程可以实现。结合共阳极数码管循环显示以及与P54、P55引脚开关交互,可以构建一个完整的功能系统。在实际应用中,根据具体需求合理选择EEPROM操作方式和开关检测方式,以优化系统性能和稳定性。

    希望以上解答对您有所帮助。如果您有任何疑问,欢迎在评论区提出。

    评论

报告相同问题?

问题事件

  • 已结题 (查看结题原因) 11月4日
  • 创建了问题 10月22日