关于EEPROM的应用总结.docx
- 文档编号:7205669
- 上传时间:2023-01-21
- 格式:DOCX
- 页数:15
- 大小:20.78KB
关于EEPROM的应用总结.docx
《关于EEPROM的应用总结.docx》由会员分享,可在线阅读,更多相关《关于EEPROM的应用总结.docx(15页珍藏版)》请在冰豆网上搜索。
关于EEPROM的应用总结
关于EEPROM的应用总结
关于EEPROM的应用总结
当在程序运行的过程中你希望修改某个变量并且此变量的值在掉电以后不丢失,那么你就可以采用将变量数据写入EEPROM的方式来实现。
什么是EEPROM,即ElectricallyErasableProgrammableRead_OnlyMemory首先它是一种存储器,并且可以通过高电压来进行反复擦写的存储器。
具有掉电数据不丢失的特点。
比如常用的24C系列,93C系列的器件。
一般这种器件采用I2C的方式与单片机进行通讯,对于这种通讯方式及器件的应用另作总结。
这里主要总结一下,STC12C5204AD芯片内部包含的EEPROM的应用方法。
STC12C5201AD系列单片机内部集成了EEPROM是与程序空间分开的,利用ISP/IAP技术可将内部dataflash当EEPROM,擦写10万次以上。
EEPROM可分为若干个扇区,每个扇区包含512字节。
使用时建议同一次修改的数据放在同一个扇区,不是同一次修改的数据放在不同的扇区,不一定要用满。
数据存储器的擦除操作是按扇区进行的。
在程序中可对EEPROM进行字节读写/字节编程/扇区擦除操作。
在工作电压Vcc偏低时,建议不要进行EEPROM/IAP操作。
以免发生数据错误。
应用的步骤
1、声明与EEPROM相关的寄存器
2、编写EEPROM初始化函数
3、编写字节擦除函数
4、编写字节编程函数
5、编写字节读取函数
6、在需要读取EEPROM字节内容时直接调用字节读取函数即可
7、在需要进行写EEPROM字节时,先调用字节擦除函数,将字节内容擦除成FFH后,在调用字节编程函数,将数据写入到EEPROM的地址单元中。
与EEPROM应用相关的寄存器
符号
描述
地址
位地址及符号
复位值
IAP_DATA
ISP/IAPflashdataregister
C2H
11111111B
IAP_ADDRH
ISP/IAPflashaddresshigh
C3H
00000000B
IAP_ADDRL
ISP/IAPflashaddresslow
C4H
IAP_CMD
ISP/IAPflashcommandregister
C5H
MS1
MS0
IAP_TRIG
ISP/IAPflashcommandtrigger
C6H
xxxxxxxxxB
IAP_CONTR
ISP/IAPcontrolregister
C7H
IAPEN
SWBS
SWRST
CMD_FAIL
WT2
WT1
WT0
0000X000B
PCON
Powercontrol
87H
SOMD
SMOD0
LVDF
POF
GF1
GF0
PD
IDL
00110000B
1、IAP_DATA:
ISP/IAP数据寄存器
ISP/IAP操作时的数据寄存器。
ISP/IAP从FlASH读出的数据存放此处,向flash写的数据也需要放在此处。
2、IAP_ADDRH和IAP_ADDRL:
IAP/ISP地址寄存器
3、IAP_CMD:
ISP/IAP命令寄存器
MS1
MS0
命令/操作模式选择
0
0
Standby待机模式,无ISP操作
0
1
从用户程序区对“dataflash/EEprom区”进行字节读
1
0
从用户的应用程序区对“dataflash/eeprom区”进行字节编写
1
1
从用户的应用程序区对“dataflash/eeprom区”进行扇区擦除
4、IAP_TRIG:
ISP/IAP命令触发寄存器
在IAPEN(IAP_CONTR.7)=1时,对IAP——trig先写入5AH,在写入A5H,ISP\IAP命令才会生效
ISP\IAP操作完成后,IAP地址高8位寄存器IAP_ADDRH、IAP地址低8位寄存器IAP_ADDRL和IAP命令寄存器IAP_CMD的内容不变。
如果接下来要对下一个地址的数据进行IAP/ISP操作,需手动将该地址的高8位和低8位分别写入IAP_ADDRH和IAP_ADDRL寄存器。
每次IAP操作时,都要对IAP_TRIG先写入5AH,再写入A5H,ISP/IAP命令才会生效。
5、IAP_CONTR:
ISP\IAP控制寄存器
SFRname
Address
Bit
B7
B6
B5
B4
B3
B2
B1
B0
IAP_CONTR
C7H
Name
IAPEN
SWBS
SWRST
CMD_FAIL
_
WT2
WT1
WT0
IAPEN:
ISP/IAP功能允许位:
0:
禁止IAP读/写/擦除dataflash/eeprom
1:
允许IAP读/写/擦除dataflash/eeprom
SWBW:
软件选择从用户应用程序区启动(送0),还是从系统ISP监控程序启动(送1)。
要与SWRST直接配合使用才可以实现
SWRST:
0:
不操作;1:
产生软件系统复位,硬件自动复位。
CMD_FAIL:
如果送了ISP/IAP命令,并对IAP_TRIG送5AH/A5H触发失败,则为1,需由软件清零。
在用户应用程序区(AP区)软件复位并从用户应用程序区(AP区)开始执行程序。
MOVIAP_CONTR,#00100000B;SWBS=0(选择AP区),SWRST=1(软复位)
在用户应用程序区(AP区)软件复位并从系统ISP监控程序区开始执行程序
MOVIAP_CONTR,#01100000B;SWBS=1(选择ISP区),SWRST=1(软复位)
在系统ISP监控程序区软件复位并从用户应用程序区(AP区)开始执行程序
MOVIAP_CONTR,#00100000B;SWBS=0(选择AP区)SWRST=1(软复位)
在系统ISP监控程序区软件复位并从系统ISP监控程序区开始执行程序。
MOVIAP_CONTR,#01100000B;SWBS=1(选择ISP区),SWRST=1(软复位)
设置等待时间
设置等待时间
CPU等待时间(多少个CPU工作时钟)
WT2
WT1
WT0
Read/读
(2个时钟)
Program/编程(=55us)
Sectorerase
扇区擦除
=21us
Recommendedsystemclock
跟等待参数对应的推荐系统时钟
1
1
1
2个时钟
55个时钟
21012个时钟
<=1MHz
1
1
0
2个时钟
110个时钟
42024个时钟
<=2MHz
1
0
1
2个时钟
165个时钟
63036个时钟
<=3MHz
1
0
0
2个时钟
330个时钟
126072个时钟
<=6MHz
0
1
1
2个时钟
660个时钟
252144个时钟
<=12MHz
0
1
0
2个时钟
1100个时钟
420240个时钟
<=20MHz
0
0
1
2个时钟
1320个时钟
504288个时钟
<=24MHz
0
0
0
2个时钟
1760个时钟
672348个时钟
<=30MHz
12c系列单片机内部EEPROM选型一览表
型号
字节数(eeprom)
扇区数
起始扇区首地址
结束扇区末尾地址
STC12C5201AD/PWM
2K
4
0000h
07ffh
STC12C5202AD/PWM
2k
4
0000h
07ffh
STC12C5203AD/PWM
2k
4
0000h
07ffh
STC12C5204AD/PWM
1k
2
0000h
03ffh
STC12C5205AD/PWM
1k
2
0000h
03ffh
大建议:
1、同一次修改的数据放在同一个扇区中不是同一次修改的数据放在另外的扇区就不须读出保护。
2、如果一个扇区只用一个字节,那就是真正的EEPROM,STC单片机的Dataflash比外部EEPROM要快很多读一个字节/编程一个字节大概是2个时钟/55微秒。
3、如果在一个扇区中存放了大量的数据,某次只需要修改其中的一个字节或一部分字节时,则另外的不需要修改的数据须先读出放在STC单片机的RAM中,然后擦除整个扇区,再将需要保留的数据和需修改的数据按字节逐字节写回该扇区中(只有字节写命令,无连续字节写命令)。
这时每个扇区使用的字节数是使用的越少越方便(不需要读出一大堆需保留数据)。
常见问题:
1、IAP指令完成后,地址是否会自动”加1”或“减1”?
不会
2、送5A和A5触发之后下一次IAP命令是否还需要送5A和A5触发?
是,一定要。
STC12C5201AD/PWM单片机内部EEPROM地址表
第一扇区
第二扇区
第三扇区
第四扇区
每个扇区
512字节
建议同一次修改的数据放在同一个扇区,不是同一次修改的数据放在不同的扇区,不必用满,当然也可以用满。
起始地址
结束地址
起始地址
结束地址
起始地址
结束地址
起始地址
结束地址
0000h
1FFH
200H
3FFH
400H
5FFH
600H
7FFH
第五扇区
第六扇区
第七扇区
第八扇区
起始地址
结束地址
起始地址
结束地址
起始地址
结束地址
起始地址
结束地址
800H
9FFH
A00H
BFFH
C00H
DFFH
E00H
FFFH
第九扇区
第十扇区
第十一扇区
第十二扇区
起始地址
结束地址
起始地址
结束地址
起始地址
结束地址
起始地址
结束地址
1000H
11FFH
1200H
13FFH
1400H
15FFH
1600H
17FFH
下面就举一个例子来说明一下EEPROM的应用
程序功能:
三个按键分别是,开关、增大、减小。
通过7段数码管将键值显示出来(1-9)。
并将开关键关闭前的键值保存在EEPROM中,系统再次上电时显示上次关闭前的键值。
#include
#include”intrins.h”
/******宏定义*************/
#defineuintunsignedint//用unsignedint代替unsignedint
#defineucharunsignedchar//用uchar替代unsignedchar
/*********位定义**************/
sbitSW=P3^2;//开关
sbitINC=P3^3;//增大按键
sbitDEC=P3^4;//减小按键
sbitDATA=P1^5;//595数据流
sbitSHIFT=P1^6;//595移位寄存器
sbitSTORAGE=P1^7;//595存储寄存器
sbitBEEP=P1^4;//蜂鸣器
/数码管显示代码
ucharcodenum[]={0x01,0xf3,0x89,0xa1,0xb2,0xa4,0x84,0xf1,0x80,0x20};//0-9代码
//变量声明
bitkai=0,biaozhi=0;
ucharMA,dat;
/*定义与EEPROM相关的特殊功能寄存器*/
sfrIAP_DATA=0XC2;//FLASHdataregister
sfrIAP_ADDRH=0XC3;//FLASHaddresshigh
sfrIAP_ADDRL=0XC4;//FLASHaddresslow
sfrIAP_CMD=0XC5;//FLASHcommandregister
sfrIAP_TRIG=0XC6;//FLSHcommandtrigger
sfrIAP_CONTR=0XC7;//flashcontrolregister
/*定义IAP/ISP/EEPROM命令*/
#defineCMD_IDLE0//stand_by
#defineCMD_READ1//byte_read
#defineCMD_PROGRAM2//byte_program
#defineCMD_ERASE3//sector_erase
/*定义与EEPROM相关的寄存器*/
//#defineENABLE_IAP0X80//ifsysclk<30MHz
//#defineENABLE_IAP0X81//ifsysclk<24MHz
//#defineENABLE_IAP0X82//ifsysclk<20MHz
#defineENABLE_IAP0X83//ifsysclk<12MHz//定义控制寄存器
//#defineENABLE_IAP0X84//ifsysclk<6MHz
//#defineENABLE_IAP0X85//ifsysclk<3MHz
//#defineENABLE_IAP0X86//ifsysclk<2MHz
//#defineENABLE_IAP0X87//ifsysclk<1MHz
/*定义EEPROM的起始地址*/
#defineIAP_ADDRESS0X0000
/****初始化函数**********/
Voidiapidle()
{
IAP_CONTR=0;//关闭IAP功能
IAP_CMD=0;//CMD寄存器初始化
IAP_TRIG=0;//清空触发寄存器
IAP_ADDRH=0X80;//数据指针指向非EEPROM区
IAP_ADDRL=0;//CLEARIAPaddresstopreventmisuse
}
/*读EEPROM的一个字节地址的内容
输入:
地址
输出:
EEPROM字节数据
*/
uchariapreadbyte(uintaddr)
{
IAP_CONTR=ENABLE_IAP;//设置IAP控制寄存器
IAP_CMD=CMD_READ;//设置IAP的命令寄存器为读状态
IAP_ADDRL=addr;//设置EERPROM的低8位地址
IAP_ADDRH=addr>>8;
IAP_TRIG=0X5A;
IAP_TRIG=0XA5;
_nop_();
dat=IAP_DATA;
iapidle();
returndat;
}
/*写一个字节的IAP/ISP/EEPROM空间
输入:
字节地址
要写入的数据
Voidiapprogrambyte(uintaddr,uchardat)
{
IAP_CONTR=ENABLE_IAP;//打开IAP功能并设置等待时间
IAP_CMD=CMD_PROGRAM;//设置写命令
IAP_ADDRL=addr;//设置字节地址低8位
IAP_ADDRH=addr>>8;//设置字节地址的高8位
IAP_DATA=dat;//写内容
IAP_TRIG=0X5A;//发送触发命令1
IAP_TRIG=0XA5;//发送触发命令2
_nop_();//等待直到写操作完成
Iapidle();
}
/*扇区擦除
输入:
地址
Voidiaperasesector(uintaddr)
{
IAP_CONTR=ENABLE_IAP;//开IAP功能并设置等待时间
IAP_CMD=CMD_ERASE;//设置擦除命令
IAP_ADDRL=addr;
IAP_ADDRH=addr>>8;
IAP_TRIG=0x5a;
IAP_TRIG=0XA5;
_nop_();
Iapidle();
}
/********写595函数*******************/
voidwrite_595(ucharx)
{
ucharj;
for(j=0;j<8;j++)
{
x=x<<1;
SHIFT=0;
_nop_();
_nop_();
_nop_();
DATA=CY;
SHIFT=1;
_nop_();
_nop_();
_nop_();
SHIFT=0;
}
}
/********595输出函数函数*******************/
voidout_595(void)
{
STORAGE=0;
_nop_();
_nop_();
STORAGE=1;
_nop_();
_nop_();
STORAGE=0;
}
/*软件延时*/
voiddelay(uchart)
{ucharx;
while(t--)
{
for(x=0;x<250;x++)
{
_nop_();
_nop_();
_nop_();
_nop_();
}
}
}
/******按键检测函数**********************/
voidkeycheck(void)
{
if(SW==0)//判断开关按键是否按下
{delay(10);//抗干扰
if(SW==0)//确实按下
{kai=~kai;
}
while(!
SW)//一直按下
{BEEP=1;}//蜂鸣器响
BEEP=0;//松开按键,蜂鸣器关闭
}
if(INC==0&kai==1&MA<9)//如果处于开的状态并且数字小于9则按下增大键执行
{
delay(10);
if(INC==0&kai&MA<9)
{MA++;}
while(!
INC)
{BEEP=1;}
BEEP=0;
}
if(DEC==0&kai&MA>1)
{
delay(10);
if(DEC==0&kai&MA>1)
{MA--;}
while(!
DEC)
{BEEP=1;}
BEEP=0;
}
if(kai==1)//如果电源打开了,则将电源开的状态标志置1
{biaozhi=1;}
if(biaozhi==1&kai==0)//判断电源打开后被关闭,目的是只在开关键关闭时,写一次EEPROM,避免不停的擦写EEPROM
{biaozhi=0;
iaperasesector(0x00);
programbyte(0x00,MA);
//执行EEPROM写程
}
}
//主函数
Voidmain(void)
{
BEEP=0;//关闭蜂鸣器
iapreadbyte(0x00);//读出EEPROM的值
MA=dat;
if(MA<1|MA>9)//如果读出的值不在1-9范围内则强制为5.
{MA=5;}
while
(1)
{
keycheck();//执行按键扫描程序
write_595(num[MA]);
write_595(num[MA]);
out_595();
}
}
这只是一个简单的读写一个字节的简单测试程序,对于扇区擦除的结果也没有进行验证。
想要验证需要在加一段代码。
具体请参照STC的数据手册。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 关于 EEPROM 应用 总结