一、STC15F2K60S2單片機(jī)內(nèi)部EEPROM的介紹
STC15系列單片機(jī)內(nèi)部集成了大容量的EEPROM,其與程序空間是分開的。利用ISP/IAP技術(shù)可將內(nèi)部Date Flash當(dāng)EEPROM,擦寫次數(shù)在10萬次以上。EEPROM可分為若干個(gè)扇區(qū),每個(gè)扇區(qū)包含512個(gè)字節(jié)。使用時(shí),建議同一次修改的數(shù)據(jù)放在同一個(gè)扇區(qū),不是同一次修改的數(shù)據(jù)放在不同的扇區(qū),不一定要用滿。數(shù)據(jù)存儲(chǔ)器的擦出操作是按扇區(qū)進(jìn)行的。
EEPROM可用于保存一些需要在應(yīng)用過程中修改并且掉電不丟失的參數(shù)數(shù)據(jù)。在用戶程序中,可以對(duì)EEPROM進(jìn)行字節(jié)讀/字節(jié)編程/扇區(qū)擦除操作。在工作電壓Vcc偏低時(shí),建議不要進(jìn)行EEPROM/IAP操作。
圖1 STC15F2K60S2系列EEPROM空間大小及地址圖
注:以上內(nèi)容選自STC15系列單片機(jī)官方指南書。
通過對(duì)STC15系列單片機(jī)官方指南書的查閱可知,IAP15系列除外,STC15F2K60S2系列單片機(jī)可通過圖1的地址空間開始對(duì)其內(nèi)部EEPROM進(jìn)行數(shù)據(jù)的讀寫,而IAP15系列可在用戶應(yīng)用程序區(qū)修改用戶應(yīng)用程序區(qū),一般從結(jié)束扇區(qū)末尾地址開始計(jì)算。
后面將會(huì)給出STC15系列單片機(jī)內(nèi)部EEPROM的驅(qū)動(dòng)程序,只需要調(diào)用EEPROM_Read(UINT16 eeprom_address,UINT8 *data_address,UINT8 length)和EEPROM_Write(UINT16 eeprom_address,UINT8 *data_address,UINT8 length)兩個(gè)函數(shù)即可。
二、STC15F2K60S2內(nèi)部EEPROM讀寫的驅(qū)動(dòng)程序
1.頭文件
#ifndef EEPROM_H
#define EEPROM_H
#include "STC15F2K60S2.h"
#include
#ifndef UINT8
#define UINT8 unsigned char
#endif
#ifndef UINT16
#define UINT16 unsigned int
#endif
#ifndef EEPROM_BUFFER_LENGTH
#define EEPROM_BUFFER_LENGTH 128 //數(shù)據(jù)保護(hù)緩沖長(zhǎng)度
#endif
#define ISP_STANDBY() ISP_CMD = 0 //ISP空閑命令(禁止)
#define ISP_READ() ISP_CMD = 1 //ISP讀出命令
#define ISP_WRITE() ISP_CMD = 2 //ISP寫入命令
#define ISP_ERASE() ISP_CMD = 3 //ISP擦除命令
//sfr ISP_TRIG = 0xC6;
#define ISP_TRIG() ISP_TRIG = 0x5A, ISP_TRIG = 0xA5 //ISP觸發(fā)命令
// 7 6 5 4 3 2 1 0 Reset Value
//sfr IAP_CONTR = 0xC7; IAPEN SWBS SWRST CFAIL - WT2 WT1 WT0 0000,x000 //IAP Control Register
#define ISP_EN (1<<7)
#define ISP_SWBS (1<<6)
#define ISP_SWRST (1<<5)
#define ISP_CMD_FAIL (1<<4)
#define ISP_WAIT_1MHZ 7
#define ISP_WAIT_2MHZ 6
#define ISP_WAIT_3MHZ 5
#define ISP_WAIT_6MHZ 4
#define ISP_WAIT_12MHZ 3
#define ISP_WAIT_20MHZ 2
#define ISP_WAIT_24MHZ 1
#define ISP_WAIT_30MHZ 0
#if (MAIN_Fosc >= 24000000L)
#define ISP_WAIT_FREQUENCY ISP_WAIT_30MHZ
#elif (MAIN_Fosc >= 20000000L)
#define ISP_WAIT_FREQUENCY ISP_WAIT_24MHZ
#elif (MAIN_Fosc >= 12000000L)
#define ISP_WAIT_FREQUENCY ISP_WAIT_20MHZ
#elif (MAIN_Fosc >= 6000000L)
#define ISP_WAIT_FREQUENCY ISP_WAIT_12MHZ
#elif (MAIN_Fosc >= 3000000L)
#define ISP_WAIT_FREQUENCY ISP_WAIT_6MHZ
#elif (MAIN_Fosc >= 2000000L)
#define ISP_WAIT_FREQUENCY ISP_WAIT_3MHZ
#elif (MAIN_Fosc >= 1000000L)
#define ISP_WAIT_FREQUENCY ISP_WAIT_2MHZ
#else
#define ISP_WAIT_FREQUENCY ISP_WAIT_1MHZ
#endif
sfr ISP_DATA = 0xC2;
sfr ISP_ADDRH = 0xC3;
sfr ISP_ADDRL = 0xC4;
sfr ISP_CMD = 0xC5;
sfr ISP_TRIG = 0xC6;
sfr ISP_CONTR = 0xC7;
//定義特殊功能寄存器
void EEPROM_Disable();//關(guān)閉eeprom讀寫
void EEPROM_SectorErase(UINT16 eeprom_address);//扇區(qū)擦除
void EEPROM_Read(UINT16 eeprom_address,UINT8*data_address,UINT8 length);//讀數(shù)據(jù)
void EEPROM_Write(UINT16 eeprom_address,UINT8*data_address,UINT8 length);//寫數(shù)據(jù)
#endif
2.主程序
#include "EEPROM.h"
//STC系列的內(nèi)置EEPROM讀寫程序。
/************************************************************************
*STC15F2K60S2的EEPROM空間地址范圍:0x0000 - 0x03FF (IAP字節(jié)讀取)(1K)
*使用例程:
EEPROM_Read(0x0000,medication_lost_warning_phone_3,12);
EEPROM_Write(0x0000,medication_lost_warning_phone_3,12);
*************************************************************************/
//========================================================================
// 函數(shù): void EEPROM_Disable()
// 描述: 禁止訪問ISP/IAP.
// 參數(shù): non.
// 返回: non.
//========================================================================
void EEPROM_Disable()
{
ISP_CONTR= 0; //禁止ISP/IAP操作
ISP_CMD = 0; //去除ISP/IAP命令
ISP_TRIG = 0; //防止ISP/IAP命令誤觸發(fā)
ISP_ADDRH= 0xff; //清0地址高字節(jié)
ISP_ADDRL= 0xff; //清0地址低字節(jié),指向非EEPROM區(qū),防止誤操作
}
//========================================================================
// 函數(shù): void EEPROM_Read(UINT16 eeprom_address,UINT8 *data_address,UINT8 length)
// 描述: 從指定EEPROM首地址讀出n個(gè)字節(jié)放指定的緩沖.
// 參數(shù): eeprom_address: 讀出EEPROM的首地址.
// data_address: 讀出數(shù)據(jù)放緩沖的首地址.
// length: 讀出的字節(jié)長(zhǎng)度.
// 返回: non.
//========================================================================
void EEPROM_Read(UINT16 eeprom_address,UINT8*data_address,UINT8 length)
{
EA =0; //禁止中斷
ET0 =0;
ISP_CONTR= (ISP_EN + 3); //設(shè)置等待時(shí)間,允許ISP/IAP操作,送一次就夠
ISP_READ(); //送字節(jié)讀命令,命令不需改變時(shí),不需重新送命令
do
{
ISP_ADDRH= eeprom_address / 256; //送地址高字節(jié)(地址需要改變時(shí)才需重新送地址)
ISP_ADDRL= eeprom_address % 256; //送地址低字節(jié)
ISP_TRIG(); //先送5AH,再送A5H到ISP/IAP觸發(fā)寄存器,每次都需要如此
//送完A5H后,ISP/IAP命令立即被觸發(fā)啟動(dòng)
//CPU等待IAP完成后,才會(huì)繼續(xù)執(zhí)行程序。
_nop_();
*data_address= ISP_DATA; //讀出的數(shù)據(jù)送往
eeprom_address++;
data_address++;
}while(--length);
EEPROM_Disable();
EA =1; //重新允許中斷
ET0 =1;
}
//========================================================================
// 函數(shù): void EEPROM_SectorErase(UINT16 eeprom_address)
// 描述: 把指定地址的EEPROM扇區(qū)擦除.
// 參數(shù): eeprom_address: 要擦除的扇區(qū)EEPROM的地址.
// 返回: non.
//========================================================================
void EEPROM_SectorErase(UINT16 eeprom_address)
{
EA =0; //禁止中斷
ET0 =0;
//只有扇區(qū)擦除,沒有字節(jié)擦除,512字節(jié)/扇區(qū)。
//扇區(qū)中任意一個(gè)字節(jié)地址都是扇區(qū)地址。
ISP_ADDRH= eeprom_address / 256; //送扇區(qū)地址高字節(jié)(地址需要改變時(shí)才需重新送地址)
ISP_ADDRL= eeprom_address % 256; //送扇區(qū)地址低字節(jié)
ISP_CONTR= (ISP_EN + 3); //設(shè)置等待時(shí)間,允許ISP/IAP操作,送一次就夠
ISP_ERASE(); //送扇區(qū)擦除命令,命令不需改變時(shí),不需重新送命令
ISP_TRIG();
_nop_();
EEPROM_Disable();
EA =1; //重新允許中斷
ET0 =1;
}
//========================================================================
// 函數(shù): void EEPROM_Write(UINT16 eeprom_address,UINT8 *data_address,UINT8 length)
// 描述: 把緩沖的n個(gè)字節(jié)寫入指定首地址的EEPROM.
// 參數(shù): eeprom_address: 寫入EEPROM的首地址.
// data_address: 寫入源數(shù)據(jù)的緩沖的首地址.
// length: 寫入的字節(jié)長(zhǎng)度.
// 返回: non.
//========================================================================
void EEPROM_Write(UINT16 eeprom_address,UINT8*data_address,UINT8 length)
{
UINT8 sector_location;//待寫入數(shù)據(jù)在扇區(qū)內(nèi)的起始地址
UINT8 xdata data_buffer[EEPROM_BUFFER_LENGTH];
UINT16i;
sector_location= (UINT8)(eeprom_address & 0x01ff);
eeprom_address&= 0xfe00;
EEPROM_Read(eeprom_address,data_buffer,EEPROM_BUFFER_LENGTH);
for(i=0;i< length; i++)
{
data_buffer[sector_location+i]= data_address[i];
}
EEPROM_SectorErase(eeprom_address);
length= EEPROM_BUFFER_LENGTH;
data_address= data_buffer;
EA =0; //禁止中斷
ET0 =0;
ISP_CONTR= (ISP_EN + 3); //設(shè)置等待時(shí)間,允許ISP/IAP操作,送一次就夠
ISP_WRITE(); //送字節(jié)寫命令,命令不需改變時(shí),不需重新送命令
do
{
ISP_ADDRH= eeprom_address / 256; //送地址高字節(jié)(地址需要改變時(shí)才需重新送地址)
ISP_ADDRL= eeprom_address % 256; //送地址低字節(jié)
ISP_DATA = *data_address; //送數(shù)據(jù)到ISP_DATA,只有數(shù)據(jù)改變時(shí)才需重新送
ISP_TRIG();
_nop_();
eeprom_address++;
data_address++;
}while(--length);
EEPROM_Disable();
EA =1; //重新允許中斷
ET0 =1;
}
-
驅(qū)動(dòng)器
+關(guān)注
關(guān)注
54文章
8697瀏覽量
150006 -
EEPROM
+關(guān)注
關(guān)注
9文章
1086瀏覽量
83781 -
STC15F2K60S2
+關(guān)注
關(guān)注
9文章
25瀏覽量
17531 -
Flash存儲(chǔ)
+關(guān)注
關(guān)注
0文章
40瀏覽量
8443 -
數(shù)據(jù)存儲(chǔ)器
+關(guān)注
關(guān)注
1文章
69瀏覽量
17992
發(fā)布評(píng)論請(qǐng)先 登錄
STC15F2K60S2單片機(jī)的特點(diǎn)有哪些呢
STC15F2K60S2具有哪些引腳功能?
STC15F2K60S2單片機(jī)電路原理圖的詳細(xì)資料免費(fèi)下載

單片機(jī)STC15F2K60S2的詳細(xì)資料和程序資料說明
STC15F2K60S2單片機(jī)的使用程序免費(fèi)下載

使用STC15F2K60S2單片機(jī)驅(qū)動(dòng)PWM的程序免費(fèi)下載

STC15F2K60S2系列學(xué)習(xí)板原理圖免費(fèi)下載

stc15f2k60s2單片機(jī)開發(fā)環(huán)境構(gòu)建

單片機(jī)學(xué)習(xí)筆記——雙機(jī)通信(型號(hào):STC15F2K60S2)

評(píng)論