stc8h8k64u的EEPROM,断电上电读取部分数据出错。
<p>工作逻辑:stc8h8k64u的串口DMA_485和触摸屏通讯,单片机每200ms读取一次触摸屏的参数寄存器(共19个16位寄存器),如果发现用户对触摸屏的参数寄存器做了改动,和上一次值不一样,就擦除EEPROM,把19个参数写一遍,正常情况下,如果用户不操作触摸屏,每次读取的寄存器参数和前一次一样,就不会触发操作擦写EEPROM;所以每次上电开机,把存在EEPROM中上次断电前存入的参数,读取使用。</p><p>目前出现的问题:单片机串口DMA工作正常,触摸屏发送的数据(44个字节),22个字节存入EEPROM中然后再读出通过串口输出,可以看到读出来的数据都是是正确的,这是否表明已经正确写入了eeprom中了?但是当我断电上电再读eeprom,会出现前5个字节的数据是正常的,后面的数据有2字节是对的,其余全部是错的。工作中大部分时间是不擦写eeprom的。</p>
<p>程序在烧录的时候,频率选择33.1776MHz;分配给eeprom的空间是6KB;我擦除的是两个扇区0x1000,0x1200;分别存储在0x1010,0x01020.......0x101f; 0x1210,0x12020.......0x1260;<br />
断电上电数据正确的是0x1010......0x1070;</p>
<p>我单独写了一个测试eeprom的程序,下面的程序是正常的,折腾两天了,一直解决不了。附上eeprom擦写读程序,那位大佬帮忙指点一下。<br />
void IapIdle()</p>
<p>{ </p>
<p>IAP_CONTR = 0; //关闭IAP功能 </p>
<p>IAP_CMD = 0; //清除命令寄存器 </p>
<p>IAP_TRIG = 0; //清除触发寄存器 </p>
<p>IAP_ADDRH = 0x80; //将地址设置到非IAP区域 </p>
<p>IAP_ADDRL = 0;</p>
<p>}</p>
<p>uchar EEPROM_Read(uint Addr)</p>
<p>{ </p>
<p> uchar Data; </p>
<p>EA = 0; </p>
<p>IAP_CONTR = 0x80; //使能IAP </p>
<p>IAP_TPS = 33; //设置等待参数33.1776MHz </p>
<p>IAP_CMD = 0x01; //设置IAP读命令 </p>
<p>IAP_ADDRL = Addr; //设置IAP低地址 </p>
<p> IAP_ADDRH = Addr >> 8; //设置IAP高地址 </p>
<p> IAP_TRIG = 0x5a; //写触发命令(0x5a) </p>
<p> IAP_TRIG = 0xa5; //写触发命令(0xa5) </p>
<p><em>nop</em>(); <em>nop</em>(); <em>nop</em>(); </p>
<p>Data = IAP_DATA; //读IAP数据 </p>
<p> IapIdle(); //关闭IAP功能 </p>
<p>EA = 1; </p>
<p> return Data;</p>
<p>}</p>
<p>void EEPROM_Write(uint Addr, uchar Data)</p>
<p>{ </p>
<p>EA = 0; </p>
<p>IAP_CONTR = 0x80; //使能IAP </p>
<p>IAP_TPS = 33; //设置等待参数33.1776MHz </p>
<p>IAP_CMD = 0x02; //设置IAP写命令 </p>
<p>IAP_ADDRL = Addr; //设置IAP低地址 </p>
<p> IAP_ADDRH = Addr >> 8; //设置IAP高地址 </p>
<p>IAP_DATA = Data; //写IAP数据 </p>
<p> IAP_TRIG = 0x5a; //写触发命令(0x5a) </p>
<p>IAP_TRIG = 0xa5; //写触发命令(0xa5) </p>
<p> <em>nop</em>(); <em>nop</em>(); <em>nop</em>(); </p>
<p> IapIdle(); //关闭IAP功能 </p>
<p>EA = 1;</p>
<p>}</p>
<p>void EEPROM_Erase(uint Addr)</p>
<p>{ </p>
<p>EA = 0; </p>
<p>IAP_CONTR = 0x80; //使能IAP </p>
<p>IAP_TPS = 33; //设置等待参数33.1776MHz </p>
<p> IAP_CMD = 0x03; //设置IAP擦除命令 </p>
<p>IAP_ADDRL = Addr; //设置IAP低地址 </p>
<p>IAP_ADDRH = Addr >> 8; //设置IAP高地址 </p>
<p>IAP_TRIG = 0x5a; //写触发命令(0x5a) </p>
<p> IAP_TRIG = 0xa5; //写触发命令(0xa5) </p>
<p><em>nop</em>(); <em>nop</em>(); <em>nop</em>(); IapIdle(); //关闭IAP功能 </p>
<p>EA = 1;</p>
<p>}</p>
【新提醒】EEPROM的使用 请 配合比较器做掉电检测 | 唯一正解,电力系统标准应用 - EEPROM/DataFlash 国芯人工智能技术交流网站 - AI32位8051交流社区
多加几个nop(); 试试。 wulin 发表于 2026-5-17 12:29
多加几个nop(); 试试。
加了nop();没有改善,还是一样, 神农鼎 发表于 2026-5-17 12:08
【新提醒】EEPROM的使用 请 配合比较器做掉电检测 | 唯一正解,电力系统标准应用 - EEPROM/DataFlash 国芯 ...
硬件已经做好了,不好加元器件呢 dxm121 发表于 2026-5-17 15:31
硬件已经做好了,不好加元器件呢
先飞线测试下 dxm121 发表于 2026-5-17 15:31
加了nop();没有改善,还是一样,
程序没有问题,再降频11.0592试试。不是有特别需求不要使用高频时钟,可以避免许多麻烦。 烧录附件例子到芯片里试试,功能验证正常后再进行修改或者移植。 我也出现过。将keil编辑优化改一下解决。原来在6 往小改。我的也困扰很久。最后发现优化问题。而且问题很好复现
页:
[1]