求教:32G12K128的EEPROM读写不可靠问题
各位大师,你们好:本人试用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; //打开所有中断
}
请指教
再次感谢
在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读写的可靠性。
示例代码优化
以下是对您提供的代码进行优化的示例:
c
// EEPROM相关定义
define EEPROMoperationAddress 0x0000 // 定义EEPROM所在扇区及初始地址
// 关闭IAP函数
void IapIdle(void)
{
IAPCONTR = 0; // 关闭 IAP 功能
IAPCMD = 0; // 清除命令寄存器
IAPTRIG = 0; // 清除触发寄存器
IAPADDRE = 0xff; // 将地址设置到非 IAP 区域
IAPADDRH = 0xff; // 将地址设置到非 IAP 区域
IAPADDRL = 0xff;
}
// 扇区擦除函数
void EEPROMradDataByteFunction(ulong EEPROMaddress, uchar dataAddress, uchar quantity)
{
EA = 0; // 关闭所有中断
IAPCONTR = 0x80; // 使能 IAP
IAPTPS = mainFosc / 1000000; // 设置等待参数
// 确保地址对齐
if (EEPROMaddress % 512 != 0) {
// 处理地址未对齐的情况
return;
}
// 执行EEPROM操作
// ...
IapIdle(); // 关闭IAP
EA = 1; // 重新开启中断
}
总结
EEPROM读写不可靠问题可能由多种因素引起,包括时钟配置、地址对齐、电源稳定性、中断干扰等。通过仔细检查代码、优化硬件设计、确保电源稳定以及进行充分的测试,可以有效提高EEPROM读写的可靠性。如果问题仍然存在,建议联系芯片厂商获取进一步的技术支持。
希望以上建议对您有所帮助,祝您顺利解决问题!
[本文内容由国芯人工智能辅助生成,仅供参考] 写之前要扇区擦除
页:
[1]