找回密码
 立即注册

QQ登录

只需一步,快速开始

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

STC8F单片机EEPROM神奇事件

[复制链接]
跳转到指定楼层
楼主
ID:95375 发表于 2021-9-5 16:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
请问有哪个大人碰到过一组数据存到EEPROM中取出后数据是一样的,再写回数组中却使用异常的吗?从串口发送数据到电脑对比是数据存进去的和取出来的是真的一模一样的,但用来发射红外信号却异常,原数组数据却正常,再把备用数组数据写回原数组里也正常,太神奇了。
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:624769 发表于 2021-9-5 16:48 | 只看该作者
STC8F 系列 直接用 MOVC 读Eeprom 效率高,系统还不会暂停,会比较好一点。而且活用extern unsigned char code 可以直接当数组用,而不用预先读出来。
回复

使用道具 举报

板凳
ID:57657 发表于 2021-9-5 17:05 | 只看该作者
用MOVC指令访问,不管是ROM还是EEPROM,都是一样的速度,部分老型号不支持用MOVC访问EEPROM,C语言用 unsigned char code 指针。
回复

使用道具 举报

地板
ID:160500 发表于 2021-9-5 18:04 | 只看该作者
数据写入EEPROM,清零原数组,再读取EEPROM中的数据赋值给数组,此时暂停程序,检查数组中数据是否一致。如果一致,继续运行程序,看是否正常,不正常继续排查;如果数据不一致,则检查读取是否出错、写入数组的方法等等。
回复

使用道具 举报

5#
ID:417092 发表于 2021-9-5 19:24 | 只看该作者
没看懂你说的什么意思!!!
但是通信容易出问题的有
1,串口,发送和接收的波特率不一致。没使用校验。。。。
2,从高到低位,和 从低位到高位。弄反了。。。。
回复

使用道具 举报

6#
ID:401564 发表于 2021-9-5 23:45 | 只看该作者
神奇的事件,在99.9999%的情况下,是由于神奇的人引起的
刚开始学单片机的时候,总觉得单片机不是这不行就是那不行
现在,出了问题,首先排除的就是"单片机坏了"
回复

使用道具 举报

7#
ID:95375 发表于 2021-9-8 21:12 | 只看该作者
  1. 也许我没有表达清楚意思,就是一组数组数据通过红外发射后能正常控制设备,但把这组数组

  2. 数据保存到EEPROM后再取出放回数组再通过红外发射却不能控制设备了,可以确定这组数据在

  3. 存入前和取出后是完全一样的,没有出错也没有错序,可为什么就不能正常了,原以为是发射

  4. 用的数组重写数据造成出错,但用另外一组完全一样的数组同时保存数据,再把这组数据复制

  5. 到发射数组后却能正常控制。


  6. 建立两组数组

  7. uint  remotedata[207]; //发射数组
  8. uint  temp[207];        //临时数组



  9. 红外接收头收到数据后存到发射数组里然后通过红外发射头发射能正常控制设备

  10. 然后把发射数组数据存到EEPROM里

  11. /*-------------------------------
  12. 写一字节数据到ISP/IAP/EEPROM区域
  13. -------------------------------*/
  14. void IapProgram(int addr, char dat)
  15. {
  16.     IAP_CONTR = WT_12M;                         //使能IAP
  17.     IAP_CMD = 2;                                //设置IAP写命令
  18.     IAP_ADDRL = addr;                           //设置IAP低地址
  19.     IAP_ADDRH = addr >> 8;                      //设置IAP高地址
  20.     IAP_DATA = dat;                             //写IAP数据
  21.     IAP_TRIG = 0x5a;                            //写触发命令(0x5a)
  22.     IAP_TRIG = 0xa5;                            //写触发命令(0xa5)
  23.     _nop_();
  24.     IapIdle();                                  //关闭IAP功能
  25. }


  26.                                                                                

  27. for(i=0;i<207;i++)//把学到的数据保存到内存
  28.                                                                                 {
  29.                                                                                        

  30. IapProgram(IAP_ADDRESS+i,remotedata[i]);//写数据到EEPROM
  31.                                                                                 }
  32.                                                                                
  33.                                                                                

  34. for(i=0;i<207;i++)//
  35.                                                                                 {
  36.                                                                                        

  37.         temp[i]=remotedata[i];//
  38.                                                                                 }


  39. 官方写入代码,应该没问题吧,同时也把数据写入到临时数组里



  40. 然后把EEPROM数据读回到发射数组里

  41.                                 for(i=0;i<207;i++)//
  42.                                 {
  43.                                         remotedata[i]=IapRead(IAP_ADDRESS+i);//把

  44. 内存中数据读到数组
  45.                                 }


  46. 也没问题吧,通过串口对比过写入和读出的数据是完全一模一样的,如果是单单保存数据这是

  47. 完全没毛病的,但通过红外发射头发射这组数据却不正常了

  48. 不服真不行啊,把临时数组里的数据写回到发射数组里就又发射正常了

  49.                         for(i=0;i<207;i++)//
  50.                         {
  51.                                 remotedata[i]=temp[i];//
  52.                         }               

  53. 把EEPROM读取换成MOVC读取是一个样

  54. //BYTE IapRead(WORD addr)
  55. char IapRead(int addr)
  56. {
  57.                 addr += IAP_OFFSET; //使用 MOVC 读取 EEPROM 需要加上相应的偏移
  58.                 return *(unsigned char code *)(addr); //使用 MOVC 读取数据       
  59. }



复制代码
回复

使用道具 举报

8#
ID:95375 发表于 2021-9-8 21:20 | 只看该作者
188610329 发表于 2021-9-5 16:48
STC8F 系列 直接用 MOVC 读Eeprom 效率高,系统还不会暂停,会比较好一点。而且活用extern unsigned char c ...

换MOVC读取还是一样,请问extern unsigned char code当数组用的话要怎么用,比如

for(i=0;i<207;i++)//
{
        temp[ i]=remotedata[ i];//
}

要怎样用extern unsigned char code替代,我怎么感觉这个是定义常量用的呢
回复

使用道具 举报

9#
ID:95375 发表于 2021-9-8 21:22 | 只看该作者
npn 发表于 2021-9-5 17:05
用MOVC指令访问,不管是ROM还是EEPROM,都是一样的速度,部分老型号不支持用MOVC访问EEPROM,C语言用 unsig ...

谢谢,不是MOVC读取的问题,不会指针,看到指针就晕
回复

使用道具 举报

10#
ID:95375 发表于 2021-9-8 21:24 | 只看该作者
liuzx66 发表于 2021-9-5 18:04
数据写入EEPROM,清零原数组,再读取EEPROM中的数据赋值给数组,此时暂停程序,检查数组中数据是否一致。如 ...

数据是一致的,数据不一致那就好办了
回复

使用道具 举报

11#
ID:95375 发表于 2021-9-8 21:30 | 只看该作者
Y_G_G 发表于 2021-9-5 23:45
神奇的事件,在99.9999%的情况下,是由于神奇的人引起的
刚开始学单片机的时候,总觉得单片机不是这不行就是 ...

这是肯定的,在未知的知识前任何人对任何事都感觉到神奇,如同魔术一般,我只是想看看有没有人碰到我这样的问题,实在是想不明白相同的数据能做出不同的事情来,毕竟代码是没有思想的,只是按我们设定的路走,现在却变异了,肯定不是“单片机坏了”
回复

使用道具 举报

12#
ID:57657 发表于 2021-9-8 22:12 | 只看该作者
单片机内置的EEPROM,不是真正的EEPROM,而是Flash闪存 ,二进制1可以写成0,反过来就不可以,只有擦除才可以全部恢复为1,一次擦1扇区(512字节)。
24C02等EEPROM芯片没有扇区的说法,可以直接读写。
回复

使用道具 举报

13#
ID:624769 发表于 2021-9-8 23:45 | 只看该作者
liyago 发表于 2021-9-8 21:20
换MOVC读取还是一样,请问extern unsigned char code当数组用的话要怎么用,比如

for(i=0;i

创建一个汇编文件,
用  
CSEG      AT    2000H
Eeprom_DATA:      DS    0FFH
指向Eeprom 空间
然后 PUBLIC  Eeprom_DATA

然后再C语言 中 extern unsigned char code  Eeprom_DATA[];  来声明

那么, 对于C语言的判断, 就是引用 汇编里面定义的常量数组。 其实汇编里只是给了一个地址。
你C语言调用这个地址,就会到 0x2000 所对应的 Eeprom 里面 MovC 读出来了。
回复

使用道具 举报

14#
ID:624769 发表于 2021-9-8 23:48 | 只看该作者

看你的代码, 写入前没有擦除 Eeprom,  IAP的Eeprom, 必须擦除后才能正确写入,否则会乱七八糟的东西,即使两次写入相同的东西,也会变成乱七八糟的东西。
回复

使用道具 举报

15#
ID:161164 发表于 2021-9-8 23:52 | 只看该作者
最直观的方法就是用逻辑分析仪或示波器看看输出端的波型
比较一下成功和失败的分别

红外线发射是经38kHz调制后输出的
对时间有极高的要求

到现时为止你发的代码只有数据的存取
而没有数据转输出的那部分

会不会是直接读取EEPorm会对发射有影响?
回复

使用道具 举报

16#
ID:95375 发表于 2021-9-9 17:19 | 只看该作者
谢谢各位大大的回复,问题已解决了,原来是我所有数据都是按两位16进制来处理了,实际上数据中有3位16进制数,stc-isp自带的串口助手和XCOM V2.6都是显示两位16进制数,所以一时没有发现数据有错。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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