<acronym id="xonnx"></acronym>
      <td id="xonnx"></td>
    1. <pre id="xonnx"></pre>

      1. 專注電子技術學習與研究
        當前位置:單片機教程網 >> 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的數據手冊。
        關閉窗口

        相關文章

        欧美性色欧美精品视频,99热这里只有精品mp4,日韩高清亚洲日韩精品一区二区,2020国自产拍精品高潮