久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

關(guān)于STC單片機(jī)EEPROM的應(yīng)用總結(jié)

作者:劉佳喝   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時間:2014年03月16日   【字體:

 

當(dāng)在程序運(yùn)行的過程中你希望修改某個變量并且此變量的值在掉電以后不丟失,那么你就可以采用將變量數(shù)據(jù)寫入EEPROM的方式來實(shí)現(xiàn)。
什么是EEPROM,即Electrically Erasable ProgrammableRead_Only Memory首先它是一種存儲器,并且可以通過高電壓來進(jìn)行反復(fù)擦寫的存儲器。具有掉電數(shù)據(jù)不丟失的特點(diǎn)。比如常用的24C系列,93C系列的器件。一般這種器件采用I2C的方式與單片機(jī)進(jìn)行通訊,對于這種通訊方式及器件的應(yīng)用另作總結(jié)。這里主要總結(jié)一下,STC12C5204AD芯片內(nèi)部包含的EEPROM的應(yīng)用方法。
STC12C5201AD系列單片機(jī)內(nèi)部集成了EEPROM是與程序空間分開的,利用ISP/IAP技術(shù)可將內(nèi)部data flash當(dāng)EEPROM,擦寫10萬次以上。
EEPROM可分為若干個扇區(qū),每個扇區(qū)包含512字節(jié)。
使用時建議同一次修改的數(shù)據(jù)放在同一個扇區(qū),不是同一次修改的數(shù)據(jù)放在不同的扇區(qū),不一定要用滿。數(shù)據(jù)存儲器的擦除操作是按扇區(qū)進(jìn)行的。
在程序中可對EEPROM進(jìn)行字節(jié)讀寫/字節(jié)編程/扇區(qū)擦除操作。在工作電壓Vcc偏低時,建議不要進(jìn)行EEPROM/IAP操作。以免發(fā)生數(shù)據(jù)錯誤。
應(yīng)用的步驟
1、 聲明與EEPROM相關(guān)的寄存器
2、 編寫EEPROM初始化函數(shù)
3、 編寫字節(jié)擦除函數(shù)
4、 編寫字節(jié)編程函數(shù)
5、 編寫字節(jié)讀取函數(shù)
6、 在需要讀取EEPROM字節(jié)內(nèi)容時直接調(diào)用字節(jié)讀取函數(shù)即可
7、 在需要進(jìn)行寫EEPROM字節(jié)時,先調(diào)用字節(jié)擦除函數(shù),將字節(jié)內(nèi)容擦除成FFH后,在調(diào)用字節(jié)編程函數(shù),將數(shù)據(jù)寫入到EEPROM的地址單元中。
 
與EEPROM應(yīng)用相關(guān)的寄存器

符號
描述
地址
位地址及符號
復(fù)位值
IAP_DATA
ISP/IAP flash data register
C2H
 
 
 
 
 
 
 
 
1111 1111B
IAP_ADDRH
ISP/IAP flash address high
C3H
 
 
 
 
 
 
 
 
0000 0000B
IAP_ADDRL
ISP/IAP flash address low
C4H
 
 
 
 
 
 
 
 
 
IAP_CMD
ISP/IAP flash command register
C5H
 
 
 
 
 
 
MS1
MS0
 
IAP_TRIG
ISP/IAP flash command trigger
C6H
 
 
 
 
 
 
 
 
xxxxxxxxxB
IAP_CONTR
ISP/IAP control register
C7H
IAPEN
SWBS
SWRST
CMD_FAIL
 
WT2
WT1
WT0
0000X000B
PCON
Power control
87H
SOMD
SMOD0
LVDF
POF
GF1
GF0
PD
IDL
00110000B

1、IAP_DATA:ISP/IAP數(shù)據(jù)寄存器
     ISP/IAP操作時的數(shù)據(jù)寄存器。
ISP/IAP從FlASH讀出的數(shù)據(jù)存放此處,向flash寫的數(shù)據(jù)也需要放在此處。
2、 IAP_ADDRH和IAP_ADDRL :IAP/ISP地址寄存器
 
 
3、 IAP_CMD:ISP/IAP命令寄存器
 

MS1
MS0
命令/操作   模式選擇
0
0
Standby 待機(jī)模式,無ISP操作
0
1
從用戶程序區(qū)對“data flash /EEprom區(qū)”進(jìn)行字節(jié)讀
1
0
從用戶的應(yīng)用程序區(qū)對“data flash/eeprom區(qū)”進(jìn)行字節(jié)編寫
1
1
從用戶的應(yīng)用程序區(qū)對“data flash/eeprom區(qū)”進(jìn)行扇區(qū)擦除

4、IAP_TRIG:ISP/IAP命令觸發(fā)寄存器
在IAPEN(IAP_CONTR.7)=1時,對IAP——trig先寫入5AH,在寫入A5H,ISP\IAP命令才會生效
ISP\IAP操作完成后,IAP地址高8位寄存器IAP_ADDRH、IAP地址低8位寄存器IAP_ADDRL 和IAP命令寄存器IAP_CMD的內(nèi)容不變。如果接下來要對下一個地址的數(shù)據(jù)進(jìn)行IAP/ISP操作,需手動將該地址的高8位和低8位分別寫入IAP_ADDRH和IAP_ADDRL寄存器。
每次IAP操作時,都要對IAP_TRIG先寫入5AH,再寫入A5H,ISP/IAP命令才會生效。
5、IAP_CONTR:ISP\IAP控制寄存器

SFR name
Address
Bit
B7
B6
B5
B4
B3
B2
B1
B0
IAP_CONTR
C7H
Name
IAPEN
SWBS
SWRST
CMD_FAIL
_
WT2
WT1
WT0

IAPEN:ISP/IAP功能允許位:0:禁止IAP讀/寫/擦除 data flash /eeprom
                       1:允許IAP讀/寫/擦除 data flash /eeprom
SWBW:軟件選擇從用戶應(yīng)用程序區(qū)啟動(送0),還是從系統(tǒng)ISP監(jiān)控程序啟動(送1)。
      要與SWRST直接配合使用才可以實(shí)現(xiàn)
SWRST:0:不操作;1:產(chǎn)生軟件系統(tǒng)復(fù)位,硬件自動復(fù)位。
CMD_FAIL:如果送了ISP/IAP命令,并對IAP_TRIG送5AH/A5H觸發(fā)失敗,則為1,需由軟件清零。
在用戶應(yīng)用程序區(qū)(AP區(qū))軟件復(fù)位并從用戶應(yīng)用程序區(qū)(AP區(qū))開始執(zhí)行程序。
MOV IAP_CONTR,#00100000B;SWBS=0(選擇AP區(qū)),SWRST=1(軟復(fù)位)
在用戶應(yīng)用程序區(qū)(AP區(qū))軟件復(fù)位并從系統(tǒng)ISP監(jiān)控程序區(qū)開始執(zhí)行程序
MOV IAP_CONTR,#01100000B;SWBS=1(選擇ISP區(qū)),SWRST=1(軟復(fù)位)
在系統(tǒng)ISP監(jiān)控程序區(qū)軟件復(fù)位并從用戶應(yīng)用程序區(qū)(AP區(qū))開始執(zhí)行程序
MOV IAP_CONTR,#00100000B;SWBS=0(選擇AP區(qū))SWRST=1(軟復(fù)位)
在系統(tǒng)ISP監(jiān)控程序區(qū)軟件復(fù)位并從系統(tǒng)ISP監(jiān)控程序區(qū)開始執(zhí)行程序。
MOV IAP_CONTR,#01100000B;SWBS=1(選擇ISP區(qū)),SWRST=1(軟復(fù)位)
設(shè)置等待時間

設(shè)置等待時間
CPU等待時間(多少個CPU工作時鐘)
WT2
WT1
WT0
Read/讀
(2個時鐘)
Program/編程(=55us)
Sector erase
扇區(qū)擦除
=21us
Recommended system clock
跟等待參數(shù)對應(yīng)的推薦系統(tǒng)時鐘
 
1
1
1
2個時鐘
55個時鐘
21012個時鐘
<=1MHz
 
1
1
0
2個時鐘
110個時鐘
42024個時鐘
<=2MHz
 
1
0
1
2個時鐘
165個時鐘
63036個時鐘
<=3MHz
 
1
0
0
2個時鐘
330個時鐘
126072個時鐘
<=6MHz
 
0
1
1
2個時鐘
660個時鐘
252144個時鐘
<=12MHz
 
0
1
0
2個時鐘
1100個時鐘
420240個時鐘
<=20MHz
 
0
0
1
2個時鐘
1320個時鐘
504288個時鐘
<=24MHz
 
0
0
0
2個時鐘
1760個時鐘
672348個時鐘
<=30MHz
 

12c系列單片機(jī)內(nèi)部EEPROM選型一覽表

型號
字節(jié)數(shù)(eeprom)
扇區(qū)數(shù)
起始扇區(qū)首地址
結(jié)束扇區(qū)末尾地址
STC12C5201AD/PWM
2K
4
0000h
07ffh
STC12C5202AD/PWM
2k
4
0000h
07ffh
STC12C5203AD/PWM
2k
4
0000h
07ffh
STC12C5204AD/PWM
1k
2
0000h
03ffh
STC12C5205AD/PWM
1k
2
0000h
03ffh

 
大建議:
1、 同一次修改的數(shù)據(jù)放在同一個扇區(qū)中不是同一次修改的數(shù)據(jù)放在另外的扇區(qū)就不須讀出保護(hù)。
2、 如果一個扇區(qū)只用一個字節(jié),那就是真正的EEPROM,STC單片機(jī)的Data flash 比外部EEPROM要快很多讀一個字節(jié)/編程一個字節(jié)大概是2個時鐘/55微秒。
3、 如果在一個扇區(qū)中存放了大量的數(shù)據(jù),某次只需要修改其中的一個字節(jié)或一部分字節(jié)時,則另外的不需要修改的數(shù)據(jù)須先讀出放在STC單片機(jī)的RAM中,然后擦除整個扇區(qū),再將需要保留的數(shù)據(jù)和需修改的數(shù)據(jù)按字節(jié)逐字節(jié)寫回該扇區(qū)中(只有字節(jié)寫命令,無連續(xù)字節(jié)寫命令)。這時每個扇區(qū)使用的字節(jié)數(shù)是使用的越少越方便(不需要讀出一大堆需保留數(shù)據(jù))。
常見問題:
1、 IAP指令完成后,地址是否會自動” 加1”或“減1”?
不會
2、 送5A和A5觸發(fā)之后下一次IAP命令是否還需要送5A和A5觸發(fā)?
是,一定要。
STC12C5201AD/PWM單片機(jī)內(nèi)部EEPROM地址表

第一扇區(qū)
第二扇區(qū)
第三扇區(qū)
第四扇區(qū)
每個扇區(qū)
512字節(jié)
建議同一次修改的數(shù)據(jù)放在同一個扇區(qū),不是同一次修改的數(shù)據(jù)放在不同的扇區(qū),不必用滿,當(dāng)然也可以用滿。
起始地址
結(jié)束地址
起始地址
結(jié)束地址
起始地址
結(jié)束地址
起始地址
結(jié)束地址
0000h
1FFH
200H
3FFH
400H
5FFH
600H
7FFH
第五扇區(qū)
第六扇區(qū)
第七扇區(qū)
第八扇區(qū)
起始地址
結(jié)束地址
起始地址
結(jié)束地址
起始地址
結(jié)束地址
起始地址
結(jié)束地址
800H
9FFH
A00H
BFFH
C00H
DFFH
E00H
FFFH
第九扇區(qū)
第十扇區(qū)
第十一扇區(qū)
第十二扇區(qū)
起始地址
結(jié)束地址
起始地址
結(jié)束地址
起始地址
結(jié)束地址
起始地址
結(jié)束地址
1000H
11FFH
1200H
13FFH
1400H
15FFH
1600H
17FFH

 
下面就舉一個例子來說明一下EEPROM的應(yīng)用
   程序功能:
三個按鍵分別是,開關(guān)、增大、減小。通過7段數(shù)碼管將鍵值顯示出來(1-9)。
并將開關(guān)鍵關(guān)閉前的鍵值保存在EEPROM中,系統(tǒng)再次上電時顯示上次關(guān)閉前的鍵值。
 
 
 
 
#include<reg52.h>//頭文件
#include”intrins.h”
/******宏定義*************/
#define uintunsigned int//用unsigned int 代替unsigned int
#define ucharunsigned char//用uchar 替代unsigned char
/*********位定義**************/
sbit SW=P3^2;//開關(guān)
sbit INC=P3^3;//增大按鍵
sbit DEC=P3^4;//減小按鍵
sbitDATA=P1^5;//595數(shù)據(jù)流
sbitSHIFT=P1^6;//595移位寄存器
sbitSTORAGE=P1^7;//595存儲寄存器
sbitBEEP=P1^4;//蜂鳴器
/數(shù)碼管顯示代碼
uchar codenum[]={0x01,0xf3,0x89,0xa1,0xb2,0xa4,0x84,0xf1,0x80,0x20} ; //0-9代碼
 
//變量聲明
bit kai=0,biaozhi=0;
uchar MA,dat;
/*定義與EEPROM相關(guān)的特殊功能寄存器*/
sfrIAP_DATA=0XC2;//FLASH data register
sfrIAP_ADDRH=0XC3;//FLASH address high
sfrIAP_ADDRL=0XC4;//FLASH address low
sfrIAP_CMD=0XC5;//FLASH command register
sfrIAP_TRIG=0XC6;//FLSH command trigger
sfrIAP_CONTR=0XC7;//flash control register
/*定義IAP/ISP/EEPROM命令*/
#define CMD_IDLE0//stand_by
#define CMD_READ1//byte_read
#defineCMD_PROGRAM 2//byte_program
#defineCMD_ERASE   3//sector_erase
/*定義與EEPROM相關(guān)的寄存器 */
//#defineENABLE_IAP 0X80  //if sysclk<30MHz
//#defineENABLE_IAP 0X81  //if sysclk<24MHz
//#defineENABLE_IAP 0X82  //if sysclk<20MHz
#defineENABLE_IAP 0X83  //if sysclk<12MHz//定義控制寄存器
//#defineENABLE_IAP 0X84  //if sysclk<6MHz
//#defineENABLE_IAP 0X85  //if sysclk<3MHz
//#define ENABLE_IAP  0X86 //if sysclk<2MHz
//#defineENABLE_IAP 0X87  //if sysclk<1MHz
 
/*定義EEPROM 的起始地址*/
#defineIAP_ADDRESS 0X0000
 
/****初始化函數(shù)**********/
Void iapidle()
{
 IAP_CONTR=0;//關(guān)閉IAP功能
 IAP_CMD=0;//CMD寄存器初始化
 IAP_TRIG=0;//清空觸發(fā)寄存器
 IAP_ADDRH=0X80;//數(shù)據(jù)指針指向非EEPROM區(qū)
 IAP_ADDRL=0;//CLEAR IAP address to preventmisuse
}
/*讀EEPROM的一個字節(jié)地址的內(nèi)容
 輸入:地址
 輸出:EEPROM字節(jié)數(shù)據(jù)
 */
uchar iapreadbyte(uint addr)
{
 
 IAP_CONTR=ENABLE_IAP;//設(shè)置IAP控制寄存器
 IAP_CMD=CMD_READ;//設(shè)置IAP的命令寄存器為讀狀態(tài)
 IAP_ADDRL=addr;//設(shè)置EERPROM的低8位地址
 IAP_ADDRH=addr>>8;
 IAP_TRIG=0X5A;
 IAP_TRIG=0XA5;
 _nop_();
 dat=IAP_DATA;
 iapidle();
 return dat;
 
}
/*寫一個字節(jié)的IAP/ISP/EEPROM空間
 輸入: 字節(jié)地址
        要寫入的數(shù)據(jù)
Void iapprogrambyte(uint addr,uchar dat)
{
IAP_CONTR=ENABLE_IAP;//打開IAP功能并設(shè)置等待時間
IAP_CMD=CMD_PROGRAM;//設(shè)置寫命令
IAP_ADDRL=addr;//設(shè)置字節(jié)地址低8位
IAP_ADDRH=addr>>8;//設(shè)置字節(jié)地址的高8位
IAP_DATA=dat;//寫內(nèi)容
IAP_TRIG=0X5A;//發(fā)送觸發(fā)命令1
IAP_TRIG=0XA5;//發(fā)送觸發(fā)命令2
_nop_();//等待直到寫操作完成
Iapidle();
}
/*扇區(qū)擦除
輸入:地址
Void iaperasesector(uint addr)
{
 IAP_CONTR=ENABLE_IAP;//開IAP功能并設(shè)置等待時間
 IAP_CMD=CMD_ERASE;//設(shè)置擦除命令
 IAP_ADDRL=addr;
 IAP_ADDRH=addr>>8;
 IAP_TRIG=0x5a;
 IAP_TRIG=0XA5;
_nop_();
Iapidle();
}
/********寫595函數(shù)*******************/
void write_595(uchar x)
{
 uchar j;
 for(j=0;j<8;j++)
        {
          x=x<<1;
          SHIFT=0;
          _nop_();
          _nop_();
          _nop_();
          DATA=CY;
          SHIFT=1;
          _nop_();
          _nop_();
          _nop_();
          SHIFT=0;
 
         }
 
}
/********595輸出函數(shù)函數(shù)*******************/
void out_595(void)
{
 STORAGE=0;
 _nop_();
 _nop_();
 STORAGE=1;
 _nop_();
 _nop_();
 STORAGE=0;
 
}                
 
/*軟件延時 */
void delay(uchar t)
{ uchar x;
while(t--)
 {
for(x=0;x<250;x++)
 {
  _nop_();
  _nop_();
  _nop_();
  _nop_();
 }
 }
}
/******按鍵檢測函數(shù)**********************/
void keycheck(void)
{
 if(SW==0)//判斷開關(guān)按鍵是否按下
    {delay(10);//抗干擾
     if(SW==0)//確實(shí)按下
                {kai=~kai;
                    }
                    while(!SW)//一直按下
                    {BEEP=1;}//蜂鳴器響
                    BEEP=0;//松開按鍵,蜂鳴器關(guān)閉
           }
 if(INC==0&kai==1&MA<9)//如果處于開的狀態(tài)并且數(shù)字小于9則按下增大鍵執(zhí)行
        {
          delay(10);
          if(INC==0&kai&MA<9)
                 {MA++;}
                   while(!INC)
                   {BEEP=1;}
                   BEEP=0;
         }
 if(DEC==0&kai&MA>1)
      {
          delay(10);
          if(DEC==0&kai&MA>1)
                 {MA--;}
                   while(!DEC)
                   {BEEP=1;}
                   BEEP=0;
         }
  if(kai==1) //如果電源打開了,則將電源開的狀態(tài)標(biāo)志置1
  {biaozhi=1;}
  if(biaozhi==1&kai==0)//判斷電源打開后被關(guān)閉,目的是只在開關(guān)鍵關(guān)閉時,寫一次EEPROM,避免不停的擦寫EEPROM
    { biaozhi=0;
            iaperasesector(0x00);
            programbyte(0x00,MA);
                        // 執(zhí)行EEPROM寫程
           }
   }
//主函數(shù)
Void main(void )
{
 
  BEEP=0; //關(guān)閉蜂鳴器
 iapreadbyte(0x00);//讀出EEPROM的值
MA=dat;
if(MA<1|MA>9)//如果讀出的值不在1-9范圍內(nèi)則強(qiáng)制為5.
{MA=5;}
 while(1)
 {
 keycheck();//執(zhí)行按鍵掃描程序
 write_595(num[MA]);
 write_595(num[MA]);
 out_595();
 }
}
這只是一個簡單的讀寫一個字節(jié)的簡單測試程序,對于扇區(qū)擦除的結(jié)果也沒有進(jìn)行驗(yàn)證。
想要驗(yàn)證需要在加一段代碼。具體請參照STC的數(shù)據(jù)手冊。
關(guān)閉窗口

相關(guān)文章

主站蜘蛛池模板: 国产免费观看视频 | 久久久蜜臀国产一区二区 | 日一区二区三区 | 国产97在线 | 日韩 | 中文字幕在线不卡播放 | 久久久免费 | 日韩精品在线网站 | 国产精品久久久久久久久久三级 | 最近中文字幕第一页 | 2020天天操| 欧美精品被 | 久久中文字幕一区 | 国产精品久久久久久吹潮日韩动画 | www.玖玖玖 | 天堂资源最新在线 | 精品视频一区二区三区四区 | 国产一区欧美 | 99久久婷婷国产综合精品电影 | 免费在线观看毛片 | 最新高清无码专区 | 一区二区国产在线 | 九九色综合 | 中文字幕成人免费视频 | 91资源在线 | 97国产一区二区精品久久呦 | 亚洲欧美激情网 | 日韩久久久一区二区 | 日韩在线免费视频 | 亚洲一区二区三区四区五区中文 | av黄在线观看 | 特黄色一级毛片 | 国产欧美日韩精品一区 | 欧美国产一区二区 | 亚洲免费一区二区 | 一级亚洲| 国产一区二区三区四区hd | 日韩国产精品一区二区三区 | 午夜影院黄 | 久久久91| 国产高清性xxxxxxxx | 99re视频|