关于STC单片机EEPROM的应用总结
大建议:
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”
/******宏定义*************/
#define uintunsigned int//用unsigned int 代替unsigned int
#define ucharunsigned char//用uchar 替代unsigned char
/*********位定义**************/
sbit SW=P3^2;//开关
sbit INC=P3^3;//增大按键
sbit DEC=P3^4;//减小按键
sbitDATA=P1^5;//595数据流
sbitSHIFT=P1^6;//595移位寄存器
sbitSTORAGE=P1^7;//595存储寄存器
sbitBEEP=P1^4;//蜂鸣器
/数码管显示代码
uchar codenum[]={0x01,0xf3,0x89,0xa1,0xb2,0xa4,0x84,0xf1,0x80,0x20} ; //0-9代码
//变量声明
bit kai=0,biaozhi=0;
uchar MA,dat;
/*定义与EEPROM相关的特殊功能寄存器*/
sfrIAP_DATA=0XC2;//FLASH data register
sfrIAP_ADDRH=0XC3;//FLASH address high
sfrIAP_ADDRL=0XC4;//FLASH address low
sfrIAP_CMD=0XC5;//FLASH command register
sfrIAP_TRIG=0XC6;//FLSH command trigger
sfrIAP_CONTR=0XC7;//flashcontrol register
/*定义IAP/ISP/EEPROM命令*/
#define CMD_IDLE0//stand_by
#define CMD_READ1//byte_read
#defineCMD_PROGRAM 2//byte_program
#defineCMD_ERASE 3//sector_erase
/*定义与EEPROM相关的寄存器 */
//#defineENABLE_IAP0X80 //if sysclk<30MHz
//#defineENABLE_IAP0X81 //if sysclk<24MHz
//#defineENABLE_IAP0X82 //if sysclk<20MHz
#defineENABLE_IAP0X83 //if sysclk<12MHz//定义控制寄存器
//#defineENABLE_IAP0X84 //if sysclk<6MHz
//#defineENABLE_IAP0X85 //if sysclk<3MHz
//#define ENABLE_IAP 0X86//if sysclk<2MHz
//#defineENABLE_IAP0X87 //if sysclk<1MHz
/*定义EEPROM 的起始地址*/
#defineIAP_ADDRESS 0X0000
/****初始化函数**********/
Void iapidle()
{
IAP_CONTR=0;//关闭IAP功能
IAP_CMD=0;//CMD寄存器初始化
IAP_TRIG=0;//清空触发寄存器
IAP_ADDRH=0X80;//数据指针指向非EEPROM区
IAP_ADDRL=0;//CLEAR IAP address to preventmisuse
}
/*读EEPROM的一个字节地址的内容
输入:地址
输出:EEPROM字节数据
*/
uchar iapreadbyte(uint addr)
{
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();
return dat;
}
/*写一个字节的IAP/ISP/EEPROM空间
输入: 字节地址
要写入的数据
Void iapprogrambyte(uint addr,uchar dat)
{
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();
}
/*扇区擦除
输入:地址
Void iaperasesector(uint addr)
{
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函数*******************/
void write_595(uchar x)
{
uchar j;
for(j=0;j<8;j++)
{
x=x<<1;
SHIFT=0;
_nop_();
_nop_();
_nop_();
DATA=CY;
SHIFT=1;
_nop_();
_nop_();
_nop_();
SHIFT=0;
}
关键词:
STC单片机EEPRO
评论