在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > STC單片機(jī)內(nèi)部EEPROM的應(yīng)用

            STC單片機(jī)內(nèi)部EEPROM的應(yīng)用

            作者: 時(shí)間:2016-11-13 來源:網(wǎng)絡(luò) 收藏
            單片機(jī)運(yùn)行時(shí)的數(shù)據(jù)都存在于RAM(隨機(jī)存儲(chǔ)器)中,在掉電后RAM中的數(shù)據(jù)是無法保留的,那么怎樣使數(shù)據(jù)在掉電后不丟失呢?這就需要使用EEPROM或FLASHROM等存儲(chǔ)器來實(shí)現(xiàn)。在傳統(tǒng)的單片機(jī)系統(tǒng)中,一般是在片外擴(kuò)展存儲(chǔ)器,單片機(jī)與存儲(chǔ)器之間通過IIC或SPI等接口來進(jìn)行數(shù)據(jù)通信。這樣不光會(huì)增加開發(fā)成本,同時(shí)在程序開發(fā)上也要花更多的心思。在STC單片機(jī)中內(nèi)置了EEPROM(其實(shí)是采用IAP技術(shù)讀寫內(nèi)部FLASH來實(shí)現(xiàn)EEPROM),這樣就節(jié)省了片外資源,使用起來也更加方便。下面就詳細(xì)介紹STC單片機(jī)內(nèi)置EEPROM及其使用方法。

            STC各型號(hào)單片機(jī)內(nèi)置的EEPROM的容量各有不同,見下表:

            本文引用地址:http://www.biyoush.com/article/201611/316202.htm

            單片機(jī)芯片型號(hào)

            起始地址

            內(nèi)置EEPROM容量(每扇區(qū)512字節(jié))

            STC89C51RC,STC89LE51RC

            0x2000

            共八個(gè)扇區(qū)

            STC89C52RC,STC89LE52RC

            0x2000

            共八個(gè)扇區(qū)

            STC89C54RD+,STC89LE54RD+

            0x8000

            共五十八個(gè)扇區(qū)

            STC89C55RD+,STC89LE55RD+

            0x8000

            共五十八個(gè)扇區(qū)

            STC89C58RD+,STC89LE58RD+

            0x8000

            共五十八個(gè)扇區(qū)

            內(nèi)部EEPROM可以擦寫100000次以上)

            上面提到了IAP,它的意思是“在應(yīng)用編程”,即在程序運(yùn)行時(shí)程序存儲(chǔ)器可由程序自身進(jìn)行擦寫。正是是因?yàn)橛辛薎AP,從而可以使單片機(jī)可以將數(shù)據(jù)寫入到程序存儲(chǔ)器中,使得數(shù)據(jù)如同燒入的程序一樣,掉電不丟失。當(dāng)然寫入數(shù)據(jù)的區(qū)域與程序存儲(chǔ)區(qū)要分開來,以使程序不會(huì)遭到破壞。

            要使用IAP功能,與以下幾個(gè)特殊功能寄存器相關(guān):

            寄存器標(biāo)識(shí)

            地址

            名稱

            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

            ISP_DATA: ISP/IAP操作時(shí)的數(shù)據(jù)寄存器。

            ISP/IAP從Flash讀出的數(shù)據(jù)放在此處,向Flash寫的數(shù)據(jù)也需放在此處

            ISP_ADDRH:ISP/IAP操作時(shí)的地址寄存器高八位。

            ISP_ADDRL:ISP/IAP操作時(shí)的地址寄存器低八位。

            ISP_CMD: ISP/IAP操作時(shí)的命令模式寄存器,須命令觸發(fā)寄存器觸發(fā)方可生效。

            B7

            B6

            B5

            B4

            B3

            B2

            B1

            B0

            命令/操作模式選擇

            保留

            命令選擇

            0

            0

            0

            待機(jī)模式,無ISP/IAP操作

            0

            0

            1

            對(duì)用戶的應(yīng)用程序Flash區(qū)及數(shù)據(jù)Flash區(qū)字節(jié)讀

            0

            1

            0

            對(duì)用戶的應(yīng)用程序Flash區(qū)及數(shù)據(jù)Flash區(qū)字節(jié)編程

            0

            1

            1

            對(duì)用戶的應(yīng)用程序Flash區(qū)及數(shù)據(jù)Flash區(qū)扇區(qū)擦除

            ISP_TRIG:ISP/IAP操作時(shí)的命令觸發(fā)寄存器。

            當(dāng)ISPEN(ISP_CONTR.7)=1時(shí),對(duì)ISP_TRIG先寫入0x46,再寫入0xb9,ISP/IAP命令才會(huì)生效。

            ISP_CONTR:ISP/IAP控制寄存器。

            D7

            D6

            D5

            D4

            D3

            D2

            D1

            D0

            ISPEN

            SWBS

            SWRST

            WT2

            WT1

            WT0

            ISPEN:ISP/IAP功能允許位。0:禁止ISP/IAP編程改變Flash,1:允許編程改變Flash

            SWBS:軟件選擇從用戶主程序區(qū)啟動(dòng)(0),還是從ISP程序區(qū)啟動(dòng)(1)。

            SWRST:0:不操作,1:產(chǎn)生軟件系統(tǒng)復(fù)位,硬件自動(dòng)清零。

            ISP_CONTR中的SWBS與SWRST這兩個(gè)功能位,可以實(shí)現(xiàn)單片機(jī)的軟件啟動(dòng),并啟動(dòng)到ISP區(qū)或用戶程序區(qū),這在“STC單片機(jī)自動(dòng)下載”一節(jié),亦有所應(yīng)用。

            如:

            ISP_CONTR=0x60; 則可以實(shí)現(xiàn)從用戶應(yīng)用程序區(qū)軟件復(fù)位到ISP程序區(qū)開始運(yùn)行程序。

            ISP_CONTR=0x20; 則可以實(shí)現(xiàn)從ISP程序區(qū)軟件復(fù)位到用戶應(yīng)用程序區(qū)開始運(yùn)行程序。

            用IAP向Flash中讀寫數(shù)據(jù),是需要一定的讀寫時(shí)間的,讀寫數(shù)據(jù)命令發(fā)出后,要等待一段時(shí)間才可以讀寫成功。這個(gè)等待時(shí)間就是由WT2、WT1、WT0與晶體振蕩器頻率決定的。

            設(shè)置等待時(shí)間

            CPU等待時(shí)間(機(jī)器周期)

            WT2

            WT1

            WT0

            讀取

            編程

            扇區(qū)擦除

            建議的系統(tǒng)時(shí)鐘

            0

            1

            1

            6

            30

            5471

            5MHz

            0

            1

            0

            11

            60

            10942

            10MHz

            0

            0

            1

            22

            120

            21885

            20MHz

            0

            0

            0

            43

            240

            43769

            40MHz

            (以上的建議時(shí)鐘是(WT2、WT1、WT0)取不同的值時(shí)的標(biāo)稱時(shí)鐘,用戶系統(tǒng)中的時(shí)鐘不要過高,否則可能使操作不穩(wěn)定。)

            以下是具體的實(shí)現(xiàn)代碼:

            EEPROM操作函數(shù):

            #define RdCommand 0x01

            #define PrgCommand 0x02

            #define EraseCommand 0x03

            #define Error 1

            #define Ok 0

            #define WaitTime 0x01

            #define PerSector 512

            unsignedchar xdata Ttotal[512];

            /*

            ---------------------------------------------------------------------

            打開 ISP,IAP功能

            ---------------------------------------------------------------------

            */

            voidISP_IAP_enable(void)

            {

            EA=0;/*關(guān)中斷*/

            ISP_CONTR|=0x18;/*0001,1000*/

            ISP_CONTR|=WaitTime;/*寫入硬件延時(shí)*/

            ISP_CONTR|=0x80;/*ISPEN=1*/

            }

            /*

            ---------------------------------------------------------------------

            關(guān)閉 ISP,IAP功能

            ---------------------------------------------------------------------

            */

            voidISP_IAP_disable(void)

            {

            ISP_CONTR&=0x7f;/* ISPEN = 0 */

            ISP_TRIG=0x00;

            EA=1;/*開中斷 */

            }

            /*

            ----------------------------------------------------------------------

            公用的觸發(fā)代碼

            ----------------------------------------------------------------------

            */

            voidISPgoon(void)

            {

            ISP_IAP_enable();/*打開 ISP,IAP功能 */

            ISP_TRIG=0x46;/*觸發(fā)ISP_IAP命令字節(jié)1 */

            ISP_TRIG=0xb9;/*觸發(fā)ISP_IAP命令字節(jié)2 */

            _nop_();

            }

            /*

            -----------------------------------------------------------------------

            字節(jié)讀

            -----------------------------------------------------------------------

            */

            unsignedchar byte_read(unsigned int byte_addr)

            {

            ISP_ADDRH=(unsigned char)(byte_addr>>8); /*地址賦值*/

            ISP_ADDRL=(unsigned char)(byte_addr&0x00ff);

            ISP_CMD&=0xf8; /*清除低3位 */

            ISP_CMD|=RdCommand;/*寫入讀命令*/

            ISPgoon();/*觸發(fā)執(zhí)行*/

            ISP_IAP_disable();/*關(guān)閉ISP,IAP功能*/

            return ISP_DATA;/*返回讀到的數(shù)據(jù)*/

            }

            /*

            ------------------------------------------------------------------------

            扇區(qū)擦除

            ------------------------------------------------------------------------

            */

            voidsectorerase(unsigned int sector_addr)

            {

            unsigned int iSectorAddr;

            iSectorAddr=(sector_addr&0xfe00);/*取扇區(qū)地址*/

            ISP_ADDRH=(unsigned char)(iSectorAddr>>8);

            ISP_ADDRL=0x00;

            ISP_CMD&=0xf8;/*清空低3位*/

            ISP_CMD|=EraseCommand;/*擦除命令3*/

            ISPgoon();/*觸發(fā)執(zhí)行 */

            ISP_IAP_disable();/*關(guān)閉ISP,IAP功能*/

            }

            /*

            -------------------------------------------------------------------------------------

            字節(jié)寫

            -------------------------------------------------------------------------------------

            */

            voidbyte_write(unsigned int byte_addr, unsigned char original_data)

            {

            ISP_ADDRH=(unsigned char)(byte_addr>>8); /*取地址*/

            ISP_ADDRL=(unsigned char)(byte_addr & 0x00ff);

            ISP_CMD&=0xf8;/*清低3位*/

            ISP_CMD|=PrgCommand;/*寫命令2*/

            ISP_DATA=original_data;/*寫入數(shù)據(jù)準(zhǔn)備*/

            ISPgoon();/*觸發(fā)執(zhí)行*/

            ISP_IAP_disable();/*關(guān)閉IAP功能*/

            }

            /*

            -----------------------------------------------------------------

            字節(jié)寫并校驗(yàn)

            -----------------------------------------------------------------

            */

            unsignedchar byte_write_verify(unsigned int byte_addr, unsigned char original_data)

            {

            ISP_ADDRH=(unsigned char)(byte_addr>>8); /*取地址*/

            ISP_ADDRL=(unsigned char)(byte_addr&0xff);

            ISP_CMD&=0xf8;/*清低3位*/

            ISP_CMD|=PrgCommand;/*寫命令2*/

            ISP_DATA=original_data;

            ISPgoon();/*觸發(fā)執(zhí)行*/

            /*開始讀,沒有在此重復(fù)給地址,地址不會(huì)被自動(dòng)改變*/

            ISP_DATA=0x00;/*清數(shù)據(jù)傳遞寄存器*/

            ISP_CMD&=0xf8;/*清低3位*/

            ISP_CMD|=RdCommand;/*讀命令1*/

            ISP_TRIG=0x46;/*觸發(fā)ISP_IAP命令字節(jié)1 */

            ISP_TRIG=0xb9;/*觸發(fā)ISP_IAP命令字節(jié)2 */

            _nop_();/*延時(shí)*/

            ISP_IAP_disable();/*關(guān)閉IAP功能*/

            if(ISP_DATA==original_data)/*讀寫數(shù)據(jù)校驗(yàn)*/

            return Ok;/*返回校驗(yàn)結(jié)果*/

            else

            return Error;

            }

            /*

            --------------------------------------------------------------------------

            數(shù)組寫入

            --------------------------------------------------------------------------

            */

            unsignedchar arraywrite(unsigned int begin_addr, unsigned int len, unsigned char *array)

            {

            unsigned int i;

            unsigned int in_addr;

            /*判是否是有效范圍,此函數(shù)不允許跨扇區(qū)操作 */

            if(len > PerSector)

            return Error;

            in_addr = begin_addr & 0x01ff;/*扇區(qū)內(nèi)偏移量 */

            if((in_addr+len)>PerSector)

            return Error;

            in_addr = begin_addr;

            /*逐個(gè)寫入并校對(duì) */

            ISP_IAP_enable();/*打開IAP功能 */

            for(i=0;i

            {

            /*寫一個(gè)字節(jié) */

            ISP_ADDRH=(unsigned char)(in_addr >> 8);

            ISP_ADDRL=(unsigned char)(in_addr & 0x00ff);

            ISP_DATA=array[i]; /*取數(shù)據(jù) */

            ISP_CMD&=0xf8;/*清低3位 */

            ISP_CMD|=PrgCommand;/*寫命令2 */

            ISP_TRIG=0x46;/*觸發(fā)ISP_IAP命令字節(jié)1 */

            ISP_TRIG=0xb9;/*觸發(fā)ISP_IAP命令字節(jié)2 */

            _nop_();

            /*讀回來 */

            ISP_DATA=0x00;

            ISP_CMD&=0xf8;/*清低3位*/

            ISP_CMD|=RdCommand;/*讀命令1*/

            ISP_TRIG=0x46;/*觸發(fā)ISP_IAP命令字節(jié)1 */

            ISP_TRIG=0xb9;/*觸發(fā)ISP_IAP命令字節(jié)2 */

            _nop_();

            /*比較對(duì)錯(cuò) */

            if(ISP_DATA!=array[i])

            {

            ISP_IAP_disable();

            return Error;

            }

            in_addr++;/*指向下一個(gè)字節(jié)*/

            }

            ISP_IAP_disable();

            return Ok;

            }

            /*

            -----------------------------------------------------------------------------

            扇區(qū)讀出

            -----------------------------------------------------------------------------

            */

            /*程序?qū)Φ刂窙]有作有效性判斷,請(qǐng)調(diào)用前事先保證他在規(guī)定范圍內(nèi) */

            voidarrayread(unsigned int begin_addr, unsigned char len)

            {

            unsigned int iSectorAddr;

            unsigned int i;

            iSectorAddr = begin_addr; // & 0xfe00; /*取扇區(qū)地址*/

            ISP_IAP_enable();

            for(i=0;i

            {

            ISP_ADDRH=(unsigned char)(iSectorAddr>>8);

            ISP_ADDRL=(unsigned char)(iSectorAddr & 0x00ff);

            ISP_CMD&=0xf8;/*清低3位*/

            ISP_CMD|=RdCommand;/*讀命令1*/

            ISP_DATA=0;

            ISP_TRIG=0x46;/*觸發(fā)ISP_IAP命令字節(jié)1 */

            ISP_TRIG=0xb9;/*觸發(fā)ISP_IAP命令字節(jié)2 */

            _nop_();

            Ttotal[i]=ISP_DATA;

            iSectorAddr++;

            }

            ISP_IAP_disable();/*關(guān)閉IAP功能*/

            }

            主函數(shù)對(duì)EEPROM操作函數(shù)進(jìn)行調(diào)用:

            #include c51rd.h>

            #include

            #include

            #include

            inti;

            voiddelay(unsigned int time)

            {

            while(time--);

            }

            voidmain()

            {

            _ADOS(22.1184);

            //ADOS自動(dòng)下載

            //for(i=0;i<100;i++)

            //{

            //Ttotal[i]=i;

            //}

            //arraywrite(0x8000,100,Ttotal);

            /*

            第一次運(yùn)行時(shí)向EEPROM中寫入數(shù)據(jù)

            然后再將寫入函數(shù)注釋掉,將先前寫

            入的數(shù)據(jù)讀出,輸出在P2口上。

            */

            arrayread(0x8000,100);

            for(i=0;i<100;i++)

            {

            P2=~Ttotal[i];

            delay(10000);

            }

            while(1);

            }



            評(píng)論


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

            關(guān)閉