STC的EEPROM掉电会丢数据,一部分芯片
如题,我去年用stc做了个小东西,用到了EEPROM,后来我选了个STC8G2K64S4打算替代,结果问题来了,设置完参数掉电就没了?命名设置完参数我还读出校验的,没设置进去,那是要返回设置失败的,但是设置的时候返回都成功。我觉得是不是这个地方的EEPROM坏了,然后换了几个位置都一样。
换了个没上过电的样品测试,一样保存不下来。
后来单独写了个小程序,如果能保存,第二次以后上电,都会闪几下灯,测试了两个样品,无论多少次,灯都不闪,然后把第二个样品换了个芯片,居然,灯闪了,真是郁闷。
#include "stc8g.h"
#include "intrins.h"
//#include <eepromx.h>
//#include "task_mange.h"
sbit run_led = P3^6;
unsigned char code test1[]={0x11,0x22,0x33,0x44};
unsigned char test2;
#define WT_30M 0x80
//#define WT_24M 0x81
//#define WT_20M 0x82
//#define WT_12M 0x83
//#define WT_6M 0x84
//#define WT_3M 0x85
//#define WT_2M 0x86
//#define WT_1M 0x87
#define IAP_OFFSET 0X8000
#define test_addr 0X800
#define RUN_LED_ON() run_led=0
#define RUN_LED_OFF() run_led=1
void Delay100ms() //@33.1776MHz
{
unsigned char i, j, k;
_nop_();
i = 17;
j = 213;
k = 185;
do
{
do
{
while (--k);
} while (--j);
} while (--i);
}
void IapIdle()
{
IAP_CONTR = 0; //关闭IAP功能
IAP_CMD = 0; //清除命令寄存器
IAP_TRIG = 0; //清除触发寄存器
IAP_ADDRH = 0x80; //将地址设置到非IAP区域
IAP_ADDRL = 0;
}
char IapRead(int addr)
{
char dat;
IAP_CONTR = WT_30M; //使能IAP
IAP_TPS = 33;
IAP_CMD = 1; //设置IAP读命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
dat = IAP_DATA; //读IAP数据
IapIdle(); //关闭IAP功能
return dat;
}
void IapProgram(int addr, char dat)
{
IAP_CONTR = WT_30M; //使能IAP
IAP_TPS = 33;
IAP_CMD = 2; //设置IAP写命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写IAP数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
IapIdle(); //关闭IAP功能
}
void IapErase(int addr)
{
IAP_CONTR = WT_30M; //使能IAP
IAP_TPS = 33;
IAP_CMD = 3; //设置IAP擦除命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_(); //
IapIdle(); //关闭IAP功能
}
//char eeprom_read(unsigned int addr)
//{
// addr+=IAP_OFFSET;
// return *(char code *)(addr);
//}
//读取多个EEPROM地址 ,返回值为CRC 校验码
void eeprom_read_buf(int addr,char *buf,char bflong)
{
// char xj;
// int crc=0;
// int crc2=0;
char i=0;
for(i=0;i<bflong;i++)
{
//IapProgram(addr+i, buf);
buf=IapRead(addr+i); //eeprom_read(addr+i);
}
// crc=eeprom_read(addr+i);
// //crc=xj;
// crc=crc<<8;
// i++ ;
// crc2=eeprom_read(addr+i); //注意
// crc=crc+(crc2&0x00ff);
// return (crc);
}
//写多个EEPROM地址
void IapProgram_buf(int addr,char *buf,char bflong)
{
char i=0;
// int crcx;
char mid;
// crc
IapErase(addr); // 先擦除EEPROM对应的块
// crcx = crc16_modbus(buf, bflong) ;
for(i=0;i<bflong;i++)
{
mid=buf;
IapProgram(addr+i, buf);
}
// IapProgram(addr+i, (crcx>>8)); //写入CRC
//
// i++;
// IapProgram(addr+i, crcx);
}
//--------------------------------------------
void test_eeprom()
{
IapErase(test_addr);
IapProgram_buf(test_addr,test1,4);
//IapProgram_buf(test_addr,test1,4);
eeprom_read_buf(test_addr,test2,4);
_nop_();
}
void testread()
{
eeprom_read_buf(test_addr,test2,4);
_nop_();
}
void main(void)
{
unsigned char xi1;
P3M0|=0X60;
P3M1&=0X9F;
testread();
for(xi1=0;xi1<20;xi1++)
{
if(test2==0x11)
{
_nop_();
RUN_LED_ON() ;
Delay100ms();
Delay100ms();
Delay100ms();
Delay100ms();
RUN_LED_OFF() ;
Delay100ms();
Delay100ms();
Delay100ms();
Delay100ms();
}
}
test_eeprom();
while(1)
{
_nop_();
}
}
这个是程序存储器里分出来的。我只是担心,是否程序存储器会丢失? wqsjob 发表于 2020-9-4 21:27
这个是程序存储器里分出来的。我只是担心,是否程序存储器会丢失?
程序也会丢的,亲身经历 {:lol:}
不过当时是我逻辑没写好 , 在掉电后去操作了 EEPROM , 导致有概率丢程序。后来改掉那个BUG后就好了 huangyiting1990 发表于 2020-9-4 21:44
程序也会丢的,亲身经历
不过当时是我逻辑没写好 , 在掉电后去操作了 EEPROM , 导致有概 ...
所以还是要开低电压复位啊。不过stc待机功耗还是要大不少,没有stm32l0省电。 wye11083 发表于 2020-9-4 22:53
所以还是要开低电压复位啊。不过stc待机功耗还是要大不少,没有stm32l0省电。 ...
低电压复位解决不了问题吧,要做掉电检测+大电容才能解决问题 操作flash之前,我都是先判断有没有低压标志,电压正常再操作,基本就没有出问题了 要不就写两份,每份都加校验码一起写进去
两份不要同时写,隔个几秒,
这样能保证掉电时只会写坏一份,因为有校验码,所以肯定知道哪一份是好的 重要场合关键参数还是外置eep芯片安全 可靠内部flash从当年的PIC到现在的MCU标配 都一样性格异变不可捉摸{:lol:} hefq 发表于 2020-9-4 23:57
要不就写两份,每份都加校验码一起写进去
两份不要同时写,隔个几秒,
这样能保证掉电时只会写坏一份,因为 ...
我怀疑你只看了标题,但是我没证据{:lol:}
是整个都坏了。
只是存储配置数据,也许一辈子就写那么一次.原来我程序里读用的并不是IAP读,而是MOVC读,上边贴出来的有这段子程序,只是我现在测试的时候用了IAP的读.
还有,不牵涉到掉电的时候保存数据,不存在掉电的时候破坏EEPROM数据.
我思考了一夜,大概理出来一个思路,坏的原因应该如下:
以下子程序里,IAP_TPS = 33;这一行是后来加的,在老的芯片里根本没有这个配置,也就是在去年的芯片里,这个是在IAP_CONTR 里配置的.
void IapProgram(int addr, char dat)
{
IAP_CONTR = WT_30M; //使能IAP
IAP_TPS = 33;
IAP_CMD = 2; //设置IAP写命令
IAP_ADDRL = addr; //设置IAP低地址
IAP_ADDRH = addr >> 8; //设置IAP高地址
IAP_DATA = dat; //写IAP数据
IAP_TRIG = 0x5a; //写触发命令(0x5a)
IAP_TRIG = 0xa5; //写触发命令(0xa5)
_nop_();
IapIdle(); //关闭IAP功能
}
1.开始两个样片都是上电,烧老程序.然后测试发现没法设置,返回设置不成功.
2.然后我将其中一个配置成仿真模式,看看什么问题,结果发现写的时候死在那里了,然后我就纳闷,去年好好的程序,写EEPROM死了?
3. 查数据手册,发现新版的多了个以上这么个东西,然后把这句话加进去.果然解决了问题.设置也成功了.
4.忙其他事情几天,才回来弄这件小事,不过说实话,研发无小事啊.结果头大了,每次上电,都恢复到默认的参数了,配置的都保存不下来.
5. 我当时想,是不是老程序把eeprom的这个部分写坏了,我换个地址.然后换了地址也是一样现象,设置成功,但是停电了,数据就没了.这是最坑的地方,写进去,读出来比较,和写进去的一样.但是一停电就没了,这是把EEPROM直接升级成SRAM了啊?RAM不是比EEPROM贵吗?
6.开始我是想换个芯片,但想想两块都是这样,可能性太小了.并且老电工了,也懒的动手,把去年写的程序扒出来一点点查,查了一天,总算把程序又看懂了,我写这部分程序的时候可是才用了半天时间,检查都用了一天。可是程序没发现什么问题.
7.其中一块换了芯片,上测试程序,OK.上正常程序,OK.
也就是,老程序就写了EEPROM其中的某一个地方,我一次配置数据有4个区域,相当于测试那么长时间,写了几百次,把整块EEPROM都干死了?
还有就是,出了这个问题,老板看我的眼神都不对,和我说,这么低级的问题,你竟然搞了两次,前后弄了两三天?
wqsjob 发表于 2020-9-5 09:05
我怀疑你只看了标题,但是我没证据
是整个都坏了。
只是存储配置数据,也许一辈子就写那么一次. ...
我是回的另一个人的贴子,你的这种情况就是坏了,没救了{:lol:} 这种问题碰到多了,特别是外部强干扰的时候更容易出问题。就是Flash的EEprom数据丢失,再不敢用STC内部的EEprom了,正常使用压根用不到写,甚至把写功能屏蔽掉了,使用过程中还是一样丢过一部分数据。今后不敢再用了,外部EEprom走起。。。 gylg3344love 发表于 2020-9-27 11:07
这种问题碰到多了,特别是外部强干扰的时候更容易出问题。就是Flash的EEprom数据丢失,再不敢用STC内部的EE ...
是的,我这个产品就是安装的时候,设置一下服务器的IP地址之类的参数,之后就不会再写了。
wye11083 发表于 2020-9-4 22:53
所以还是要开低电压复位啊。不过stc待机功耗还是要大不少,没有stm32l0省电。 ...
STC8G系列的,Power Down模式0.4uA。 擦除、写入EEPROM时,多设置一些条件吧,比如我常用一个4字节的PASSWORD。STC的EEPROM是从FLASH中分出来的,按理不应该容易掉的,反正从2003年用STC到现在,我基本没碰到掉EEPROM数据的。如果EEPROM容易掉,同理程序也应该容易掉,但是实际上程序却又很少会掉,所以基本跟操作有关的,或者电源或IO有高压尖峰(超过6V就算)冲击IC。我一般开发产品时,都会做几十上百个样机做220V上电、断电实现,开4秒关4秒,24小时超过1万次的开关电,看是否有任何异样。 我有个小产品正在上,看来的得注意下这问题了! 但还是有点堵的赶脚 小李非刀 发表于 2020-9-27 16:19
STC8G系列的,Power Down模式0.4uA。
stm32l0是4ua。。 碰到过 eeprom读出来变成255了。 EEPROM 操作所需时间是硬件自动控制的,用户只需要正确设置 IAP_TPS 寄存器即可。
IAP_TPS=系统工作频率/1000000(小数部分四舍五入进行取整)
例如: 系统工作频率为 12MHz,则 IAP_TPS 设置为 12;
你的系统工作频率为30MHz???则 IAP_TPS 设置为30,而你套用了33 ??? 导致操作时间不能保证哦 gylg3344love 发表于 2020-9-27 11:07
这种问题碰到多了,特别是外部强干扰的时候更容易出问题。就是Flash的EEprom数据丢失,再不敢用STC内部的EE ...
(引用自11楼)
为何外部就一定稳定 lb0857 发表于 2020-9-5 07:57
重要场合关键参数还是外置eep芯片安全 可靠内部flash从当年的PIC到现在的MCU标配 都一样性格异变 ...
(引用自8楼)
为何外部的稳定 akey3000 发表于 2022-7-3 15:51
为何外部的稳定
(引用自21楼)
内部时钟一般是RC振荡电路,会收到温漂的影响,不过在他们的销售强推下,实测STC15系列的比早期的老型号确实是好了很多。要求高的话可以外部时钟,时钟精准
页:
[1]