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

📄 eepdemo.lst

📁 STC系列单片机EEPROM使用程序,经过修改可以在STC12C54系列上使用
💻 LST
字号:
C51 COMPILER V8.08   EEPDEMO                                                               03/08/2009 13:41:49 PAGE 1   


C51 COMPILER V8.08, COMPILATION OF MODULE EEPDEMO
OBJECT MODULE PLACED IN eepDemo.OBJ
COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE eepDemo.c BROWSE DEBUG OBJECTEXTEND

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 <STC12C5410AD.H>
  26          #include <intrins.h>
  27          
  28          #define uchar   unsigned char
  29          #define uint    unsigned int
  30          
  31          /* STC89C54RD+的flash空间从0x4000~0xf3ff 共90个扇区,每扇区512字节      */
  32          //      #define BaseAddr                0x1000          /*      51rc    */
  33          //      #define EndSectoraddr   0x3d00          /*      51rc    */
  34          //      #define EndAddr 0x3fff          /*      51rc 12K eeprom */
  35          
  36                  #define BaseAddr                0x0400
  37                  #define EndSectoraddr   0x2F00
  38                  #define EndAddr                 0x2FFF
  39          
  40          /* ------------- 定义扇区大小 ------------- */
  41          #define PerSector               512
  42          
  43          /* 用户程序需要记忆的数组, 用户实际使用了n-1个数据,数组长度规整到
  44                  2 4 8 16 32 64 上 */
  45          uchar Ttotal[16]        =
  46          {
  47                  0x55,                           /* 作为判别引导头使用,用户程序请不要修改它 */
  48                  /* 用户保存记忆的数据 */
  49                  0x01,                           /* 用途说明....*/
  50                  0x02,
  51                  0x03,
  52                  0x04,
  53                  0x05,
  54                  0x06,
  55                  0x07,
C51 COMPILER V8.08   EEPDEMO                                                               03/08/2009 13:41:49 PAGE 2   

  56                  0x08,
  57                  0x09,
  58                  0x0a,
  59                  0x0b,
  60                  0x0c,
  61                  0x0d,
  62                  0x0e,
  63                  0x0f,
  64          };
  65          
  66          uint    timerForDelay,          /* 专供延时用的变量 */
  67                          i,                                      /* 循环变量                     */
  68                          EepromPtr;                      /* eeprom读写指针       */
  69          
  70          /* ======================= IAP外部函数列表 =======================*/
  71          /* 扇区擦除                                     */
  72                  extern void SectorErase(uint sector_addr);
  73          /* byte 读                                      */
  74                  extern uchar byte_read(uint byte_addr); 
  75          /* byte 写                                      */
  76                  extern void byte_write(uint byte_addr, uchar original_data);
  77          /* byte写并校验                         */
  78                  extern uchar byte_write_verify(uint byte_addr, uchar original_data);
  79          /* byte数组写并校验                     */
  80                  extern uchar ArrayWrite(uint begin_addr, uint len, uchar *array);
  81          /* byte数组读, 存在Ttotal[]     */
  82                  extern void ArrayRead(uint begin_addr, uchar len);
  83          
  84          /* ============================ 延时 ========================= */
  85          void delay(int counter)
  86          {
  87   1              timerForDelay = counter;
  88   1              while(timerForDelay);
  89   1      }
  90          
  91          /* ==============================================================
  92           初始化开启定时器2,定时周期设定为10mS(下载板上 18.432M 晶振)
  93           ============================================================== */
  94          void initCT1() 
  95          {
  96   1      
  97   1              TMOD   = 0x01;          
  98   1              TH0     = 0xdc;                                 // 定时器初值
  99   1              TL0     = 0x00;
 100   1              EA      = 1;    
 101   1              ET0 = 1;                                        // 允许T2中断
 102   1              TR0 = 1;                                        // 启动
 103   1      }
 104          
 105          /* ==============================================================
 106           定时器CT2中断服务程序
 107           ============================================================== */
 108          timer1Int(void) interrupt 1       using 1
 109          {
 110   1              TH1     = 0xdc;                                 // 定时器初值
 111   1              TL1     = 0x00;
 112   1      
 113   1              if(timerForDelay)timerForDelay--;       /* 定时变量处理                 */
 114   1      }
 115          
 116          /* ==============================================================
 117           从eeprom中读取数据
C51 COMPILER V8.08   EEPDEMO                                                               03/08/2009 13:41:49 PAGE 3   

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

 180   1              {                                                               /* 数据写入,如果有错换一块     */
 181   2                      goto NextArea;
 182   2              }
 183   1      }
 184          
 185          /* ================================================================
 186                  储存于读取的反复测试,每个小区域16字节,每个扇区512字节,即每个
 187          扇区分成32个小块,每次写入顺序往后移动一个小区域,进行256次读写操作
 188          实际上跨越了8个扇区。
 189          按照51rc 12K eeprom计算,可以反复纪录7680万次
 190          按照52rc 8K eeprom计算,可以反复纪录3840万次
 191          按照54rd+45K eeprom计算,可以反复纪录2.88亿次
 192          足够系统对记忆体的要求。
 193           ================================================================ */
 194          void main()
 195          {
 196   1              P1 = 0xff;                                      /* 所有LED熄灭  */
 197   1              initCT1();                                      /* CT2初始化,用来做定时器              */
 198   1              /* ------------------ 演示 256 次读写操作 ----------------- */
 199   1              for(i=0;i<256;i++)
 200   1              {
 201   2                      DataRestore();                  /* 从eeprom中读取记忆数据               */
 202   2                      P1 = (uchar)((EepromPtr >> 4) & 0xff);  /* 显示读取地址 */
 203   2                      delay(1);                               /* 延时保留显示状态1秒                  */
 204   2                      DataSave();                             /* 数据再次保存                                 */
 205   2                      P1 = (uchar)((EepromPtr >> 4) & 0xff);  /* 显示写入地址 */
 206   2                      delay(1);                               /* 延时保留显示状态1秒                  */
 207   2              }
 208   1      
 209   1              while(1);                                       /* 演示完毕 */
 210   1      }


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =    356    ----
   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 + -