找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 883|回复: 4
收起左侧

向各位大佬学习:这个单片机EEPROMD的例子无法保存数据?

[复制链接]
ID:706724 发表于 2023-2-28 22:04 | 显示全部楼层 |阅读模式
这个是论坛的例子,在开发板将这个EEPROMD的例子进行验证,发现无法保存关机前的LED 灯的状态!不知道问题出在哪里?恳请高手指点一二!

单片机源程序如下:
  1. /***************************************************************
  2.     作品:EEPROM实验,开机还原关电前LED的亮灭状况
  3.   单片机:STC89C52RC
  4.     晶振:12M
  5. 编译环境:Keil uVision4 V9.00
  6. ***************************************************************/     
  7. //#include <STC89C52RC.H>
  8. #include <reg52.h>
  9. #include <intrins.h>
  10. #define uchar unsigned char   
  11. #define uint unsigned int
  12. /****************特殊功能寄存器声明****************/
  13. sfr ISP_DATA = 0xe2;   
  14. sfr ISP_ADDRH = 0xe3;     
  15. sfr ISP_ADDRL = 0xe4;   
  16. sfr ISP_CMD = 0xe5;   
  17. sfr ISP_TRIG = 0xe6;      
  18. sfr ISP_CONTR = 0xe7;
  19. sbit LED1 = P2^0;
  20. sbit LED2 = P2^1;
  21. sbit K1   = P3^2;                           //按钮1
  22. sbit K2   = P3^3;                           //按钮2
  23. void  cc(uint addr);
  24. void  xcx(uint addr,uchar dat);
  25. uchar dcx(uint addr);
  26. void  Q0();
  27. /*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
  28. 函数:主程序
  29. ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/

  30. void main(void)
  31. {
  32.    uchar V;
  33.    V = dcx(0x2002);                          // 开机读取EEPROM区2002h数据,还原关电前LED的亮灭状况
  34.    if(V == 2)          {LED1=0;LED2=1;}
  35.    else if(V == 6){LED1=0;LED2=0;}
  36.    while(1)
  37.      {
  38.       if(!K1)
  39.             {
  40.               while(!K1);
  41.               LED1=0;LED2=1;
  42.               cc(0x2000);                  // 擦除第1个扇区(2000h~21FFh)
  43.               xcx(0x2002,2);          // 对EEPROM区2002h写入2
  44.             }
  45.           if(!K2)
  46.             {
  47.               while(!K2);
  48.               LED1=0;LED2=0;
  49.               cc(0x2000);                  // 擦除第1个扇区(2000h~21FFh)
  50.               xcx(0x2002,6);                          // 对EEPROM区2002h写入6
  51.             }
  52.      }
  53. }
复制代码


回复

使用道具 举报

ID:213173 发表于 2023-3-1 07:34 | 显示全部楼层
  1. /***************************************************************
  2.     作品:EEPROM实验,开机还原关电前LED的亮灭状况
  3.   单片机:STC89C52RC
  4.     晶振:12M
  5. 编译环境:Keil uVision4 V9.00
  6. ***************************************************************/     
  7. //#include <STC89C52RC.H>
  8. #include <reg52.h>
  9. #include <intrins.h>
  10. #define uchar unsigned char   
  11. #define uint unsigned int
  12. //定义ISP的操作命令
  13. #define RdCommand 0x01                //读命令
  14. #define PrgCommand 0x02                //写命令
  15. #define EraseCommand 0x03        //擦除命令
  16. #define WaitTime 0x01                 //定义CPU的等待时间,写入硬件延时
  17. /****************特殊功能寄存器声明****************/
  18. sfr ISP_DATA = 0xe2;   
  19. sfr ISP_ADDRH = 0xe3;     
  20. sfr ISP_ADDRL = 0xe4;   
  21. sfr ISP_CMD = 0xe5;   
  22. sfr ISP_TRIG = 0xe6;      
  23. sfr ISP_CONTR = 0xe7;

  24. sbit LED1 = P2^0;
  25. sbit LED2 = P2^1;
  26. sbit K1   = P3^2;                           //按钮1
  27. sbit K2   = P3^3;                           //按钮2

  28. /* ================ 打开 ISP,IAP 功能 ================= */
  29. void ISP_IAP_enable(void)
  30. {
  31.         EA = 0;       /* 关中断   */
  32.         ISP_CONTR = ISP_CONTR & 0x18;       /* 0001,1000 */
  33.         ISP_CONTR = ISP_CONTR | WaitTime; /* 写入硬件延时 */
  34.         ISP_CONTR = ISP_CONTR | 0x80;       /* ISPEN=1  */
  35. }
  36. /* =============== 关闭 ISP,IAP 功能 ================== */
  37. void ISP_IAP_disable(void)
  38. {
  39.         ISP_CONTR = ISP_CONTR & 0x7f; /* ISPEN = 0 */
  40.         ISP_TRIG = 0x00;
  41.         EA   =   1;   /* 开中断 */
  42. }
  43. /* ================ 公用的触发代码 ==================== */
  44. void ISPgoon(void)
  45. {
  46.         ISP_IAP_enable();   /* 打开 ISP,IAP 功能 */
  47.         ISP_TRIG = 0x46;  /* 触发ISP_IAP命令字节1 */
  48.         ISP_TRIG = 0xb9;  /* 触发ISP_IAP命令字节2 */
  49.         _nop_();
  50. }
  51. /* ==================== 字节读 ======================== */
  52. unsigned char byte_read(unsigned int byte_addr)
  53. {
  54.         ISP_ADDRH = (unsigned char)(byte_addr >> 8);/* 地址赋值 */
  55.         ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
  56.         ISP_CMD   = ISP_CMD & 0xf8;   /* 清除低3位  */
  57.         ISP_CMD   = ISP_CMD | RdCommand; /* 写入读命令 */
  58.         ISPgoon();       /* 触发执行  */
  59.         ISP_IAP_disable();    /* 关闭ISP,IAP功能 */
  60.         return (ISP_DATA);    /* 返回读到的数据 */
  61. }
  62. /* ================== 扇区擦除 ======================== */
  63. void SectorErase(unsigned int sector_addr)
  64. {
  65.         unsigned int iSectorAddr;
  66.         iSectorAddr = (sector_addr & 0xfe00); /* 取扇区地址 */
  67.         ISP_ADDRH = (unsigned char)(iSectorAddr >> 8);
  68.         ISP_ADDRL = 0x00;
  69.         ISP_CMD = ISP_CMD & 0xf8;   /* 清空低3位  */
  70.         ISP_CMD = ISP_CMD | EraseCommand; /* 擦除命令3  */
  71.         ISPgoon();       /* 触发执行  */
  72.         ISP_IAP_disable();    /* 关闭ISP,IAP功能 */
  73. }
  74. /* ==================== 字节写 ======================== */
  75. void byte_write(unsigned int byte_addr, unsigned char original_data)
  76. {
  77.         ISP_ADDRH = (unsigned char)(byte_addr >> 8);  /* 取地址  */
  78.         ISP_ADDRL = (unsigned char)(byte_addr & 0x00ff);
  79.         ISP_CMD  = ISP_CMD & 0xf8;    /* 清低3位 */
  80.         ISP_CMD  = ISP_CMD | PrgCommand;  /* 写命令2 */
  81.         ISP_DATA = original_data;   /* 写入数据准备 */
  82.         ISPgoon();       /* 触发执行  */
  83.         ISP_IAP_disable();     /* 关闭IAP功能 */
  84. }
  85. void delayms(uint xms)  
  86. {
  87.         uint i,j;
  88.         for(i=xms;i>0;i--)
  89.                 for(j=120;j>0;j--);
  90. }

  91. /*┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈
  92. 函数:主程序
  93. ┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈┈*/

  94. void main(void)
  95. {
  96.         uchar V;
  97.         V = byte_read(0x2002);             // 开机读取EEPROM区2002h数据,还原关电前LED的亮灭状况
  98.         if(V == 2){LED1=0;LED2=1;}
  99.         else if(V == 6){LED1=1;LED2=0;}
  100.         else {LED1=0;LED2=0;}//首次上电EEPROM的默认数据是0xff
  101.         while(1)
  102.         {
  103.                 if(!K1)
  104.                 {
  105.                         delayms(10);
  106.                         if(!K1)
  107.                         {
  108.                                 LED1=0;LED2=1;
  109.                                 while(!K1);//等待松手
  110.                                 SectorErase(0x2000);          // 擦除第1个扇区(2000h~21FFh)
  111.                                 byte_write(0x2002,2);         // 对EEPROM区2002h写入2
  112.                         }
  113.                 }
  114.                 if(!K2)
  115.                 {
  116.                         delayms(10);
  117.                         if(!K2)
  118.                         {
  119.                                 LED1=1;LED2=0;
  120.                                 while(!K2);//等待松手
  121.                                 SectorErase(0x2000);                  // 擦除第1个扇区(2000h~21FFh)
  122.                                 byte_write(0x2002,6);               // 对EEPROM区2002h写入6
  123.                         }
  124.                 }
  125.         }
  126. }
复制代码
回复

使用道具 举报

ID:161164 发表于 2023-3-1 09:10 | 显示全部楼层
代码不全,请重贴
回复

使用道具 举报

ID:996773 发表于 2023-3-1 15:39 | 显示全部楼层
c语言怎么这么长,测试eeprom不要整这些按钮啥的,直接写个八位数据存到2000H,

下次通电直接读取出来发送到p0口八个指示灯看看就行了,新手写程序一个按钮延时

就可能把擦除过程给搅黄了。
回复

使用道具 举报

ID:706724 发表于 2023-3-4 10:44 | 显示全部楼层

这个例子,开机也总是回到默认的状态。LED1,LED2同时亮
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表