【51单片机快速入门指南】7:片上EEPROM
目錄
- 硬知識
- IAP及EEPROM新增特殊功能寄存器介紹
- EEPROM空間大小及地址
- 小常識
- 大建議
- 常見問題
- 示例程序
- EEPROM.c
- EEPROM.h
- 測試程序
- main.c
普中51-單核-A2
STC89C52
Keil uVision V5.29.0.0
PK51 Prof.Developers Kit Version:9.60.0.0
硬知識
???????摘自《STC89C52系列單片機器件手冊》
???????STC89C5x系列單片機內(nèi)部集成了的EEPROM是與程序空間是分開的,利用ISP/IAP技術(shù)可將內(nèi)部Data Flash當EEPROM,擦寫次數(shù)在10萬次以上。EEPROM可分為若干個扇區(qū),每個扇區(qū)包含512字節(jié)。使用時,建議同一次修改的數(shù)據(jù)放在同一個扇區(qū),不是同一次修改的數(shù)據(jù)放在不同的扇區(qū),不一定要用滿。數(shù)據(jù)存儲器的擦除操作是按扇區(qū)進行的。
???????EEPROM可用于保存一些需要在應用過程中修改并且掉電不丟失的參數(shù)數(shù)據(jù)。在用戶程序中,可以對EEPROM進行字節(jié)讀/字節(jié)編程/扇區(qū)擦除操作。在工作電壓Vcc偏低時,建議不要進行EEPROM/IAP操作。
IAP及EEPROM新增特殊功能寄存器介紹
ISP/IAP數(shù)據(jù)寄存器ISP_DATA
???????ISP_DATA : ISP/IAP操作時的數(shù)據(jù)寄存器。
???????ISP/IAP 從Flash讀出的數(shù)據(jù)放在此處,向Flash寫的數(shù)據(jù)也需放在此處
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格式如下:
???????程序在系統(tǒng)ISP程序區(qū)時可以對用戶應用程序區(qū)/數(shù)據(jù)Flash區(qū)(EEPROM)進行字節(jié)讀/字節(jié)編程/扇區(qū)擦除;程序在用戶應用程序區(qū)時,僅可以對數(shù)據(jù)Flash 區(qū)(EEPROM)進行字節(jié)讀/字節(jié)編程/扇區(qū)擦除。已經(jīng)固化有ISP引導碼,并設(shè)置為上電復位進入ISP
ISP/IA命令觸發(fā)寄存器ISP_TRIG
???????ISP_TRIG: ISP/IAP 操作時的命令觸發(fā)寄存器。 在ISPEN(ISP_CONTR.7) = 1 時,對ISP_TRIG先寫入46h,再寫入B9h,ISP/IAP 命令才會生效。
???????ISP/IAP操作完成后,ISP地址高八位寄存器ISP_ADDRH、ISP地址低八位寄存器ISP_ADDRL和ISP命令寄存器ISP_CMD的內(nèi)容不變。如果接下來要對下一個地址的數(shù)據(jù)進行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: 軟件選擇從用戶應用程序區(qū)啟動(送0),還是從系統(tǒng) ISP監(jiān)控程序區(qū)啟動(送1)。要與SWRST直接配合才可以實現(xiàn)
???????SWRST:
??????????????0: 不操作;
??????????????1: 產(chǎn)生軟件系統(tǒng)復位,硬件自動復位。
???????;在用戶應用程序區(qū)(AP區(qū))軟件復位并從系統(tǒng)ISP監(jiān)控程序區(qū)開始執(zhí)行程序
??????????????MOV ISP_CONTR, #01100000B ;SWBS = 1(選擇ISP區(qū)), SWRST = 1(軟復位)
???????;在系統(tǒng)ISP監(jiān)控程序區(qū)軟件復位并從用戶應用程序區(qū)(AP 區(qū))開始執(zhí)行程序
??????????????MOV ISP_CONTR, #00100000B ;SWBS = 0(選擇AP 區(qū)), SWRST = 1(軟復位)
EEPROM空間大小及地址
內(nèi)部可用EEPROM的地址與程序空間是分開的:程序在用戶應用程序區(qū)時,可以對EEPROM 進行IAP/ISP操作。
小常識
???????3個基本命令——字節(jié)讀,字節(jié)編程,扇區(qū)擦除
???????字節(jié)編程:將"1"寫成"1"或"0",將"0"寫成"0"。如果某字節(jié)是FFH,才可對其進行字節(jié)編程。如果該字節(jié)不是FFH,則須先將整個扇區(qū)擦除,因為只有“扇區(qū)擦除”才可以將"0"變?yōu)?#34;1"。
???????扇區(qū)擦除:只有“扇區(qū)擦除”才可能將"0"擦除為"1"。
大建議
常見問題
示例程序
改自官方例程。
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 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首地址第一個數(shù)是否與DATA一致,如果不一致,點亮LED0,如果一致點亮LED1。按下KEY1后擦除第一個扇區(qū),按下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);}} } 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的【51单片机快速入门指南】7:片上EEPROM的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《产品结构设计》——黎恢来,笔记
- 下一篇: Android反编译查看源码