新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > STC單片機EEPROM的應(yīng)用和程序

STC單片機EEPROM的應(yīng)用和程序

作者: 時間:2016-11-24 來源:網(wǎng)絡(luò) 收藏
最近,由于工作的需要,用STC89C52來開發(fā)新產(chǎn)品,要用天STC的Eeprom的功能,上網(wǎng)也找了一點資料,得到很大幫助,真的非常感謝。程序是我在網(wǎng)上摘錄的,調(diào)試通過了,不過我產(chǎn)品在用動態(tài)掃描顯示的,由于在Eeprom擦除時要用幾十毫秒,會有一閃爍的。不過這是正常的。

本文引用地址:http://m.butianyuan.cn/article/201611/320955.htm

單片機運行時的數(shù)據(jù)都存在于RAM(隨機存儲器)中,在掉電后RAM 中的數(shù)據(jù)是無
法保留的,那么怎樣使數(shù)據(jù)在掉電后不丟失呢?這就需要使用EEPROM 或FLASHROM 等
存儲器來實現(xiàn)。在傳統(tǒng)的單片機系統(tǒng)中,一般是在片外擴(kuò)展存儲器,單片機與存儲器之間通
過IIC 或SPI 等接口來進(jìn)行數(shù)據(jù)通信。這樣不光會增加開發(fā)成本,同時在程序開發(fā)上也要花
更多的心思。在STC 單片機中內(nèi)置了EEPROM(其實是采用IAP 技術(shù)讀寫內(nèi)部FLASH 來
實現(xiàn)EEPROM),這樣就節(jié)省了片外資源,使用起來也更加方便。下面就詳細(xì)介紹STC 單
片機內(nèi)置EEPROM 及其使用方法。
STC 各型號單片機內(nèi)置的EEPROM 的容量各有不同,見下表:
(內(nèi)部EEPROM 可以擦寫100000 次以上)
上面提到了IAP,它的意思是“在應(yīng)用編程”,即在程序運行時程序存儲器可由程序自
身進(jìn)行擦寫。正是是因為有了IAP,從而可以使單片機可以將數(shù)據(jù)寫入到程序存儲器中,使
得數(shù)據(jù)如同燒入的程序一樣,掉電不丟失。當(dāng)然寫入數(shù)據(jù)的區(qū)域與程序存儲區(qū)要分開來,以
使程序不會遭到破壞。
要使用IAP 功能,與以下幾個特殊功能寄存器相關(guān):
ISP_DATA: ISP/IAP 操作時的數(shù)據(jù)寄存器。
ISP/IAP 從Flash 讀出的數(shù)據(jù)放在此處,向Flash 寫的數(shù)據(jù)也需放在此處
ISP_ADDRH:ISP/IAP 操作時的地址寄存器高八位。
ISP_ADDRL:ISP/IAP 操作時的地址寄存器低八位。
ISP_CMD: ISP/IAP 操作時的命令模式寄存器,須命令觸發(fā)寄存器觸發(fā)方可生效。
ISP_TRIG:ISP/IAP 操作時的命令觸發(fā)寄存器。
當(dāng)ISPEN(ISP_CONTR.7)=1 時,對ISP_TRIG 先寫入0x46,再寫入0xb9,ISP/IAP
命令才會生效。
單片機芯片型號起始地址內(nèi)置EEPROM 容量(每扇區(qū)512 字節(jié))
STC89C51RC,STC89LE51RC 0x2000 共八個扇區(qū)
STC89C52RC,STC89LE52RC 0x2000 共八個扇區(qū)
STC89C54RD+,STC89LE54RD+ 0x8000 共五十八個扇區(qū)
STC89C55RD+,STC89LE55RD+ 0x8000 共五十八個扇區(qū)
STC89C58RD+,STC89LE58RD+ 0x8000 共五十八個扇區(qū)
寄存器標(biāo)識地址名稱7 6 5 4 3 2 1 0 初始值
ISP_DATA 0xE2 ISP/IAP閃存數(shù)據(jù)寄存器11111111
ISP_ADDRH 0xE3 ISP/IAP 閃存地址高位00000000
ISP_ADDRL 0xE4 ISP/IAP 閃存地址低位00000000
ISP_CMD 0xE5 ISP/IAP閃存命令寄存器MS2
MS1 MS0 xxxxx000
ISP_TRIG 0xE6 ISP/IAP 閃存命令觸發(fā)xxxxxxxx
ISP_CONTR 0xE7 ISP/IAP 控制寄存器ISPEN SWBS SWRST WT2
WT1 WT0 00xx000
B7 B6 B5 B4 B3 B2 B1 B0 命令/操作模式選擇
保留命令選擇
- - - - - 0 0 0 待機模式,無ISP/IAP 操作
- - - - - 0 0 1 對用戶的應(yīng)用程序Flash 區(qū)及數(shù)據(jù)Flash 區(qū)字節(jié)讀
- - - - - 0 1 0 對用戶的應(yīng)用程序Flash 區(qū)及數(shù)據(jù)Flash 區(qū)字節(jié)編程
- - - - - 0 1 1 對用戶的應(yīng)用程序Flash 區(qū)及數(shù)據(jù)Flash 區(qū)扇區(qū)擦除
ISP_CONTR:ISP/IAP 控制寄存器。
ISPEN:ISP/IAP 功能允許位。0:禁止ISP/IAP 編程改變Flash,1:允許編程改變Flash
SWBS:軟件選擇從用戶主程序區(qū)啟動(0),還是從ISP 程序區(qū)啟動(1)。
SWRST:0:不操作,1:產(chǎn)生軟件系統(tǒng)復(fù)位,硬件自動清零。
ISP_CONTR 中的SWBS 與SWRST 這兩個功能位,可以實現(xiàn)單片機的軟件啟動,并
啟動到ISP 區(qū)或用戶程序區(qū),這在“STC 單片機自動下載”一節(jié),亦有所應(yīng)用。
如:
ISP_CONTR=0x60? 則可以實現(xiàn)從用戶應(yīng)用程序區(qū)軟件復(fù)位到ISP 程序區(qū)開始運行
程序。
ISP_CONTR=0x20? 則可以實現(xiàn)從ISP 程序區(qū)軟件復(fù)位到用戶應(yīng)用程序區(qū)開始運行
程序。
用IAP 向Flash 中讀寫數(shù)據(jù),是需要一定的讀寫時間的,讀寫數(shù)據(jù)命令發(fā)出后,要等待
一段時間才可以讀寫成功。這個等待時間就是由WT2、WT1、WT0 與晶體振蕩器頻率決定
的。
(以上的建議時鐘是(WT2、WT1、WT0)取不同的值時的標(biāo)稱時鐘,用戶系統(tǒng)中的時鐘
不要過高,否則可能使操作不穩(wěn)定。)

#include "reg52.h"
#include "eeprom.h"

//****************** 關(guān)閉 ISP,IAP 功能 **************
void ISP_IAP_Disable(void)
{
ISP_CONTR = 0x00;
ISP_CMD = 0X00;
ISP_TRIG = 0x00;
EA = 1; //開中斷
}

//*******************字節(jié)讀***************************

ucharByte_read(uint byte_addr)
{

ISP_CONTR = En_Wait_TIME;//開啟ISP/IAP;并送等待時間
ISP_CMD = Read_COM; //送字節(jié)讀命令字
ISP_ADDRH = (uchar)(byte_addr >> 8);//送地址高字節(jié)
ISP_ADDRL = (uchar)(byte_addr & 0X00FF);//送地址低字節(jié)
EA = 0;//關(guān)中斷
ISP_TRIG = 0X46;//送觸發(fā)命令字 0X46、0XB9
ISP_TRIG = 0XB9;
_nop_();
ISP_IAP_Disable(); //關(guān)閉ISP/IAP功能
EA = 1; //開中斷
return ((unsigned char)ISP_DATA);
}

//********************字節(jié)編程***********************

void Byte_program(uint byte_addr, uchar isp_iap_data)
{

ISP_CONTR = En_Wait_TIME;//開啟ISP/IAP;并送等待時間
ISP_CMD = Prog_COM; //送字節(jié)編程命令字
ISP_ADDRH = (uchar)(byte_addr >> 8);//送地址高字節(jié)
ISP_ADDRL = (uchar)(byte_addr & 0X00FF);//送地址低字節(jié)
ISP_DATA = isp_iap_data;//送數(shù)據(jù)進(jìn)ISP_DATA
EA = 0;//關(guān)中斷
ISP_TRIG = 0X46;//送觸發(fā)命令字 0X46、0XB9
ISP_TRIG = 0XB9;
_nop_();
ISP_IAP_Disable(); //關(guān)閉ISP/IAP功能
EA = 1; //開中斷
}

//********************* 扇區(qū)擦除*********************
voidSector_erase(uint sector_addr)
{

ISP_CONTR = En_Wait_TIME;//開啟ISP/IAP;并送等待時間
//ISP_CONTR=0xc1;
ISP_CMD = Dele_COM; //送扇區(qū)擦除命令字
ISP_ADDRH = (uchar)(sector_addr >> 8);//送地址高字節(jié)
ISP_ADDRL = (uchar)(sector_addr & 0X00FF);//送地址低字節(jié)
EA = 0;//關(guān)中斷
ISP_TRIG = 0X46;//送觸發(fā)命令字 0X46、0XB9
ISP_TRIG = 0XB9;
_nop_();
ISP_IAP_Disable(); //關(guān)閉ISP/IAP功能
EA = 1;
}


#ifndef _eeprom_h
#define _eeprom_H

//*********************EEPROM定義命令字節(jié)******************
#define Read_COM0X01//字節(jié)讀數(shù)據(jù)存儲區(qū)
#define Prog_COM0X02//字節(jié)編程數(shù)據(jù)存儲區(qū)
#define Dele_COM0X03//扇區(qū)擦除數(shù)據(jù)存儲區(qū)
#define En_Wait_TIME 0X81//設(shè)置等待時間 ,并使能ISP/IAP
//從用戶區(qū)啟動程序
//0X00==40MHZ以下,0X01==20MHZ以下
//0X02==10MHZ以下,0X03==5MHZ以下,現(xiàn)在設(shè)置了20MHZ以下的,
//
#define Start_ADDRH0X20 //扇區(qū)地址高位,STC89C/LE52RC
#define Start_ADDRL0X00 //扇區(qū)地址低位

#endif

注意了,要寫數(shù)據(jù)時,一定要對該扇區(qū)先擦除后寫數(shù)據(jù)的,所以要寫的數(shù)據(jù)盡量不要多,也可以對不同功能的數(shù)據(jù)存在不同的扇區(qū)里。如:

Sector_erase(0X2e00);//扇區(qū)擦除,第八個扇區(qū)
Byte_program(0X2e00,Eeprom_ReadCode);//寫EEPROM,保存可讀命令

要讀數(shù)據(jù)時,就直接讀就可以了。

ReadData=Byte_read(0X2002);//讀取該地址的數(shù)據(jù)

讀一個字節(jié)、編程一個字節(jié)、擦除一個扇區(qū)分別用時10us、60us、10ms



關(guān)鍵詞: STC單片機EEPRO

評論


技術(shù)專區(qū)

關(guān)閉