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

求教:32G12K128的EEPROM读写不可靠问题

[复制链接]
  • 打卡等级:初来乍到
  • 打卡总天数:2
  • 最近打卡:2025-04-22 08:55:10
已绑定手机

1

主题

0

回帖

105

积分

注册会员

积分
105
发表于 2025-4-22 08:55:10 | 显示全部楼层 |阅读模式
各位大师,你们好:
      本人试用32G12K128,EEPROM的读、擦、写,参照了官网提供的代码:(STC32G-DEMO-CODE-V9.6)→(18-通过串口2发送命令读写EEPROM测试程序)→(C语言)→UART-EEPROM.c
      现在的问题是,读写出错率太高,一时不知如何解决,请教各位老师指点,谢谢。
      本人分别编写了三个函数:
      //EEPROM相关定义
#define EEPROMoperationAddress 0x0000                //定义EEPROM所在扇区及初始地址

各函数如下:

关闭IAP函数:
void IapIdle(void)
{
        IAP_CONTR = 0;          //关闭 IAP 功能
    IAP_CMD = 0;            //清除命令寄存器
    IAP_TRIG = 0;           //清除触发寄存器
    IAP_ADDRE = 0xff;       //将地址设置到非 IAP 区域
    IAP_ADDRH = 0xff;       //将地址设置到非 IAP 区域
    IAP_ADDRL = 0xff;
}

扇区擦除函数:
//读取EEPROM,获取量程、波特率、从机地址等数据
void EEPROMradDataByteFunction(ulong EEPROMaddress,uchar *dataAddress,uchar quantity)
{
        EA=0;        //关闭所有中断
        
        IAP_CONTR = 0x80; //使能 IAP
    IAP_TPS = mainFosc/1000000;        //设置等待参数22.1184MHz
    IAP_CMD = 1;  //设置 IAP 读命令
        do
        {
                IAP_ADDRE = (uchar)(EEPROMaddress >> 16); //送地址高字节(地址需要改变时才需重新送地址)
        IAP_ADDRH = (uchar)(EEPROMaddress >> 8);  //送地址中字节(地址需要改变时才需重新送地址)
        IAP_ADDRL = (uchar)EEPROMaddress;         //送地址低字节(地址需要改变时才需重新送地址)
        IAP_TRIG = 0x5a; //写触发命令(0x5a)
        IAP_TRIG = 0xa5; //写触发命令(0xa5)
        _nop_();   //由于STC32G是多级流水线的指令系统,触发命令后建议加4个NOP,保证IAP_DATA的数据完成准备
        _nop_();
                _nop_();
                _nop_();
                _nop_();
                *dataAddress = IAP_DATA; //读 IAP 数据
        EEPROMaddress++;
        dataAddress++;
        }while(--quantity);
        IapIdle();        //关闭IAP功能
        
        EA=1;        //打开所有中断
}

多字节读函数:
void EEPROMradDataByteFunction(ulong EEPROMaddress,uchar *dataAddress,uchar quantity)
{
        EA=0;        //关闭所有中断
        
        IAP_CONTR = 0x80; //使能 IAP
    IAP_TPS = mainFosc/1000000;        //设置等待参数22.1184MHz
    IAP_CMD = 1;  //设置 IAP 读命令
        do
        {
                IAP_ADDRE = (uchar)(EEPROMaddress >> 16); //送地址高字节(地址需要改变时才需重新送地址)
        IAP_ADDRH = (uchar)(EEPROMaddress >> 8);  //送地址中字节(地址需要改变时才需重新送地址)
        IAP_ADDRL = (uchar)EEPROMaddress;         //送地址低字节(地址需要改变时才需重新送地址)
        IAP_TRIG = 0x5a; //写触发命令(0x5a)
        IAP_TRIG = 0xa5; //写触发命令(0xa5)
        _nop_();   //由于STC32G是多级流水线的指令系统,触发命令后建议加4个NOP,保证IAP_DATA的数据完成准备
        _nop_();
                _nop_();
                _nop_();
                _nop_();
                *dataAddress = IAP_DATA; //读 IAP 数据
        EEPROMaddress++;
        dataAddress++;
        }while(--quantity);
        IapIdle();        //关闭IAP功能
        
        EA=1;        //打开所有中断
}

多字节写函数:
/*在写数据之前按照PDF推荐,先将EEPROM内的16个数据读出到EEPROMarray数组,然后擦除,最后再将EEPROM数组的数据写回EEPROM中,重新读取EEPROM的16个数据,存放到anotherArray数组中,以判断是否读写成功,出错概率很大*/
void EEPROMwriteAnyByte(ulong EEPROMaddress,uchar dataAddress[],uchar quantity)
{
        uchar i=0;
        EA=0;        //关闭所有中断
        
        IAP_CONTR = 0x80; //使能 IAP
    IAP_TPS = mainFosc/1000000;        //设置等待参数22.1184MHz
    IAP_CMD = 2;  //设置 IAP 写命令
        do
        {
                IAP_ADDRE = (uchar)(EEPROMaddress >> 16); //送地址高字节(地址需要改变时才需重新送地址)
        IAP_ADDRH = (uchar)(EEPROMaddress >> 8);  //送地址中字节(地址需要改变时才需重新送地址)
        IAP_ADDRL = (uchar)EEPROMaddress;         //送地址低字节(地址需要改变时才需重新送地址)
        //IAP_DATA = *dataAddress;         //写 IAP 数据
                IAP_DATA = dataAddress;         //写 IAP 数据
        IAP_TRIG = 0x5a; //写触发命令(0x5a)
        IAP_TRIG = 0xa5; //写触发命令(0xa5)
        _nop_();   //由于STC32G是多级流水线的指令系统,触发命令后建议加4个NOP,保证IAP_DATA的数据完成准备
        _nop_();
                _nop_();
                _nop_();
                _nop_();
        EEPROMaddress++;
        dataAddress++;
                i++;
        }while(--quantity);
        IapIdle();        //关闭IAP功能
        
        EA=1;        //打开所有中断
}

请指教
再次感谢

      
回复

使用道具 举报 送花

3

主题

1160

回帖

1031

积分

等待验证会员

积分
1031
发表于 2025-4-22 08:58:00 | 显示全部楼层
在STC32G12K128的EEPROM读写过程中,出现高错误率的问题可能涉及多个方面。以下是一些可能的原因及解决方案,供您参考:

1. 时钟配置与等待时间
问题分析:EEPROM操作需要特定的时钟频率和等待时间。如果时钟配置不当或等待时间不足,可能导致读写操作失败。
解决方案:确保IAPTPS寄存器正确配置,以匹配主时钟频率。IAPTPS的计算公式为:IAPTPS = mainFosc / 1000000。例如,如果主时钟频率为12MHz,则IAPTPS应设置为12。此外,确保在EEPROM操作后留有足够的等待时间。

2. 地址对齐与边界检查
问题分析:EEPROM操作通常要求地址对齐,且不能跨越扇区边界。如果地址未对齐或操作跨越了扇区边界,可能导致读写错误。
解决方案:确保操作地址正确对齐,并检查操作范围是否在单个扇区内。例如,STC32G12K128的EEPROM扇区大小为512字节,确保操作地址和长度不跨越扇区边界。

3. 电源稳定性
问题分析:EEPROM操作对电源稳定性要求较高。如果电源波动较大,可能导致读写错误。
解决方案:确保电源稳定,避免在电源波动较大的情况下进行EEPROM操作。可以考虑增加电源滤波电容或使用稳压电源。

4. 中断干扰
问题分析:在EEPROM操作过程中,如果中断未被正确关闭,可能导致操作被中断,从而引发错误。
解决方案:在EEPROM操作前关闭所有中断(如您代码中的EA=0),并在操作完成后重新开启中断。

5. EEPROM寿命与磨损均衡
问题分析:EEPROM有有限的擦写次数,频繁的擦写操作可能导致某些扇区失效。
解决方案:尽量减少EEPROM的擦写次数,采用磨损均衡算法,将数据分散到不同的扇区中。

6. 代码优化与调试
问题分析:代码实现可能存在潜在问题,如未正确设置寄存器或操作顺序不当。
解决方案:仔细检查代码,确保所有寄存器设置正确,操作顺序符合数据手册要求。可以通过调试工具逐步检查每一步操作的结果。

7. 硬件连接与PCB设计
问题分析:硬件连接不良或PCB设计不当可能导致信号干扰,影响EEPROM操作。
解决方案:检查硬件连接,确保EEPROM相关引脚连接正确。优化PCB设计,减少信号干扰。

8. 固件版本与数据手册
问题分析:固件版本可能存在已知问题,或数据手册中的信息不准确。
解决方案:确保使用最新的固件版本,并参考最新的数据手册。如有必要,联系芯片厂商获取技术支持。

9. 环境因素
问题分析:极端温度或湿度可能影响EEPROM的可靠性。
解决方案:确保工作环境在芯片规定的温度范围内,避免在极端环境下进行EEPROM操作。

10. 测试与验证
问题分析:未进行充分的测试与验证,可能导致问题未被及时发现。
解决方案:编写全面的测试程序,覆盖各种可能的操作场景,确保EEPROM读写的可靠性。

示例代码优化
以下是对您提供的代码进行优化的示例:
  1. c
  2. // EEPROM相关定义
  3. define EEPROMoperationAddress 0x0000 // 定义EEPROM所在扇区及初始地址
  4. // 关闭IAP函数
  5. void IapIdle(void)
  6. {
  7.     IAPCONTR = 0;          // 关闭 IAP 功能
  8.     IAPCMD = 0;            // 清除命令寄存器
  9.     IAPTRIG = 0;           // 清除触发寄存器
  10.     IAPADDRE = 0xff;       // 将地址设置到非 IAP 区域
  11.     IAPADDRH = 0xff;       // 将地址设置到非 IAP 区域
  12.     IAPADDRL = 0xff;
  13. }
  14. // 扇区擦除函数
  15. void EEPROMradDataByteFunction(ulong EEPROMaddress, uchar dataAddress, uchar quantity)
  16. {
  17.     EA = 0; // 关闭所有中断
  18.     IAPCONTR = 0x80; // 使能 IAP
  19.     IAPTPS = mainFosc / 1000000; // 设置等待参数
  20.     // 确保地址对齐
  21.     if (EEPROMaddress % 512 != 0) {
  22.         // 处理地址未对齐的情况
  23.         return;
  24.     }
  25.     // 执行EEPROM操作
  26.     // ...
  27.     IapIdle(); // 关闭IAP
  28.     EA = 1; // 重新开启中断
  29. }
复制代码

总结
EEPROM读写不可靠问题可能由多种因素引起,包括时钟配置、地址对齐、电源稳定性、中断干扰等。通过仔细检查代码、优化硬件设计、确保电源稳定以及进行充分的测试,可以有效提高EEPROM读写的可靠性。如果问题仍然存在,建议联系芯片厂商获取进一步的技术支持。

希望以上建议对您有所帮助,祝您顺利解决问题!

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

使用道具 举报 送花

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

76

主题

4833

回帖

8343

积分

超级版主

DebugLab

积分
8343
发表于 2025-4-22 09:36:16 | 显示全部楼层
写之前要扇区擦除
DebugLab
回复 支持 反对

使用道具 举报 送花

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

本版积分规则

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

GMT+8, 2025-5-1 19:46 , Processed in 0.133258 second(s), 57 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

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