找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3332|回复: 9
打印 上一主题 下一主题
收起左侧

请问STC单片机的eeprom 的写入问题

[复制链接]
跳转到指定楼层
楼主
ID:518902 发表于 2020-9-21 21:11 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我知道stc的eeprom是flash做出来的eeprom,不是严格意义上的,但是我想  它不是flash闪存吗 必须通过擦除才能把0变成1,我想:如果我这样:在第一个扇区写入 00 FF FF...........FF

然后我又对它修改一番 改成写入 00 00 FF.....FF,不知能不能直接写入成功呢?
于是我编写了程序,发现毫无反应.......无语中
不知道大家有试过吗? 能否直接写入(新的0数值而不先擦除)  呢
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:807591 发表于 2020-9-22 08:40 | 只看该作者
必须是整个扇区擦除后都是FF....可以对任意一个字节写数据...
回复

使用道具 举报

板凳
ID:213173 发表于 2020-9-22 08:54 | 只看该作者
楼主的想法是正确的,可能是测试方法不对得不到预想结果。这是用TX-1C实验板的测试程序,下载时勾选擦除用户EEPROM区。
  1. #include <reg52.h>      //52系列单片机头文件
  2. #include <intrins.h>
  3. #define uchar unsigned char
  4. #define uint unsigned int
  5. //定义ISP的操作命令
  6. #define RdCommand 0x01                //读命令
  7. #define PrgCommand 0x02                //写命令
  8. #define EraseCommand 0x03        //擦除命令
  9. #define WaitTime 0x01                 //定义CPU的等待时间,写入硬件延时
  10. /*STC89系列EEPROM寄存器声明*/
  11. sfr ISP_DATA=0xe2;                //0000,0000 EEPROM数据寄存器
  12. sfr ISP_ADDRH=0xe3;                //0000,0000 EEPROM地址高字节
  13. sfr ISP_ADDRL=0xe4;                //0000,0000 EEPROM地址第字节
  14. sfr ISP_CMD=0xe5;                   //xxxx,xx00 EEPROM命令寄存器
  15. sfr ISP_TRIG=0xe6;                //0000,0000 EEPRPM命令触发寄存器
  16. sfr ISP_CONTR=0xe7;                //0000,x000 EEPROM控制寄存器

  17. sbit dula=P2^6;  //声明U1锁存器的锁存端
  18. sbit wela=P2^7;  //声明U2锁存器的锁存端

  19. uchar code table[]={
  20. 0x3f,0x06,0x5b,0x4f,
  21. 0x66,0x6d,0x7d,0x07,
  22. 0x7f,0x6f,0x77,0x7c,
  23. 0x39,0x5e,0x79,0x71};

  24. uchar data dis_buf[3];
  25. uchar num,i;

  26. void delayms(uint xms)   
  27. {
  28.         uint i,j;
  29.         for(i=xms;i>0;i--)        //i=xms即延时约xms毫秒
  30.                 for(j=110;j>0;j--);
  31. }

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

  97. void main()
  98. {
  99.         num=byte_read(0x2000);//读取EEPROM中数据
  100.         byte_write(0x2000,num<<1);//从低位加0,写入新数据。只能写0不可写1!
  101.         if(num==0)//上电第9次
  102.                 SectorErase(0x2000);//擦除扇区重新恢复0xff
  103.         while(1)
  104.         {
  105.                 dis_buf[0]=table[num/100%10];
  106.                 dis_buf[1]=table[num/10%10];
  107.                 dis_buf[2]=table[num%10];
  108.                 display();
  109.                 delayms(1);
  110.         }
  111. }
复制代码
回复

使用道具 举报

地板
ID:65956 发表于 2020-9-22 08:54 | 只看该作者
STC的手册已有说了,要写之前要把要写入的扇区给先擦除,然后再写就能保证写入的万无一失,如果不擦就先写当然也可以,但是能否写正确就不能保证了,按官方方法操作肯定不会有问题的
回复

使用道具 举报

5#
ID:88256 发表于 2020-9-22 09:00 | 只看该作者
不应该毫无反应的,把你的程序贴出来看看呗
回复

使用道具 举报

6#
ID:311846 发表于 2020-9-22 09:05 | 只看该作者
不按规范操作没试过,一般都是按照官方给的操作,没出现过问题,你不按操作来,人家都说了错误会操作失败咯!还要去试。你硬是想知道,打电话去问问厂商看他怎么设计的吧!
回复

使用道具 举报

7#
ID:147710 发表于 2020-9-22 10:08 | 只看该作者
本帖最后由 XTXB 于 2020-9-22 10:40 编辑

STC15亲测可行,STC8G要加这个命令才行:ISP_TPS = 12;(12M晶振,24M晶振要改为24)               
回复

使用道具 举报

8#
ID:136485 发表于 2020-9-22 11:28 | 只看该作者
你要重写必须要重新擦除,而且是一擦就是一个扇区
回复

使用道具 举报

9#
ID:748096 发表于 2020-9-22 16:07 | 只看该作者
理论上应该可以写入成功,只要是FF就可以写入数据
回复

使用道具 举报

10#
ID:518902 发表于 2020-9-22 23:23 | 只看该作者
XTXB 发表于 2020-9-22 10:08
STC15亲测可行,STC8G要加这个命令才行:ISP_TPS = 12;(12M晶振,24M晶振要改为24)

是这样呀! 谢谢您
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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