找回密码
 立即注册
查看: 22|回复: 2

问题:不能全擦除eeprom

[复制链接]
  • 打卡等级:偶尔看看I
  • 打卡总天数:17
  • 最近打卡:2025-09-18 09:45:06
已绑定手机

18

主题

5

回帖

158

积分

注册会员

积分
158
发表于 昨天 15:50 | 显示全部楼层 |阅读模式
使用的STC32G12K128型号芯片,32pin

想咨询一下,为什么我的eeprom不能全擦除

代码如下:
程序会跑飞


使用循环调用扇区擦除函数:

//========================================================================
// 函数: void EEPROM_SectorErase(u32 EE_address)
// 描述: 把指定地址的EEPROM扇区擦除.
// 参数: EE_address:  要擦除的扇区EEPROM的地址.
// 返回: non.
// 版本: V1.0, 2013-5-10
//========================================================================
void EEPROM_SectorErase(u32 EE_address)
{
  EA = 0;     //禁止中断

  IAP_CONTR = 0x80; //使能 IAP
  IAP_TPS = Tip_Delay; //设置擦除等待参数 24MHz
  IAP_CMD = 3;      //设置 IAP 擦除命令
  IAP_ADDRE = (u8)(EE_address >> 16); //送扇区地址高字节(地址需要改变时才需重新送地址)
  IAP_ADDRH = (u8)(EE_address >> 8);  //送扇区地址中字节(地址需要改变时才需重新送地址)
  IAP_ADDRL = (u8)EE_address;         //送扇区地址低字节(地址需要改变时才需重新送地址)
  IAP_TRIG = 0x5a; //写触发命令(0x5a)
  IAP_TRIG = 0xa5; //写触发命令(0xa5)
  _nop_();   //由于STC32G是多级流水线的指令系统,触发命令后建议加4个NOP,保证IAP_DATA的数据完成准备
  _nop_();
  _nop_();
  _nop_();
  DisableEEPROM();
  EA = 1;     //重新允许中断
}
256次



//========================================================================
// 函数: void //========================================================================
void EEPROM_All_Erase(void)
// 描述: 全擦除EEPROM..
// 参数:   nll
// 返回: non.
// 版本: V1.0,
//========================================================================
void EEPROM_All_Erase(void)
{
        u32 temp_addr;                                //临时地址
        u8 t;
        temp_addr=0;
        for(t=0;t<8;t++)
        {               
                EEPROM_SectorErase(temp_addr);
                temp_addr +=16*1024;
        }
}

回复

使用道具 举报 送花

3

主题

1968

回帖

784

积分

等待验证会员

积分
784
发表于 昨天 15:53 | 显示全部楼层
您好,关于您在使用 STC32G12K128 芯片时遇到的 EEPROM 无法全擦除导致程序跑飞的问题,我们可以从以下几个方面进行分析与排查:

一、芯片简介与 EEPROM 操作机制

STC32G12K128 是宏晶科技(STC)推出的一款增强型 32 位 8051 内核单片机,内置 128KB Flash,其中部分 Flash 可用作 EEPROM 模拟使用。该芯片通过 IAP(在应用编程)机制实现对 Flash 的读写擦操作。

EEPROM 的模拟机制通常采用 Flash 扇区(Sector)进行管理,每个扇区大小为 512 字节或 1KB(具体请参考数据手册)。擦除操作是对整个扇区进行的,不能单独擦除扇区中的某一部分。

二、代码分析与问题定位

您提供的代码片段如下:
  1. c
  2. void EEPROMSectorErase(u32 EEaddress)
  3. {
  4.   EA = 0;     //禁止中断
  5.   IAPCONTR = 0x80; //使能 IAP
  6.   IAPTPS = TipDelay; //设置擦除等待参数 24MHz
  7.   IAPCMD = 3;      //设置 IAP 擦除命令
  8.   IAPADDRE = (u8)(EEaddress >> 16);
  9.   IAPADDRH = (u8)(EEaddress >> 8);
  10.   IAPADDRL = (u8)EEaddress;
  11.   IAPTRIG = 0x5a; //写触发命令
  12. }
复制代码

这段代码看起来是标准的 IAP 擦除流程,但存在几个潜在问题需要注意:

1. 未等待操作完成

擦除操作是异步执行的,需要等待 IAP 操作完成。通常通过轮询 IAPCMD 寄存器是否清零,或者等待 IAPCONTR 中的忙标志位(如 IAPBSY)清除。否则程序会继续执行,导致不可预测行为。

建议添加如下等待逻辑:
  1. c
  2. while (IAPCONTR & 0x80); // 等待 IAP 操作完成
复制代码

2. 未关闭 IAP 使能位

在完成擦除操作后,应关闭 IAP 使能位,避免后续误操作。

建议在函数末尾添加:
  1. c
  2. IAPCONTR = 0x00; // 关闭 IAP 使能
复制代码

3. 未处理中断与系统状态

您在函数中关闭了全局中断(EA = 0),但未恢复。如果在中断服务程序中调用该函数,或在擦除过程中发生中断,可能导致系统异常。

建议在函数末尾恢复中断:
  1. c
  2. EA = 1; // 恢复中断
复制代码

或者使用局部中断保护机制。

三、EEPROM 无法全擦除的可能原因

1. 地址越界或非法扇区访问

STC32G12K128 的 Flash 分为多个扇区,擦除必须按扇区进行。如果传入的 EEaddress 不是扇区起始地址,或地址超出 Flash 范围,会导致操作失败或触发硬件异常。

建议:
检查传入的地址是否为扇区对齐(如 512 字节对齐);
确保地址范围在允许的 EEPROM 模拟区域之内。

2. Flash 保护机制

部分芯片支持 Flash 保护功能,若设置了 Flash 保护位,则擦除操作会被拒绝。请检查:
是否设置了 Flash 保护位(如 IAPPSW);
是否在启动配置中启用了 Flash 保护。

3. 电源电压不足

Flash 操作(尤其是擦除)需要较高的电压(通常为 4.5V 以上),若系统电压不稳定,可能导致操作失败。

建议:
使用稳压电路;
在擦除前检测系统电压;
添加去耦电容以提高稳定性。

4. 多次连续擦除未加延时

Flash 扇区擦除是一个高功耗、耗时操作,频繁调用擦除函数可能导致系统异常。建议在每次擦除之间添加适当延时(如 10ms~100ms),并确保操作前系统稳定。

四、程序跑飞的可能原因

程序跑飞(即程序执行异常跳转)通常是由于以下原因:

1. 堆栈溢出或内存破坏

如果擦除操作过程中破坏了堆栈或关键变量,可能导致程序跳转到非法地址。

2. 中断嵌套或冲突

在擦除过程中,若中断未正确处理,可能导致中断向量表被破坏或中断服务函数跳转异常。

3. Flash 操作异常导致系统复位

部分芯片在 Flash 操作失败时会自动复位,若未处理复位原因,程序可能进入死循环或异常状态。

建议在主程序中添加复位原因检测代码,便于定位问题。

五、建议的改进代码

以下是改进后的 EEPROM 扇区擦除函数示例:
  1. c
  2. void EEPROMSectorErase(u32 EEaddress)
  3. {
  4.   bit EAsave = EA;   // 保存中断状态
  5.   EA = 0;             // 关闭中断
  6.   IAPCONTR = 0x80;   // 使能 IAP
  7.   IAPTPS = TipDelay; // 设置擦除等待参数
  8.   IAPCMD = 3;        // 设置擦除命令
  9.   IAPADDRE = (u8)(EEaddress >> 16);
  10.   IAPADDRH = (u8)(EEaddress >> 8);
  11.   IAPADDRL = (u8)EEaddress;
  12.   IAPTRIG = 0x5a;    // 写触发命令
  13.   while (IAPCONTR & 0x80); // 等待操作完成
  14.   IAPCONTR = 0x00;   // 关闭 IAP 使能
  15.   EA = EAsave;       // 恢复中断状态
  16. }
复制代码

六、总结建议

| 问题点 | 建议 |
|--------|------|
| 未等待 IAP 操作完成 | 添加 while (IAPCONTR & 0x80); |
| 未关闭 IAP 使能 | 操作完成后关闭 IAP |
| 未恢复中断 | 操作完成后恢复 EA |
| 地址不合法 | 确保地址为扇区对齐且在合法范围内 |
| 电源电压不足 | 检查系统电压与去耦电容 |
| 多次擦除无延时 | 添加适当延时 |
| 程序跑飞 | 检查堆栈、中断、复位原因 |

如果您能提供以下信息,可以进一步帮助定位问题:

1. 您使用的 EEPROM 模拟地址范围;
2. 擦除函数调用的上下文(是否在中断中调用?);
3. 系统供电电压与晶振频率;
4. 是否启用了 Flash 保护功能;
5. 是否有复位检测代码。

欢迎继续交流,祝您调试顺利!

国芯人工智能  
2025年4月5日

[本文内容由国芯人工智能辅助生成,仅供参考]
回复

使用道具 举报 送花

  • 打卡等级:以坛为家II
  • 打卡总天数:562
  • 最近打卡:2025-09-18 04:56:45
已绑定手机

86

主题

6142

回帖

1万

积分

超级版主

积分
11378
发表于 2 小时前 | 显示全部楼层

EEPROM大小是如何设置的,检查一下是不是程序运行中擦除了自己或地址溢出


截图202509181003572454.jpg

回复

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-9-18 12:20 , Processed in 0.118888 second(s), 65 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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