日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

發布時間:2023/12/9 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【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系列單片機內部集成了的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: 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首地址第一個數是否與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的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。