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

📄 eepdemo.lst

📁 stc单片机读写内部eeprom程序,可以直接使用
💻 LST
字号:
C51 COMPILER V8.01   EEPDEMO                                                               12/16/2005 22:10:43 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+进行了调试,但可以给其他芯片编程时作为参考。
  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                0x4000
  33                  #define EndSectoraddr   0xf200
  34                  #define EndAddr                 0xf3ff
  35          
  36          /* ------------- 定义扇区大小 ------------- */
  37          #define PerSector               512
  38          
  39          /* 用户程序需要记忆的数组, 用户实际使用了n-1个数据, */
  40          uchar Ttotal[16]        =
  41          {
  42                  0x55,                           /* 作为判别引导头使用,用户程序请不要修改它 */
  43                  /* 用户保存记忆的数据 */
  44                  0x01,   0x02,   0x03,   0x04,   0x05,   0x06,   0x07,   0x08,
  45                  0x09,   0x0a,   0x0b,   0x0c,   0x0d,   0x0e,   0x0f,
  46          };
  47          
  48          uint    timerForDelay,          /* 专供延时用的变量 */
  49                          i,                                      /* 循环变量                     */
  50                          EepromPtr;                      /* eeprom读写指针       */
  51          
  52          /* =========================== 外部函数列表 ============================*/
  53          extern uchar byte_read(uint byte_addr);         // byte读
  54          extern void byte_write(uint byte_addr, uchar original_data);
  55          extern void SectorErase(uint sector_addr);      // 扇区擦除
C51 COMPILER V8.01   EEPDEMO                                                               12/16/2005 22:10:43 PAGE 2   

  56          extern uchar byte_write_verify(uint byte_addr, uchar original_data);    // byte写并校验
  57          extern uchar ArrayWrite(uint begin_addr, uint len, uchar *array);       // byte数组写并校验
  58          extern void ArrayRead(uint begin_addr, uchar len);              // 读出, 保存在Ttotal[]中
  59          
  60          /* ================ 短延时 =============== */
  61          void delay(uint counter)
  62          {
  63   1              timerForDelay = counter;
  64   1              while(timerForDelay);
  65   1      }
  66          //////////////////////////////////////////////////////////////////
  67          // 初始化开启定时器2                                                                                    //
  68          //////////////////////////////////////////////////////////////////
  69          void initCT2()
  70          {
  71   1              RCAP2H  = 0xd8;
  72   1              RCAP2L  = 0xf0;
  73   1              TH2     = 0xd8;                                 // 定时器初值
  74   1              TL2     = 0xf0; 
  75   1              ES      = 0;                                    // 关闭通信中断
  76   1              ET2 = 1;                                        // 允许T2中断
  77   1              T2CON   = 4;                            // 自动重装的定时器
  78   1              TR2 = 1;                                        // 启动
  79   1              EA      = 1;
  80   1      }
  81          //////////////////////////////////////////////////////////////////
  82          // 定时器CT2中断服务程序                                                                                //
  83          //////////////////////////////////////////////////////////////////
  84          void timer2Int(void) interrupt 5
  85          {
  86   1              TF2 = 0;                                                        // 溢出标志必须由软件清零
  87   1              EXF2 = 0;                                                       // 捕获标志必须由软件清零
  88   1              if(timerForDelay)timerForDelay--;       // 定时变量处理
  89   1      }
  90          
  91          //////////////////////////////////////////////////////////////////
  92          // 从eeprom中读取数据                                                                                   //
  93          //////////////////////////////////////////////////////////////////
  94          void DataRestore()
  95          {
  96   1              EepromPtr = BaseAddr;                           /* 指向eeprom的起始点   */
  97   1              while(EepromPtr < EndAddr)                      /* 在eeprom的可用区域内 */
  98   1              {
  99   2                      if(byte_read(EepromPtr) == 0x55)/* 找到了上一次纪录的数据块     */
 100   2                      {
 101   3                              break;                                          /*      寻找完成        */
 102   3                      }
 103   2                      EepromPtr += 0x10;                              /* 指向下一个小区       */
 104   2              }
 105   1              if(EepromPtr >= EndAddr)                        /* 如果照遍都没有,就是新芯片   */
 106   1              {
 107   2                      EepromPtr = BaseAddr;                   /* 指向eeprom的起始点   */
 108   2                      while(ArrayWrite(EepromPtr, 0x10, Ttotal))      /* 初始化为默认数据     */
 109   2                      {
 110   3                              byte_write(EepromPtr, 0);       /* 该单元已经失效       */
 111   3                              if(EepromPtr < EndAddr)
 112   3                              {
 113   4                                      EepromPtr += 0x10;              /* 换一块新的小区       */
 114   4                              }
 115   3                              else
 116   3                              {
 117   4                                      P1=0;                                   /* 指示芯片内eeprom已经全部实效 */
C51 COMPILER V8.01   EEPDEMO                                                               12/16/2005 22:10:43 PAGE 3   

 118   4                                      EA= 0;                                  /* 不再做任何事 */
 119   4                                      while(1);                               /* 死机 */
 120   4                              }
 121   3                      }
 122   2              }
 123   1              ArrayRead(EepromPtr, 15);
 124   1      }
 125          
 126          //////////////////////////////////////////////////////////////////
 127          // 将需要记忆的数据保存到eeprom                                                                 //
 128          //////////////////////////////////////////////////////////////////
 129          void DataSave()
 130          {
 131   1      uint    wrPtr;                                                          /* 临时指针     */
 132   1      
 133   1      NextArea:
 134   1              byte_write_verify(EepromPtr, 0);                /* 将原来的标记清除     */
 135   1              EepromPtr += 0x10;                                              /* 目标存入地址         */
 136   1      
 137   1              /* -------------- 判断是否启用新的扇区 --------------- */
 138   1              if((EepromPtr & 0x1ff)==0)
 139   1              {
 140   2                      wrPtr = EepromPtr-0x200;        /* 上一个扇区的起始地址 */
 141   2                      SectorErase(wrPtr);             /* 将上一个扇区擦除,为以后重新启用准备 */
 142   2                      if(EepromPtr>=0xf400)           /* 已经用完了最后一个区域       */
 143   2                      {
 144   3                              EepromPtr=0x4000;               /* 从头开始     */
 145   3                      }
 146   2              }
 147   1              /* ----------- 数据存入前的准备 ----------- */
 148   1              /* 。。。。。。。。。。。。。。转移、处理       */
 149   1              Ttotal[0] = 0x55;                                               /* 重申本区域启用标记   */
 150   1              if(ArrayWrite(EepromPtr, 0x10, Ttotal)) /* 数据写入,如果有错换一块     */
 151   1              {
 152   2                      goto NextArea;
 153   2              }
 154   1      }
 155          
 156          void main()
 157          {
 158   1              /* 指示灯开始指示程序将要开始 */
 159   1              P1 = 0xff;                                      /* 所有LED熄灭  */
 160   1              initCT2();                                      /* CT2初始化,用来做定时器      */
 161   1              /* --------------- 演示 256 次读写操作 ----------------- */
 162   1              for(i=0;i<256;i++)
 163   1              {
 164   2                      DataRestore();                  /* 从eeprom中读取记忆数据       */
 165   2                      P1 = (uchar)((EepromPtr >> 4) & 0xff);  /* 显示读取地址*/
 166   2                      delay(200);                             /* 延时保留显示状态2秒          */
 167   2                      DataSave();                             /* 数据再次保存                         */
 168   2                      P1 = (uchar)((EepromPtr >> 4) & 0xff);  /* 显示写入地址*/
 169   2                      delay(300);                             /* 延时保留显示状态3秒          */
 170   2              }
 171   1      
 172   1              while(1);                                       /* 演示完毕 */
 173   1      }


MODULE INFORMATION:   STATIC OVERLAYABLE
   CODE SIZE        =    338    ----
   CONSTANT SIZE    =   ----    ----
   XDATA SIZE       =   ----    ----
C51 COMPILER V8.01   EEPDEMO                                                               12/16/2005 22:10:43 PAGE 4   

   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 + -