找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3696|回復(fù): 0
打印 上一主題 下一主題
收起左側(cè)

51單片機(jī)學(xué)習(xí):連續(xù)讀寫STC89C52RC內(nèi)部EEPROM存儲(chǔ)器

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:161768 發(fā)表于 2017-1-14 23:24 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
STC單片機(jī)的內(nèi)部EEPROM是用DATAFLASH模擬出來的,不是真正的EEPROM存儲(chǔ)器,不能用普通的方法來操作
下面是一些注意點(diǎn):
1.字節(jié)寫之前要先將這個(gè)字節(jié)所在扇區(qū)的其它有效數(shù)據(jù)讀取到RAM暫存(這步不是必須的)
2.暫存完之后再對整個(gè)扇區(qū)(512字節(jié))進(jìn)行擦除操作,擦拭完后,整個(gè)扇區(qū)每個(gè)地址中數(shù)據(jù)都變成0xFF
3.將欲寫入的N個(gè)字節(jié)數(shù)據(jù),用字節(jié)寫函數(shù)寫入EEPROM
4.將暫存到RAM的其它有用的EEPROM值再用字節(jié)寫函數(shù)寫回EEPROM
5.STC用FLASH模擬出來的EEPROM的字節(jié)寫功能只能將1變成0,而不能將0變成1,
  只有扇區(qū)擦除后數(shù)據(jù)才是全1,
  例如:在地址0x21f0處第1次寫11010110,第2次寫111010,讀出結(jié)果是這2個(gè)值的相與10010
         所以如果一個(gè)地址處的值不是0xff時(shí)寫入新的數(shù)據(jù)是不對的,要先執(zhí)行扇區(qū)擦除,變?yōu)?xff,
         對于單個(gè)字節(jié)的寫入,我們可以先檢查該地址處的數(shù)據(jù)是否為0xff,是的話就不用擦除扇區(qū)了
----------------------------------------------------------------------
STC89C52單片機(jī)內(nèi)部EEPROM 的讀寫過程
1  配置ISP_CONTR寄存器,使能第7位ISPEN,讓ISP_IAP功能生效,并配置低3位的等待時(shí)間
2  寫指令: 讀/寫/擦除扇區(qū) 這3個(gè)命令
3  賦值: ISP_ADDRH和ISP_ADDRL的地址值
4  關(guān)閉總中斷EA,因?yàn)橄旅嬉獙懙?個(gè)觸發(fā)指令必須是連續(xù)操作的,不能被中斷
5  執(zhí)行公用的  ISP_IAP 觸發(fā)指令,觸發(fā)后讀寫操作才能進(jìn)行
6  打開中斷 EA, 關(guān)閉ISP_IAP功能:清相關(guān)寄存器
  1. #include "my51.h"

  2. /******************定義命令字節(jié)******************/      
  3. #define read_cmd     0x01                   //字節(jié)讀數(shù)據(jù)命令     
  4. #define wirte_cmd    0x02                   //字節(jié)編程數(shù)據(jù)命令     
  5. #define erase_cmd    0x03                   //扇區(qū)擦除數(shù)據(jù)命令               
  6.   
  7. /****************特殊功能寄存器聲明****************/  
  8. sfr ISP_DATA = 0xe2;   
  9. sfr ISP_ADDRH = 0xe3;     
  10. sfr ISP_ADDRL = 0xe4;   
  11. sfr ISP_CMD = 0xe5;   
  12. sfr ISP_TRIG = 0xe6;      
  13. sfr ISP_CONTR = 0xe7;

  14. /*定義Flash 操作等待時(shí)間及允許IAP/ISP/EEPROM 操作的常數(shù)******************/
  15. //#define enable_waitTime 0x80 //系統(tǒng)工作時(shí)鐘<30MHz 時(shí),對IAP_CONTR 寄存器設(shè)置此值
  16. //#define enable_waitTime 0x81 //系統(tǒng)工作時(shí)鐘<24MHz 時(shí),對IAP_CONTR 寄存器設(shè)置此值
  17. //#define enable_waitTime 0x82  //系統(tǒng)工作時(shí)鐘<20MHz 時(shí),對IAP_CONTR 寄存器設(shè)置此值
  18. #define enable_waitTime 0x83 //系統(tǒng)工作時(shí)鐘<12MHz 時(shí),對IAP_CONTR 寄存器設(shè)置此值
  19. //#define enable_waitTime 0x84 //系統(tǒng)工作時(shí)鐘<6MHz 時(shí),對IAP_CONTR 寄存器設(shè)置此值
  20.   
  21.    
  22. void ISP_IAP_disable(void)                                     //關(guān)閉ISP_IAP
  23. {   
  24.         EA=1;                                                                          //恢復(fù)中斷
  25.     ISP_CONTR = 0x00;     
  26.     ISP_CMD = 0x00;      
  27.     ISP_TRIG = 0x00;                                                                                      
  28. }

  29. void ISP_IAP_trigger()                       //觸發(fā)
  30. {   
  31.         EA=0;                                    //下面的2條指令必須連續(xù)執(zhí)行,故關(guān)中斷                    
  32.     ISP_TRIG = 0x46;                         //送觸發(fā)命令字0x46     
  33.     ISP_TRIG = 0xB9;                         //送觸發(fā)命令字0xB9         
  34. }
  35.       

  36. void ISP_IAP_readData(u16 beginAddr, u8* pBuf, u16 dataSize) //讀取數(shù)據(jù)
  37. {
  38.         ISP_DATA=0;                                                           //清零,不清也可以
  39.         ISP_CMD = read_cmd;                                                  //指令:讀取
  40.         ISP_CONTR = enable_waitTime;                           //開啟ISP_IAP,并送等待時(shí)間
  41.         while(dataSize--)                                                  //循環(huán)讀取
  42.         {
  43.             ISP_ADDRH = (u8)(beginAddr >> 8);     //送地址高字節(jié)      
  44.             ISP_ADDRL = (u8)(beginAddr & 0x00ff); //送地址低字節(jié)
  45.                 ISP_IAP_trigger();                                        //觸發(fā)
  46.                 beginAddr++;                                                //地址++
  47.                 *pBuf++ = ISP_DATA;                                        //將數(shù)據(jù)保存到接收緩沖區(qū)
  48.         }
  49.         ISP_IAP_disable();                                                //關(guān)閉ISP_IAP功能
  50. }      
  51.    
  52. void ISP_IAP_writeData(u16 beginAddr,u8* pDat,u16 dataSize) //寫數(shù)據(jù)   
  53. {           
  54.     ISP_CONTR = enable_waitTime;                //開啟ISP_IAP,并送等待時(shí)間      
  55.     ISP_CMD = wirte_cmd;                        //送字節(jié)編程命令字
  56.         while(dataSize--)
  57.         {
  58.             ISP_ADDRH = (u8)(beginAddr >> 8);       //送地址高字節(jié)      
  59.             ISP_ADDRL = (u8)(beginAddr & 0x00ff);   //送地址低字節(jié)           
  60.             ISP_DATA = *pDat++;                     //送數(shù)據(jù)      
  61.                 beginAddr++;
  62.                 ISP_IAP_trigger();                                                 //觸發(fā)
  63.         }         
  64.     ISP_IAP_disable();   //關(guān)閉                                      
  65. }   
  66.         
  67. void ISP_IAP_sectorErase(u16 sectorAddr)             //扇區(qū)擦除
  68. {           
  69.     ISP_CONTR = enable_waitTime;                //開啟ISP_IAP;并送等待時(shí)間      
  70.     ISP_CMD = erase_cmd;                        //送扇區(qū)擦除命令字         
  71.     ISP_ADDRH = (u8)(sectorAddr >> 8);                    //送地址高字節(jié)      
  72.     ISP_ADDRL = (u8)(sectorAddr & 0X00FF);          //送地址低字節(jié)           
  73.         ISP_IAP_trigger();                                                     //觸發(fā)
  74.     ISP_IAP_disable();                          //關(guān)閉ISP_IAP功能         
  75. }
  76.    
  77. void main()                                                                     //測試
  78. {   
  79.         u8 buf[3]={0};                                                                  //接收數(shù)據(jù)緩沖區(qū)
  80.         u8 dat[5]={b(111010),b(1001),b(1),b(1011),b(1110)};//我寫成二進(jìn)制是為觀察led燈   
  81.     ISP_IAP_sectorErase(0x2000);                //扇區(qū)擦除,一塊512字節(jié)      
  82.     ISP_IAP_writeData(0x21f0,dat,sizeof(dat));  //寫EEPROM               
  83.         ISP_IAP_readData(0x21f0,buf,sizeof(buf));         //讀取
  84.         P1=buf[2];//在地址0x21f0處第1次寫11010110,第2次寫111010,讀出結(jié)果是這2個(gè)值的相與10010
  85.     while(1); //所以如果一個(gè)地址處的值不是0xff時(shí)寫入新的數(shù)據(jù)是不對的,要先擦除為0xff
  86. }
復(fù)制代碼
  1. #ifndef _MY51_H
  2. #define _MY51_H
  3. #include <reg52.h>
  4. //#include <math.h>
  5. #include <intrins.h>
  6. #include <stdio.h>
  7. #include "mytype.h"

  8. /*************二進(jìn)制輸入宏****************************/
  9. #ifndef _LongToBin_
  10. #define _LongToBin_
  11. #define LongToBin(n) \                           
  12. (                                         \
  13. ((n >> 21) & 0x80) | \
  14. ((n >> 18) & 0x40) | \
  15. ((n >> 15) & 0x20) | \
  16. ((n >> 12) & 0x10) | \
  17. ((n >> 9)  & 0x08) | \
  18. ((n >> 6)  & 0x04) | \
  19. ((n >> 3)  & 0x02) | \
  20. ((n ) & 0x01)                  \
  21. )
  22. #define  bin(n)  LongToBin(0x##n##l)
  23. #define  BIN(n)  bin(n)
  24. #define  B(n)    bin(n)
  25. #define  b(n)    bin(n)                          
  26. #endif

  27. /*************單個(gè)數(shù)據(jù)位的置位宏*********************/
  28. #ifndef   _BIT_
  29. #define   _BIT_
  30. #define   BIT(n)   (1<<n)
  31. #define   bit(n)   BIT(n)
  32. #endif

  33. #define high        1   //高電平
  34. #define low                0   //低電平

  35. #define led P1      //燈總線控制

  36. sbit led0=P1^0;     //8個(gè)led燈,陰極送低電平點(diǎn)亮
  37. sbit led1=P1^1;
  38. sbit led2=P1^2;
  39. sbit led3=P1^3;
  40. sbit led4=P1^4;
  41. sbit led5=P1^5;
  42. sbit led6=P1^6;
  43. sbit led7=P1^7;        
  44. sbit ledLock=P2^5;        //led鎖存的狀態(tài),0鎖定 ,1不鎖定

  45. sbit beep=P2^3;     //蜂鳴器

  46. void delayms(u16 ms);
  47. //void delayXus(u8 us); //函數(shù)執(zhí)行(8+6x)個(gè)機(jī)器周期, 即t=(8+6x)*1.085
  48. /////////////////////////////////////////////////////////////////////////////


  49. #endif
復(fù)制代碼
分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩

相關(guān)帖子

回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表