久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

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

 fcs_110 2011-09-01

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

2008-05-18 02:47:27|  分類: AVR與C51單片機(jī)技 |  標(biāo)簽: |字號 訂閱

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

   單片機(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各型號單片機(jī)內(nèi)置的EEPROM的容量各有不同,見下表:

 

       單片機(jī)芯片型號

 

起始地址

 

內(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

 

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

 

 

 

 

 

 

0

 

1

 

0

 

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

 

 

 

 

 

 

0

 

1

 

1

 

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

 

 

 

 

 

 

 

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

           當(dāng)ISPEN(ISP_CONTR.7)=1時(shí),,對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

 

unsigned char xdata Ttotal[512];

 

/*

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

     打開 ISP,IAP 功能

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

*/

void ISP_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 功能

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

*/

void ISP_IAP_disable(void)

{

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

 ISP_TRIG=0x00;

 EA=1;/* 開中斷      */

}

 

/*

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

    公用的觸發(fā)代碼

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

*/

void ISPgoon(void)

{

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

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

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

 _nop_();

}

 

/*

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

    字節(jié)讀

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

*/

unsigned char 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ū)擦除

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

*/

void sectorerase(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é)寫

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

*/

void byte_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)

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

*/

unsigned char 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ù)組寫入

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

*/

unsigned char 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è)寫入并校對 */

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

 for(i=0;i<len;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_();

 

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

   if(ISP_DATA!=array[i])

    {

     ISP_IAP_disable();

     return Error;

    }

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

   }

   ISP_IAP_disable();

   return Ok;

}

 

/*

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

    扇區(qū)讀出

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

*/

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

void arrayread(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<len;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ù)對EEPROM操作函數(shù)進(jìn)行調(diào)用:

#include <stc51rd.h>

#include <intrins.h>

#include <stc_eeprom.h>

#include <ados.h>

 

int i;

 

void delay(unsigned int time)

{

 while(time--);

}

 

void main()

{

 _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);

}

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn),。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙,。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多