淘宝客cms建站教程,写一个有图片的网页,网站建设成本控制,网络营销服务的特点目录硬知识IAP及EEPROM新增特殊功能寄存器介绍EEPROM空间大小及地址小常识大建议常见问题示例程序EEPROM.cEEPROM.h测试程序main.c普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 硬知识 摘自《STC89C52系列单片机器件手册》 ST…
目录硬知识IAP及EEPROM新增特殊功能寄存器介绍EEPROM空间大小及地址小常识大建议常见问题示例程序EEPROM.cEEPROM.h测试程序main.c普中51-单核-A2 STC89C52 Keil uVision V5.29.0.0 PK51 Prof.Developers Kit Version:9.60.0.0 硬知识 摘自《STC89C52系列单片机器件手册》 STC89C5x系列单片机内部集成了的EEPROM是与程序空间是分开的利用ISP/IAP技术可将内部Data Flash当EEPROM擦写次数在10万次以上。EEPROM可分为若干个扇区每个扇区包含512字节。使用时建议同一次修改的数据放在同一个扇区不是同一次修改的数据放在不同的扇区不一定要用满。数据存储器的擦除操作是按扇区进行的。 EEPROM可用于保存一些需要在应用过程中修改并且掉电不丢失的参数数据。在用户程序中可以对EEPROM进行字节读/字节编程/扇区擦除操作。在工作电压Vcc偏低时建议不要进行EEPROM/IAP操作。
IAP及EEPROM新增特殊功能寄存器介绍 ISP/IAP数据寄存器ISP_DATA ISP_DATA : ISP/IAP操作时的数据寄存器。 ISP/IAP 从Flash读出的数据放在此处向Flash写的数据也需放在此处 ISP/IAP地址寄存器ISP_ADDRH和ISP_ADDRL ISP_ADDRH : ISP/IAP 操作时的地址寄存器高八位。 该寄存器地址为E3H,复位后值为00H. ISP_ADDRL : ISP/IAP 操作时的地址寄存器低八位。 该寄存器地址为E4H,复位后值为00H. ISP/IAP命令寄存器ISP_CMD ISP/IAP命令寄存器IAP_CMD格式如下 程序在系统ISP程序区时可以对用户应用程序区/数据Flash区(EEPROM)进行字节读/字节编程/扇区擦除程序在用户应用程序区时仅可以对数据Flash 区(EEPROM)进行字节读/字节编程/扇区擦除。已经固化有ISP引导码,并设置为上电复位进入ISP ISP/IA命令触发寄存器ISP_TRIG ISP_TRIG: ISP/IAP 操作时的命令触发寄存器。 在ISPEN(ISP_CONTR.7) 1 时,对ISP_TRIG先写入46h,再写入B9h,ISP/IAP 命令才会生效。 ISP/IAP操作完成后ISP地址高八位寄存器ISP_ADDRH、ISP地址低八位寄存器ISP_ADDRL和ISP命令寄存器ISP_CMD的内容不变。如果接下来要对下一个地址的数据进行ISP/IAP操作需手动将该地址的高8位和低8位分别写入ISP_ADDRH和ISP_ADDRL寄存器。 每次ISP操作时都要对ISP_TRIG先写入46H再写入B9HISP/IAP命令才会生效。 ISP/IAP命令寄存器ISP_CONTR ISP/IAP控制寄存器IAP_CONTR格式如下 ISPEN: ISP/IAP功能允许位。 0禁止IAP/ISP读/写/擦除Data Flash/EEPROM 1: 允许IAP/ISP读/写/擦除Data Flash/EEPROM SWBS: 软件选择从用户应用程序区启动(送0)还是从系统 ISP监控程序区启动(送1)。要与SWRST直接配合才可以实现 SWRST: 0: 不操作 1: 产生软件系统复位硬件自动复位。 ;在用户应用程序区(AP区)软件复位并从系统ISP监控程序区开始执行程序 MOV ISP_CONTR, #01100000B ;SWBS 1(选择ISP区), SWRST 1(软复位) ;在系统ISP监控程序区软件复位并从用户应用程序区(AP 区)开始执行程序 MOV ISP_CONTR, #00100000B ;SWBS 0(选择AP 区), SWRST 1(软复位)
EEPROM空间大小及地址
内部可用EEPROM的地址与程序空间是分开的程序在用户应用程序区时,可以对EEPROM 进行IAP/ISP操作。
小常识 3个基本命令——字节读字节编程扇区擦除 字节编程将1写成1或0将0写成0。如果某字节是FFH才可对其进行字节编程。如果该字节不是FFH则须先将整个扇区擦除因为只有“扇区擦除”才可以将0变为1。 扇区擦除只有“扇区擦除”才可能将0擦除为1。
大建议
同一次修改的数据放在同一扇区中不是同一次修改的数据放在另外的扇区就不需读出保护。如果一个扇区只用一个字节那就是真正的EEPROMSTC单片机的Data Flash比外部EPROM要快很多读一个字节/编程一个字节大概是10us/60us/10ms如果在一个扇区中存放了大量的数据某次只需要修改其中的一个字节或一部分字节时则另外的不需要修改的数据须先读出放在STC单片机的RAM中然后擦除整个扇区再将需要保留的数据和需修改的数据按字节逐字节写回该扇区中只有字节写命令无连续字节写命令。这时每个扇区使用的字节数是使用的越少越方便不需读出一大堆需保留数据。
常见问题
IAP指令完成后地址是否会自动“加1”或“减1” 答不会。送46和B9触发后下一次IAP命令是否还需要送46和B9触发答是一定要。
示例程序
改自官方例程。
EEPROM.c
/*------------------------------------------------------------------*/
/* --- STC MCU Limited ---------------------------------------------*/
/* --- STC89-90xx Series MCU ISP/IAP/EEPROM Demo -------------------*/
/* --- Mobile: (86)13922805190 -------------------------------------*/
/* --- Fax: 86-0513-55012956,55012947,55012969 ---------------------*/
/* --- Tel: 86-0513-55012928,55012929,55012966----------------------*/
/* --- Web: www.STCMCU.com -----------------------------------------*/
/* --- Web: www.GXWMCU.com -----------------------------------------*/
/* If you want to use the program or the program referenced in the */
/* article, please specify in which data and procedures from STC */
/*------------------------------------------------------------------*/#include STC89C5xRC.H
#include EEPROM.h
#include intrins.h/*Declare SFR associated with the IAP */
sfr IAP_DATA 0xE2; //Flash data register
sfr IAP_ADDRH 0xE3; //Flash address HIGH
sfr IAP_ADDRL 0xE4; //Flash address LOW
sfr IAP_CMD 0xE5; //Flash command register
sfr IAP_TRIG 0xE6; //Flash command trigger
sfr IAP_CONTR 0xE7; //Flash control register/*Define ISP/IAP/EEPROM command*/
#define CMD_IDLE 0 //Stand-By
#define CMD_READ 1 //Byte-Read
#define CMD_PROGRAM 2 //Byte-Program
#define CMD_ERASE 3 //Sector-Erasevoid Delay(unsigned char n);
void IapIdle();/*----------------------------
Disable ISP/IAP/EEPROM function
Make MCU in a safe state
----------------------------*/
void IapIdle()
{IAP_CONTR 0; //Close IAP functionIAP_CMD 0; //Clear command to standbyIAP_TRIG 0; //Clear trigger registerIAP_ADDRH 0x80; //Data ptr point to non-EEPROM areaIAP_ADDRL 0; //Clear IAP address to prevent misuse
}/*----------------------------
Read one byte from ISP/IAP/EEPROM area
Input: addr (ISP/IAP/EEPROM address)
Output:Flash data
----------------------------*/
unsigned char IapReadByte(unsigned short addr)
{unsigned char dat; //Data bufferIAP_CONTR ENABLE_IAP; //Open IAP function, and set wait timeIAP_CMD CMD_READ; //Set ISP/IAP/EEPROM READ commandIAP_ADDRL addr; //Set ISP/IAP/EEPROM address lowIAP_ADDRH addr 8; //Set ISP/IAP/EEPROM address highIAP_TRIG 0x46; //Send trigger command1 (0x46)IAP_TRIG 0xb9; //Send trigger command2 (0xb9)_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation completedat IAP_DATA; //Read ISP/IAP/EEPROM dataIapIdle(); //Close ISP/IAP/EEPROM functionreturn dat; //Return Flash data
}/*----------------------------
Program one byte to ISP/IAP/EEPROM area
Input: addr (ISP/IAP/EEPROM address)dat (ISP/IAP/EEPROM data)
Output:-
----------------------------*/
void IapProgramByte(unsigned short addr, unsigned char dat)
{IAP_CONTR ENABLE_IAP; //Open IAP function, and set wait timeIAP_CMD CMD_PROGRAM; //Set ISP/IAP/EEPROM PROGRAM commandIAP_ADDRL addr; //Set ISP/IAP/EEPROM address lowIAP_ADDRH addr 8; //Set ISP/IAP/EEPROM address highIAP_DATA dat; //Write ISP/IAP/EEPROM dataIAP_TRIG 0x46; //Send trigger command1 (0x46)IAP_TRIG 0xb9; //Send trigger command2 (0xb9)_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation completeIapIdle();
}/*----------------------------
Erase one sector area
Input: addr (ISP/IAP/EEPROM address)
Output:-
----------------------------*/
void IapEraseSector(unsigned short addr)
{IAP_CONTR ENABLE_IAP; //Open IAP function, and set wait timeIAP_CMD CMD_ERASE; //Set ISP/IAP/EEPROM ERASE commandIAP_ADDRL addr; //Set ISP/IAP/EEPROM address lowIAP_ADDRH addr 8; //Set ISP/IAP/EEPROM address highIAP_TRIG 0x46; //Send trigger command1 (0x46)IAP_TRIG 0xb9; //Send trigger command2 (0xb9)_nop_(); //MCU will hold here until ISP/IAP/EEPROM operation completeIapIdle();
}unsigned char IapWriteBytes(unsigned short addr, unsigned char * pData, unsigned short len)
{unsigned char temp[512], Addr addr;unsigned short i;Addr 9;Addr 9;addr % 512;for(i 0; i 512; i){temp[i] IapReadByte(Addr i);}for(i 0; i len; i){temp[addr i] *(pData i);}IapEraseSector(Addr); //Erase current sectorfor (i 0; i 512; i) //Program 512 bytes data into data flash{IapProgramByte(Addr i, temp[i]);}for (i 0; i len; i){if (IapReadByte(Addr addr i) ! *(pData i))return 0;}return 1;
}
EEPROM.h
#ifndef EEPROM_H_
#define EEPROM_H_/*Define ISP/IAP/EEPROM operation const for IAP_CONTR*/
//#define ENABLE_IAP 0x80 //if SYSCLK40MHz
#define ENABLE_IAP 0x81 //if SYSCLK20MHz
//#define ENABLE_IAP 0x82 //if SYSCLK10MHz
//#define ENABLE_IAP 0x83 //if SYSCLK5MHz//#define IAP_ADDRESS 0x1000 //Start address for STC89C51 EEPROM
#define IAP_ADDRESS 0x2000 //Start address for STC89C52 EEPROM
//#define IAP_ADDRESS 0x3000 //Start address for STC89C53 EEPROM
//#define IAP_ADDRESS 0x4000 //Start address for STC89C54 EEPROM
//#define IAP_ADDRESS 0x8000 //Start address for STC89C58 EEPROM
//#define IAP_ADDRESS 0xA000 //Start address for STC89C510 EEPROM
//#define IAP_ADDRESS 0xC000 //Start address for STC89C512 EEPROM
//#define IAP_ADDRESS 0xE000 //Start address for STC89C514 EEPROMunsigned char IapReadByte(unsigned short addr);
void IapProgramByte(unsigned short addr, unsigned char dat);
void IapEraseSector(unsigned short addr);#endif测试程序 检测EEPROM首地址第一个数是否与DATA一致如果不一致点亮LED0如果一致点亮LED1。按下KEY1后擦除第一个扇区按下KEY2后写入DATA。
main.c
#include STC89C5xRC.H
#include EEPROM.h#define DATA 233sbit LED0 P2^0;
sbit LED1 P2^1;
sbit KEY1 P3^1;
sbit KEY2 P3^0;void Delay20ms() //11.0592MHz
{unsigned char i, j;i 36;j 217;do{while (--j);} while (--i);
}void main(void)
{while(1){ if (IapReadByte(IAP_ADDRESS) DATA) {LED0 1;LED1 0;}else{LED0 0;LED1 1;}if (!KEY1){Delay20ms();if (!KEY1){IapEraseSector(IAP_ADDRESS);}while(!KEY1);}if (!KEY2){Delay20ms();if (!KEY2){IapProgramByte(IAP_ADDRESS, DATA);}while(!KEY2);}}
}