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

專注電子技術學習與研究
當前位置:單片機教程網 >> MCU設計實例 >> 瀏覽文章

關于STC單片機EEPROM的應用總結

作者:劉佳喝   來源:本站原創   點擊數:  更新時間:2014年03月16日   【字體:

 

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

符號
描述
地址
位地址及符號
復位值
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數據寄存器
     ISP/IAP操作時的數據寄存器。
ISP/IAP從FlASH讀出的數據存放此處,向flash寫的數據也需要放在此處。
2、 IAP_ADDRH和IAP_ADDRL :IAP/ISP地址寄存器
 
 
3、 IAP_CMD:ISP/IAP命令寄存器
 

MS1
MS0
命令/操作   模式選擇
0
0
Standby 待機模式,無ISP操作
0
1
從用戶程序區對“data flash /EEprom區”進行字節讀
1
0
從用戶的應用程序區對“data flash/eeprom區”進行字節編寫
1
1
從用戶的應用程序區對“data flash/eeprom區”進行扇區擦除

4、IAP_TRIG:ISP/IAP命令觸發寄存器
在IAPEN(IAP_CONTR.7)=1時,對IAP——trig先寫入5AH,在寫入A5H,ISP\IAP命令才會生效
ISP\IAP操作完成后,IAP地址高8位寄存器IAP_ADDRH、IAP地址低8位寄存器IAP_ADDRL 和IAP命令寄存器IAP_CMD的內容不變。如果接下來要對下一個地址的數據進行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:軟件選擇從用戶應用程序區啟動(送0),還是從系統ISP監控程序啟動(送1)。
      要與SWRST直接配合使用才可以實現
SWRST:0:不操作;1:產生軟件系統復位,硬件自動復位。
CMD_FAIL:如果送了ISP/IAP命令,并對IAP_TRIG送5AH/A5H觸發失敗,則為1,需由軟件清零。
在用戶應用程序區(AP區)軟件復位并從用戶應用程序區(AP區)開始執行程序。
MOV IAP_CONTR,#00100000B;SWBS=0(選擇AP區),SWRST=1(軟復位)
在用戶應用程序區(AP區)軟件復位并從系統ISP監控程序區開始執行程序
MOV IAP_CONTR,#01100000B;SWBS=1(選擇ISP區),SWRST=1(軟復位)
在系統ISP監控程序區軟件復位并從用戶應用程序區(AP區)開始執行程序
MOV IAP_CONTR,#00100000B;SWBS=0(選擇AP區)SWRST=1(軟復位)
在系統ISP監控程序區軟件復位并從系統ISP監控程序區開始執行程序。
MOV IAP_CONTR,#01100000B;SWBS=1(選擇ISP區),SWRST=1(軟復位)
設置等待時間

設置等待時間
CPU等待時間(多少個CPU工作時鐘)
WT2
WT1
WT0
Read/讀
(2個時鐘)
Program/編程(=55us)
Sector erase
扇區擦除
=21us
Recommended system clock
跟等待參數對應的推薦系統時鐘
 
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系列單片機內部EEPROM選型一覽表

型號
字節數(eeprom)
扇區數
起始扇區首地址
結束扇區末尾地址
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、 同一次修改的數據放在同一個扇區中不是同一次修改的數據放在另外的扇區就不須讀出保護。
2、 如果一個扇區只用一個字節,那就是真正的EEPROM,STC單片機的Data flash 比外部EEPROM要快很多讀一個字節/編程一個字節大概是2個時鐘/55微秒。
3、 如果在一個扇區中存放了大量的數據,某次只需要修改其中的一個字節或一部分字節時,則另外的不需要修改的數據須先讀出放在STC單片機的RAM中,然后擦除整個扇區,再將需要保留的數據和需修改的數據按字節逐字節寫回該扇區中(只有字節寫命令,無連續字節寫命令)。這時每個扇區使用的字節數是使用的越少越方便(不需要讀出一大堆需保留數據)。
常見問題:
1、 IAP指令完成后,地址是否會自動” 加1”或“減1”?
不會
2、 送5A和A5觸發之后下一次IAP命令是否還需要送5A和A5觸發?
是,一定要。
STC12C5201AD/PWM單片機內部EEPROM地址表

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

 
下面就舉一個例子來說明一下EEPROM的應用
   程序功能:
三個按鍵分別是,開關、增大、減小。通過7段數碼管將鍵值顯示出來(1-9)。
并將開關鍵關閉前的鍵值保存在EEPROM中,系統再次上電時顯示上次關閉前的鍵值。
 
 
 
 
#include<reg52.h>//頭文件
#include”intrins.h”
/******宏定義*************/
#define uintunsigned int//用unsigned int 代替unsigned int
#define ucharunsigned char//用uchar 替代unsigned char
/*********位定義**************/
sbit SW=P3^2;//開關
sbit INC=P3^3;//增大按鍵
sbit DEC=P3^4;//減小按鍵
sbitDATA=P1^5;//595數據流
sbitSHIFT=P1^6;//595移位寄存器
sbitSTORAGE=P1^7;//595存儲寄存器
sbitBEEP=P1^4;//蜂鳴器
/數碼管顯示代碼
uchar codenum[]={0x01,0xf3,0x89,0xa1,0xb2,0xa4,0x84,0xf1,0x80,0x20} ; //0-9代碼
 
//變量聲明
bit kai=0,biaozhi=0;
uchar MA,dat;
/*定義與EEPROM相關的特殊功能寄存器*/
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相關的寄存器 */
//#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
 
/****初始化函數**********/
Void iapidle()
{
 IAP_CONTR=0;//關閉IAP功能
 IAP_CMD=0;//CMD寄存器初始化
 IAP_TRIG=0;//清空觸發寄存器
 IAP_ADDRH=0X80;//數據指針指向非EEPROM區
 IAP_ADDRL=0;//CLEAR IAP address to preventmisuse
}
/*讀EEPROM的一個字節地址的內容
 輸入:地址
 輸出:EEPROM字節數據
 */
uchar iapreadbyte(uint addr)
{
 
 IAP_CONTR=ENABLE_IAP;//設置IAP控制寄存器
 IAP_CMD=CMD_READ;//設置IAP的命令寄存器為讀狀態
 IAP_ADDRL=addr;//設置EERPROM的低8位地址
 IAP_ADDRH=addr>>8;
 IAP_TRIG=0X5A;
 IAP_TRIG=0XA5;
 _nop_();
 dat=IAP_DATA;
 iapidle();
 return dat;
 
}
/*寫一個字節的IAP/ISP/EEPROM空間
 輸入: 字節地址
        要寫入的數據
Void iapprogrambyte(uint addr,uchar dat)
{
IAP_CONTR=ENABLE_IAP;//打開IAP功能并設置等待時間
IAP_CMD=CMD_PROGRAM;//設置寫命令
IAP_ADDRL=addr;//設置字節地址低8位
IAP_ADDRH=addr>>8;//設置字節地址的高8位
IAP_DATA=dat;//寫內容
IAP_TRIG=0X5A;//發送觸發命令1
IAP_TRIG=0XA5;//發送觸發命令2
_nop_();//等待直到寫操作完成
Iapidle();
}
/*扇區擦除
輸入:地址
Void iaperasesector(uint addr)
{
 IAP_CONTR=ENABLE_IAP;//開IAP功能并設置等待時間
 IAP_CMD=CMD_ERASE;//設置擦除命令
 IAP_ADDRL=addr;
 IAP_ADDRH=addr>>8;
 IAP_TRIG=0x5a;
 IAP_TRIG=0XA5;
_nop_();
Iapidle();
}
/********寫595函數*******************/
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輸出函數函數*******************/
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_();
 }
 }
}
/******按鍵檢測函數**********************/
void keycheck(void)
{
 if(SW==0)//判斷開關按鍵是否按下
    {delay(10);//抗干擾
     if(SW==0)//確實按下
                {kai=~kai;
                    }
                    while(!SW)//一直按下
                    {BEEP=1;}//蜂鳴器響
                    BEEP=0;//松開按鍵,蜂鳴器關閉
           }
 if(INC==0&kai==1&MA<9)//如果處于開的狀態并且數字小于9則按下增大鍵執行
        {
          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) //如果電源打開了,則將電源開的狀態標志置1
  {biaozhi=1;}
  if(biaozhi==1&kai==0)//判斷電源打開后被關閉,目的是只在開關鍵關閉時,寫一次EEPROM,避免不停的擦寫EEPROM
    { biaozhi=0;
            iaperasesector(0x00);
            programbyte(0x00,MA);
                        // 執行EEPROM寫程
           }
   }
//主函數
Void main(void )
{
 
  BEEP=0; //關閉蜂鳴器
 iapreadbyte(0x00);//讀出EEPROM的值
MA=dat;
if(MA<1|MA>9)//如果讀出的值不在1-9范圍內則強制為5.
{MA=5;}
 while(1)
 {
 keycheck();//執行按鍵掃描程序
 write_595(num[MA]);
 write_595(num[MA]);
 out_595();
 }
}
這只是一個簡單的讀寫一個字節的簡單測試程序,對于扇區擦除的結果也沒有進行驗證。
想要驗證需要在加一段代碼。具體請參照STC的數據手冊。
關閉窗口

相關文章

主站蜘蛛池模板: 亚洲精品久久久一区二区三区 | 97免费在线视频 | 欧美日韩18 | 国产精品久久在线 | 丝袜毛片 | 亚洲欧美日韩精品久久亚洲区 | 欧美国产一区二区 | 欧美国产一区二区 | 天天综合网天天综合 | 国产精品久久久久久妇女6080 | 91观看 | 久久久国产一区二区三区 | 一区二区三区回区在观看免费视频 | 成人黄色电影免费 | av毛片| 999视频| 国产精品久久福利 | 久久国产精品久久久久久 | 中文字幕一区二区三区在线视频 | 国产日韩精品在线 | 国产午夜久久 | 99免费看 | va精品| 亚洲精品久久久久久下一站 | 深夜福利亚洲 | 免费看色| 欧美日韩精品国产 | 男女免费观看在线爽爽爽视频 | 日屁网站 | 久久国产精品免费视频 | 成人精品一区二区三区中文字幕 | 久久网一区二区 | 成人在线一区二区三区 | 亚洲精品久久久久久久久久久久久 | 丁香五月网久久综合 | 成人日韩 | 国产丝袜一区二区三区免费视频 | 成人影院免费视频 | 午夜三级网站 | 在线视频中文字幕 | 国产九九精品 |