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

📄 eepdemo.lst

📁 stc单片机的iap程序
💻 LST
字号:
C51 COMPILER V8.01   EEPDEMO                                                               12/19/2005 20:22:59 PAGE 1   


C51 COMPILER V8.01, 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 "src51rd.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                0x4000
  37                  #define EndSectoraddr   0xf200
  38                  #define EndAddr                 0xf3ff
  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.01   EEPDEMO                                                               12/19/2005 20:22:59 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(uint counter)
  86          {
  87   1              timerForDelay = counter;
  88   1              while(timerForDelay);
  89   1      }
  90          
  91          /* ==============================================================
  92           初始化开启定时器2,定时周期设定为10mS(下载板上 18.432M 晶振)
  93           ============================================================== */
  94          void initCT2()
  95          {
  96   1              /* 时钟倍频时用 0x8800*/
  97   1              RCAP2H  = 0xc4;
  98   1              RCAP2L  = 0x00;
  99   1              TH2     = 0xc4;                                 // 定时器初值
 100   1              TL2     = 0x00; 
 101   1              ET2 = 1;                                        // 允许T2中断
 102   1              T2CON   = 4;                            // 自动重装的定时器
 103   1              TR2 = 1;                                        // 启动
 104   1              EA      = 1;
 105   1      }
 106          
 107          /* ==============================================================
 108           定时器CT2中断服务程序
 109           ============================================================== */
 110          void timer2Int(void) interrupt 5
 111          {
 112   1              TF2 = 0;                                                        /* 溢出标志必须由软件清零*/
 113   1              EXF2 = 0;                                                       /* 捕获标志必须由软件清零*/
 114   1              if(timerForDelay)timerForDelay--;       /* 定时变量处理                 */
 115   1      }
 116          
 117          /* ==============================================================
C51 COMPILER V8.01   EEPDEMO                                                               12/19/2005 20:22:59 PAGE 3   

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

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


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