失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > 【51单片机快速入门指南】7:片上EEPROM

【51单片机快速入门指南】7:片上EEPROM

时间:2019-09-19 21:55:37

相关推荐

【51单片机快速入门指南】7:片上EEPROM

目录

硬知识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,再写入B9H,ISP/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"。

大建议

同一次修改的数据放在同一扇区中,不是同一次修改的数据放在另外的扇区,就不需读出保护。如果一个扇区只用一个字节,那就是真正的EEPROM,STC单片机的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: -----------------------------------------*//* --- Web: -----------------------------------------*//* 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 registersfr IAP_ADDRH = 0xE3; //Flash address HIGHsfr IAP_ADDRL = 0xE4; //Flash address LOWsfr IAP_CMD= 0xE5; //Flash command registersfr IAP_TRIG = 0xE6; //Flash command triggersfr 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 functionMake 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 areaInput: 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 areaInput: 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 areaInput: 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 SYSCLK<40MHz#define ENABLE_IAP 0x81 //if SYSCLK<20MHz//#define ENABLE_IAP 0x82 //if SYSCLK<10MHz//#define ENABLE_IAP 0x83 //if SYSCLK<5MHz//#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);}}}

如果觉得《【51单片机快速入门指南】7:片上EEPROM》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。