单片机掉电记忆中的一个小细节


前言

最近在写一个用到单片机掉电记忆的程序时,发现每一次记忆的都是0(一个固定的值),原因也找了好久,后来也成功找到了。


一、掉电记忆代码(不好的,有瑕疵的)

  1. 掉电初始化函数:
void LVD_Init()
{
    PCON &= ~(0x20);   //上电后需要清LVD中断标志位
    ELVD = 1; //低压监测中断允许
    PLVD = 1;  //低压中断 优先级高 	
	EA=1;
}

  1. 掉电中断服务函数:
void  LVD_Routine(void) interrupt 6
{
 	uchar i;
   //   断电要执行的操作// 
	IapEraseSector(0x0200);//擦除第二个扇区
	if(LED1 == ON)
	{
		IapProgramByte(0x0200+1,ON);
	}
	else
	{
		IapProgramByte(0x0200+1,OFF);
	}   
    while(PCON & (1<<5))      //检测是否仍然低电压
    {
        PCON = PCON & ~(1<<5);  //低压检测标志清0
        for(i=0; i<200; i++); //延时一下
    }
}

二、问题分析:为什么存储的值是确定的(不是ON就是OFF)

  1. if(LED1 == ON):这一句的作用是判断LED1的状态,如果LED1熄灭就存储OFF,反之存储ON。但是很明显的错误就是断电后,LED1都是熄灭的状态,所以存储的值恒为OFF。
  2. IapEraseSector(0x0200);这一句也有很严重的问题,就是进行eeprom电擦除时是要电的,那么问题来了,单片机掉电后,哪里会有多余的电呢,很容易导致,还没擦除完毕,单片机就完全掉电了,后面的值就来不及存储。

三、问题解决:

  1. 可以用一个标志位跟随LED1,断电后存储这个标志位的值就可以了。
  2. 在单片机通电的时候进行eeprom的擦除。
  3. 加电容,掉电后有做足够的电执信完数据存储。

四、优化后的代码:

void LVD_Init()
{
    PCON &= ~(0x20);   //上电后需要清LVD中断标志位
    ELVD = 1; //低压监测中断允许
    PLVD = 1;  //低压中断 优先级高 	
	EA=1;
	IapEraseSector(0x0200);//擦除第二个扇区
}

void  LVD_Routine(void) interrupt 6
{
 	uchar i;
   //   断电要执行的操作// 
	if(LED1_f == ON)
	{
		IapProgramByte(0x0200+1,ON);
	}
	else
	{
		IapProgramByte(0x0200+1,OFF);
	}   
    while(PCON & (1<<5))      //检测是否仍然低电压
    {
        PCON = PCON & ~(1<<5);  //低压检测标志清0
        for(i=0; i<200; i++); //延时一下
    }
}

总结

发现问题不重要,重要的是寻找解决问题的办法,不要害怕花时间,有一句话说的好:好事多磨。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱学习的喷火龙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值