STC89C52自带的EEPROM是否只能按扇区整体擦,能否按字节擦?

STC89C52自带的EEPROM是否只能按扇区整体擦,能否按字节擦?,第1张

不要被宣传用语欺骗了……
STC89C52并没有内置的EEPROM,它是把内部的Flash分出一小块来单独给用户使用。作为Flash来讲 *** 作都是标准的,擦除 *** 作只能针对扇区进行,一个扇区512字节。
不过,实际在使用中你可以根据Flash的特性(可以把“1”写成“0”,但“0”不可以恢复成“1”,只有擦除 *** 作才能把扇区变成全“1”),合理规划自己的数据结构,线性地写零存储数据;此外应当把一个扇区的512字节尽量全都用满,减少擦除次数。

那是肯定可以随便擦写的啊,还用问么,EEPROM本来就是给单片机掉电后程序运行需要保存的数据,你设置一个值后写入EEPROM,你把电关掉,下次再开机就读EEPROM这个值出来就行了。EEPROM可以拼命的读,但不能拼命的写,它的写寿命次数只有100000次,读是无限次的。EEPROM不像RAM那样读写那么简单,EEPROM是掉电后数据不变,RAM掉电后数据没了,因为EEPROM擦写是次数限制的,而且保存的都是重要数据,不可以像RAM那样简单的写入,防止程序跑飞误修改里面的数据,所以要擦写都要执行规定的流程才能读写,具体怎么做你仔细看它的数据手册,有说明的,还有读写程序范例。搞单片机,第一要点就是仔细再仔细的看数据手册,否则你什么也不用干了。有一部分的单片机它的程序存储器(Flash)都可以擦写和读取呢。

看单片机PDF,STC的写之前一定要擦除,因为要为空时才可对其编程,写(因为只有扇区擦除才能把0变为1,若这个扇区原本有0的话你不擦出就不是覆盖了而是混乱!!!)。一个扇区可以写很多数据的,但是在每写一个数据之前要把其他的数据都先读出来保存一份到RAM,(定义几个变量,比如,a=eeprom_read(0x4000); b=eeprom_read(0x4001))读出来后执行 eeprom_eares(0x4000);也就是擦除这个扇区,等擦除 *** 作执行完后和新数据一起写入这个扇区,如下:\x0d\eeprom_write(0x4000,a);//读出来的数据写回去\x0d\eeprom_write(0x4001,b);\x0d\eeprom_write(0x4002,c);\x0d\这样c就和a,b一起写到这个扇区了,写a的时候同样要把b,c读出来,写b的时候要把a,c读出来。\x0d\很多单片机有64个扇区,够用的话尽量一个扇区写一个数据,这样程序写起来比较方便,\x0d\其他类型的单片机没试验不知道,外部eeprom情况又不一样

与单片机有关。
比如STC的单片机,在向片内EEPROM写入数据前必须执行擦除 *** 作,并且擦除是按照扇区进行的,并不能逐字节进行。
而STM8单片机,在向片内EEPROM写入数据时不需要用户在程序中进行擦除,单片机会自动擦除对应字节的数据。

/
名称:FlashRead
功能:读取程序存储器一个字
参数:addr -> 程序存储器字地址
返回:读取到的存储器值
/
uint16 FlashReadWord(uint16 addr)
{
EEADRL = ((addr) & 0x00ff);
EEADRH = ((addr) >> 8);
CFGS = 0; //访问程序存储器or数据EEPROM
LWLO = 0; //仅装载写锁存器位
EEPGD = 1; //访问程序存储器
RD = 1; //启动对程序存储器or数据EEPROM的读 *** 作,读 *** 作占用一个周期,由硬件清零
asm("NOP");
asm("NOP");
return ((EEDATH)<<8 | (EEDATL));
}
/
名称:FlashWriteWord
功能:编程程序存储器一个字
参数:addr -> 程序存储器字地址
dat -> 要编程的值
返回:无
/
void FlashWriteWord(uint16 addr,uint16 dat)
{
uint16 value;
EECON1 = 0;
EEADRL = ((addr) & 0xff);
EEADRH = ((addr) >> 8);
value = dat & 0x3fff;
EEDATH = ((value) >> 8);
EEDATL = ((value) & 0xff);
EEPGD = 1; //访问程序存储器
CFGS = 0; //访问程序存储器or数据EEPROM
WREN = 1; //使能编程/擦除 *** 作
LWLO = 0; //加载到程序存储锁存器,并编程到程序存储器
EECON2 = 0x55; //必须的解锁序列
EECON2 = 0xAA; //必须的解锁序列
WR = 1; //启动编程 *** 作
asm("NOP");
asm("NOP");
WREN = 0; //禁止编程/擦除 *** 作
}
/
名称:FlashWriteLine
功能:编程程序存储器一行(32字)
参数:addr -> 程序存储器行地址
dat -> 要编程的值
返回:无
/
void FlashWriteLine(uint16 addr,uint16 dat)
{
uint8 i;
uint16 value;
EECON1 = 0;
EEADRL = ((addr) & 0xff);
EEADRH = ((addr) >> 8);
for(i=0;i<31;i++)
{
value = dat[i] & 0x3fff;
EEDATH = ((value) >> 8);
EEDATL = ((value) & 0xff);
EEPGD = 1; //访问程序存储器
CFGS = 0; //访问程序存储器or数据EEPROM
WREN = 1; //使能编程/擦除 *** 作
LWLO = 1; //只加载到程序存储锁存器
EECON2 = 0x55; //必须的解锁序列
EECON2 = 0xAA; //必须的解锁序列
WR = 1; //启动编程 *** 作
asm("NOP");
asm("NOP");
EEADR++;
}
value = dat[31] & 0x3fff;
EEDATH = ((value) >> 8);
EEDATL = ((value) & 0xff);
EEPGD = 1; //访问程序存储器
CFGS = 0; //访问程序存储器or数据EEPROM
WREN = 1; //使能编程/擦除 *** 作
LWLO = 0; //加载到程序存储锁存器,并编程到程序存储器
EECON2 = 0x55; //必须的解锁序列
EECON2 = 0xAA; //必须的解锁序列
WR = 1; //启动编程 *** 作
asm("NOP");
asm("NOP");
WREN = 0; //禁止编程/擦除 *** 作
}
/
名称:FlashEraseLine
功能:擦除程序存储器一行
参数:addr -> 程序存储器行地址
返回:无
/
void FlashEraseLine(uint16 addr)
{
EEADRL = ((addr) & 0xff);
EEADRH = ((addr) >> 8);
CFGS = 0; //访问程序存储器or数据EEPROM
WREN = 1; //使能编程/擦除 *** 作
EEPGD = 1; //访问程序存储器
FREE = 1; //执行擦除 *** 作
EECON2 = 0x55; //必须的解锁序列
EECON2 = 0xAA; //必须的解锁序列
WR = 1; //启动程序存储器or数据EEPROM编程/擦除 *** 作
asm("NOP");
asm("NOP");
WREN = 0; //禁止编程/擦除 *** 作
}


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/13361094.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-21
下一篇 2023-07-21

发表评论

登录后才能评论

评论列表(0条)

保存