⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 eepdemo.lst

📁 STC片内EEPROM的读写原代码
💻 LST
字号:
C51 COMPILER V8.02   EEPDEMO                                                               02/28/2007 15:40:35 PAGE 1   


C51 COMPILER V8.02, COMPILATION OF MODULE EEPDEMO
OBJECT MODULE PLACED IN E:\TEMP\eepDemo.obj
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE eepDemo.c BROWSE DEBUG OBJECTEXTEND OBJECT(E:\TEMP\eepDemo.obj)

line level    source

   1          /*========================================================================
   2          IAP操作使用片内flash作为eeprom使用的驱动程序。参考来源:www.mcu-memory.com
   3          
   4          本演示代码通过对用户数据的读写操作,具体实现数据存储的组织方法,最大限度的
   5          利用eeprom的空间。这只是对eeprom进行分配轮换使用的一种方法。
   6          实现分配的思路:用户数组(需要记忆的部分)应该在4,8,16,32,64等字节以内,将第
   7          一字节留作索引头:如果读到该字节为0x55(也可以定义为其他数),则认为已经找到
   8          了有效的最后纪录,将本小区域数据读出。如果不是则继续跳到下一个小区域继续上
   9          述操作,直到找到上一次的纪录为止,如果超出了eeprom的有效范围还没有找到,则
  10          认为这是一块新的芯片,将默认的数据写入。
  11          保存的时候,首先将刚才读到的那个数组的对应eeprom中的第一字节清零,以便下次
  12          跳过,然后再推后一个小区域(记录长度),将数据写入。如果出现写入失败,接着到
  13          再下一个区域,直到写入正确为止。
  14          这里有一个问题就是,写到下一个小区域的时候会遇到跨扇区,只要判断出跨区,就
  15          将上一个扇区擦除,以备下一轮循环再使用。
  16          程序利用stc提供的下载板上的LED显示当前读或者写的地址,你可以看到led的"递减"
  17          过程,演示读写256次,从第一次的全亮,到演示完毕也全亮,刚好256次。如果中途
  18          断电,即会出现不同的结果,但再进行完演示的话,会发现结束时的led状态与开始
  19          时的一样,否则就说明你的芯片内部eeprom有损坏。
  20          
  21          演示代码仅针对stc89c54rd+/51rc进行了调试,但可以给其他芯片编程时作为参考。
  22          晓奇工作室 http://www.xiao-qi.com/
  23                                                                                                  ---- xiaoqi  2005.12
  24           ======================================================================= */
  25          #include "src51rd.h"
  26          #include <intrins.h>
  27          
  28          #define uchar   unsigned char
  29          #define uint    unsigned int
  30          
  31          /* STC89C52RC的flash空间从0x2000~0x2fff 共8个扇区,每扇区512字节*/
  32          
  33                  #define BaseAddr                0x2000
  34                  #define EndSectoraddr   0x2e00
  35                  #define EndAddr                 0x2fff
  36          
  37          /* ------------- 定义扇区大小 ------------- */
  38          #define PerSector               512
  39          
  40          /* 用户程序需要记忆的数组, 用户实际使用了n-1个数据,数组长度规整到
  41                  2 4 8 16 32 64 上 */
  42          uchar Ttotal[16]        =
  43          {
  44                  0x55,                           /* 作为判别引导头使用,用户程序请不要修改它 */
  45                  /* 用户保存记忆的数据 */
  46                  0x01,                           /* 用途说明....*/
  47                  0x02,
  48                  0x03,
  49                  0x04,
  50                  0x05,
  51                  0x06,
  52                  0x07,
  53                  0x08,
  54                  0x09,
  55                  0x0a,
C51 COMPILER V8.02   EEPDEMO                                                               02/28/2007 15:40:35 PAGE 2   

  56                  0x0b,
  57                  0x0c,
  58                  0x0d,
  59                  0x0e,
  60                  0x0f,
  61          };
  62          
  63          uint    timerForDelay,          /* 专供延时用的变量 */
  64                          i,                                      /* 循环变量                     */
  65                          EepromPtr;                      /* eeprom读写指针       */
  66          
  67          /* ======================= IAP外部函数列表 =======================*/
  68          /* 扇区擦除                                     */
  69                  extern void SectorErase(uint sector_addr);
  70          /* byte 读                                      */
  71                  extern uchar byte_read(uint byte_addr); 
  72          /* byte 写                                      */
  73                  extern void byte_write(uint byte_addr, uchar original_data);
  74          /* byte写并校验                         */
  75                  extern uchar byte_write_verify(uint byte_addr, uchar original_data);
  76          /* byte数组写并校验                     */
  77                  extern uchar ArrayWrite(uint begin_addr, uint len, uchar *array);
  78          /* byte数组读, 存在Ttotal[]     */
  79                  extern void ArrayRead(uint begin_addr, uchar len);
  80          
  81          /* ============================ 延时 ========================= */
  82          void delay(uint counter)
  83          {
  84   1              timerForDelay = counter;
  85   1              while(timerForDelay);
  86   1      }
  87          
  88          /* ==============================================================
  89           初始化开启定时器2,定时周期设定为10mS(下载板上 18.432M 晶振)
  90           ============================================================== */
  91          void initCT2()
  92          {
  93   1              /* 时钟倍频时用 0x8800*/
  94   1              RCAP2H  = 0xc4;
  95   1              RCAP2L  = 0x00;
  96   1              TH2     = 0xc4;                                 // 定时器初值
  97   1              TL2     = 0x00; 
  98   1              ET2 = 1;                                        // 允许T2中断
  99   1              T2CON   = 4;                            // 自动重装的定时器
 100   1              TR2 = 1;                                        // 启动
 101   1              EA      = 1;
 102   1      }
 103          
 104          /* ==============================================================
 105           定时器CT2中断服务程序
 106           ============================================================== */
 107          void timer2Int(void) interrupt 5
 108          {
 109   1              TF2 = 0;                                                        /* 溢出标志必须由软件清零*/
 110   1              EXF2 = 0;                                                       /* 捕获标志必须由软件清零*/
 111   1              if(timerForDelay)timerForDelay--;       /* 定时变量处理                 */
 112   1      }
 113          
 114          /* ==============================================================
 115           从eeprom中读取数据
 116           ============================================================== */
 117          void DataRestore()
C51 COMPILER V8.02   EEPDEMO                                                               02/28/2007 15:40:35 PAGE 3   

 118          {
 119   1              EepromPtr = BaseAddr;                           /* 指向eeprom的起始点   */
 120   1              while(EepromPtr < EndAddr)                      /* 在eeprom的可用区域内 */
 121   1              {
 122   2                      if(byte_read(EepromPtr) == 0x55)/* 找到了上一次有效纪录 */
 123   2                      {
 124   3                              break;                                          /*      寻找完成                        */
 125   3                      }
 126   2                      EepromPtr += 0x10;                              /* 指向下一个小区               */
 127   2              }
 128   1              if(EepromPtr >= EndAddr)                        /* 如果照遍都没有,是新片*/
 129   1              {
 130   2                      EepromPtr = BaseAddr;                   /* 指向eeprom的起始点   */
 131   2                      for(i=0;i<90;i++)
 132   2                      {
 133   3                              SectorErase(EepromPtr+0x200*i); /* 全部扇区擦除         */
 134   3                      }
 135   2                      while(ArrayWrite(EepromPtr, 0x10, Ttotal))      /* 写默认值     */
 136   2                      {                                                               /* 写入失败才运行的部分 */
 137   3                              byte_write(EepromPtr, 0);       /* 该单元已经失效               */
 138   3                              if(EepromPtr < EndAddr)
 139   3                              {
 140   4                                      EepromPtr += 0x10;              /* 换一块新的小区               */
 141   4                              }
 142   3                              else
 143   3                              {
 144   4                                      P1=0;                                   /* 指示芯片内eeprom全坏 */
 145   4                                      EA= 0;                                  /* 不再做任何事                 */
 146   4                                      while(1);                               /* 死机                                 */
 147   4                              }
 148   3                      }
 149   2              }
 150   1              ArrayRead(EepromPtr, 16);
 151   1      }
 152          
 153          /* ==============================================================
 154           将需要记忆的数据保存到eeprom
 155           ============================================================== */
 156          void DataSave()
 157          {
 158   1      uint    wrPtr;                                                                  /* 临时指针             */
 159   1      
 160   1      NextArea:
 161   1              byte_write_verify(EepromPtr, 0);                /* 将原来的标记清除     */
 162   1              wrPtr = EepromPtr & 0xfe00;     /* 上一个扇区的起始地址 */
 163   1              EepromPtr += 0x10;                                              /* 目标存入地址         */
 164   1      
 165   1              /* ------------------ 判断是否启用新的扇区 ---------------- */
 166   1              if((EepromPtr & 0x1ff)==0)
 167   1              {
 168   2                      SectorErase(wrPtr);                     /* 将上一个扇区擦除,备用       */
 169   2                      if(EepromPtr>=EndAddr)          /* 已经用完了最后一个区域       */
 170   2                      {
 171   3                              EepromPtr = BaseAddr;                                   /* 从头开始     */
 172   3                      }
 173   2              }
 174   1              /* -------------------- 数据存入前的准备 ------------------ */
 175   1              /* 。。。。。。。。。。。。。。转移、处理                                       */
 176   1              Ttotal[0] = 0x55;                                               /* 重申启用标记         */
 177   1              if(ArrayWrite(EepromPtr, 0x10, Ttotal))
 178   1              {                                                               /* 数据写入,如果有错换一块     */
 179   2                      goto NextArea;
C51 COMPILER V8.02   EEPDEMO                                                               02/28/2007 15:40:35 PAGE 4   

 180   2              }
 181   1      }
 182          
 183          /* ================================================================
 184                  储存于读取的反复测试,每个小区域16字节,每个扇区512字节,即每个
 185          扇区分成32个小块,每次写入顺序往后移动一个小区域,进行256次读写操作
 186          实际上跨越了8个扇区。
 187          按照51rc 12K eeprom计算,可以反复纪录7680万次
 188          按照52rc 8K eeprom计算,可以反复纪录3840万次
 189          按照54rd+45K eeprom计算,可以反复纪录2.88亿次
 190          足够系统对记忆体的要求。
 191           ====================================================== ======= */
 192          void main()
 193          {
 194   1              //byte_write(0x2e00,0x55);
 195   1              //SectorErase(0x2000);
 196   1              P1 = byte_read(0x2e00);
 197   1      
 198   1              while(1);               
 199   1      }


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =    311    ----
   CONSTANT SIZE    =   ----    ----
   XDATA SIZE       =   ----    ----
   PDATA SIZE       =   ----    ----
   DATA SIZE        =     22    ----
   IDATA SIZE       =   ----    ----
   BIT SIZE         =   ----    ----
END OF MODULE INFORMATION.


C51 COMPILATION COMPLETE.  0 WARNING(S),  0 ERROR(S)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -