爱点网

I Click Web.Com

52单片机 内部掉电保存 返利代码 可用

STC89C52RC的扇区分布:

/********STC89C52扇区分布*******
第一扇区:2000H–21FF
第二扇区:2200H–23FF
第三扇区:2400H–25FF
第四扇区:2600H–27FF
第五扇区:2800H–29FF
第六扇区:2A00H–2BFF
第七扇区:2C00H–2DFF
第八扇区:2E00H–2FFF
***************************************/

stc89c52rc内部EEPROM操作步骤 下面范例代码中的main.c会有使用举例

1.擦除EEPROM

2.写EEPROM

3.读EEPROM

注意,下方的main.c里面的是我举例的使用方法,按照这种方式就可以使用了。最好不要一直while的去擦除写入,毕竟这个是有读写次数限制的,虽然很大,但是还是不要存在这种的BUG才是合适的程序员。对了,这个mian.c只是举例,并不能拿来使用,你可以加上显示来看效果,但是我能确保,我提供的.c.h是一定可以使用的

为方便使用,我的范例代码是只提供 .h .c ,使用这种方式也方便进行代码替换,使你得主代码区域不会太过于复杂。我只会简单在最后写一个使用的范例,我不会将整个功能的代码放上来,因为你的作品功能只有自己知道,我如果整个实现都写出来,只会误导到你。

如果需要了解如何将.c.h添加进工程 -> 请点击

================eeprom_isp.h ================

/**********************************************
注意事项:

每个地址最多只能存储8字节,如果值超过255,则需要将值拆开

使用范例:

data_high = Tem_H/100;
data_low = Tem_H%100;

Sector_Erase(0x2000);                                       // 擦除单片机内部EEPROM的数据
EEPROM_Write(0x2000, data_high);
EEPROM_Write(0x2001, data_low);

data_high = Tem_L/100;
data_low = Tem_L%100;
EEPROM_Write(0x2002, data_high);
EEPROM_Write(0x2003, data_low);

--------------------------------

data_high = EEPROM_Read(0x2000);                     // 从EEPROM中读取报警值
data_low = EEPROM_Read(0x2001);

Tem_H = (data_high*100)+data_low;


data_high = EEPROM_Read(0x2002);                     // 从EEPROM中读取报警值
data_low = EEPROM_Read(0x2003);

Tem_L = (data_high*100)+data_low;      


**********************************************/
#ifndef _EEPROM_ISP_H
#define _EEPROM_ISP_H

#include <REG52.H>
#include<intrins.h>

sfr ISP_DATA  = 0xe2;                   // 数据寄存器
sfr ISP_ADDRH = 0xe3;                   // 地址寄存器高八位
sfr ISP_ADDRL = 0xe4;                   // 地址寄存器低八位
sfr ISP_CMD   = 0xe5;                   // 命令寄存器
sfr ISP_TRIG  = 0xe6;                   // 命令触发寄存器
sfr ISP_CONTR = 0xe7;                   // 命令寄存器



static void ISP_Disable();
unsigned char EEPROM_Read(unsigned int add);
void EEPROM_Write(unsigned int add, unsigned char ch);
void Sector_Erase(unsigned int add);



#endif

================eeprom_isp.c ================

#include "eeprom_isp.h"



/*********************************************************/
//       单片机内部EEPROM不使能
/*********************************************************/

static void ISP_Disable()
{
    ISP_CONTR = 0;
    ISP_ADDRH = 0;
    ISP_ADDRL = 0;
}

/*********************************************************/
// 从单片机内部EEPROM读一个字节,从0x2000地址开始
/*********************************************************/
unsigned char EEPROM_Read(unsigned int add)
{
    ISP_DATA  = 0x00;
    ISP_CONTR = 0x83;
    ISP_CMD   = 0x01;
    ISP_ADDRH = (unsigned char)(add >> 8);
    ISP_ADDRL = (unsigned char)(add &amp; 0xff);
    // 对STC89C51系列来说,每次要写入0x46,再写入0xB9,ISP/IAP才会生效
    ISP_TRIG  = 0x46;
    ISP_TRIG  = 0xB9;
    _nop_();
    ISP_Disable();
    return (ISP_DATA);
}


/*********************************************************/
// 往单片机内部EEPROM写一个字节,从0x2000地址开始
/*********************************************************/
void EEPROM_Write(unsigned int add, unsigned char ch)
{
    ISP_CONTR = 0x83;
    ISP_CMD   = 0x02;
    ISP_ADDRH = (unsigned char)(add >> 8);
    ISP_ADDRL = (unsigned char)(add &amp; 0xff);
    ISP_DATA  = ch;
    ISP_TRIG  = 0x46;
    ISP_TRIG  = 0xB9;
    _nop_();
    ISP_Disable();
}


/*********************************************************/
// 擦除单片机内部EEPROM的一个扇区
// 写8个扇区中随便一个的地址,便擦除该扇区,写入前要先擦除
/*********************************************************/
void Sector_Erase(unsigned int add)
{
    ISP_CONTR = 0x83;
    ISP_CMD   = 0x03;
    ISP_ADDRH = (unsigned char)(add >> 8);
    ISP_ADDRL = (unsigned char)(add &amp; 0xff);
    ISP_TRIG  = 0x46;
    ISP_TRIG  = 0xB9;
    _nop_();
    ISP_Disable();
}

================main.c ================

#include "reg52.h"
#include "eeprom_isp.h"
/*
因为一个内部地址存储的数据最大就是255了(一个char的大小)
你如果将大于255的数据放进去,就会造成数据丢失
这个一定要注意

另外,在写入数据去保存之前,一定要进行清除那一个扇区的数据
因为他并不是写入,是通过相与的(&amp;)所以写入数据一定要进行清除
他的清除扇区是只一整个扇区并不是单独的一个地址哦
*/

unsigned int Tem_H,Tem_L;//注意这边用的是unsigned int
unsigned char data_high,data_low;//这边用的是unsigned char
void main()
{
data_high = EEPROM_Read(0x2000);                     // 从EEPROM中读取报警值
data_low = EEPROM_Read(0x2001);
Tem_H = (data_high*100)+data_low;

data_high = EEPROM_Read(0x2002);                     // 从EEPROM中读取报警值
data_low = EEPROM_Read(0x2003);
Tem_L = (data_high*100)+data_low;      //这里就是将读取出来的两个数据合并起来,因为原本的数据是int型,大于255了

//另外,在读取出数据后,最好对数据进行判断,例如温度不会大于100度,你可以将读出来的数据判断是否大于100度,大于的话就重新赋值
//另外,第一次读取一般都是错误的数据,你需要进行保存一次后才能正确读取出来。

while(1)
{
Tem_H = 1000;
Tem_L = 2000;
data_high = Tem_H/100;
data_low = Tem_H%100;

Sector_Erase(0x2000);                                       // 擦除单片机内部EEPROM的数据
EEPROM_Write(0x2000, data_high);
EEPROM_Write(0x2001, data_low);

data_high = Tem_L/100;
data_low = Tem_L%100;
EEPROM_Write(0x2002, data_high);
EEPROM_Write(0x2003, data_low);
break;
}

}

点赞

发表评论

电子邮件地址不会被公开。 必填项已用*标注