930电子网

 找回密码
 立即注册
艾克姆科技推出最新产品STC32G12K128开发板
查看: 15280|回复: 8

求助:关于EEPROM写入操作

[复制链接]

3

主题

11

帖子

53

积分

注册会员

Rank: 2

积分
53
发表于 2018-1-5 20:07:56 | 显示全部楼层 |阅读模式
代码如下://写入数据函数
void IapProgramByte(uint16 addr ,uint8 dat)
{
    EA= 0 ;
    IAP_CONTR = 0X83;
    IAP_CMD = 2;
    IAP_ADDRL = addr;
    IAP_ADDRH = addr >> 8;
    IAP_TRIG = 0X5A;
    IAP_TRIG = 0X5A;
    _nop_();
    IAP_DATA = dat;
    IapIdle(); //关闭 IAP
    EA = 1;
}

//调用部分,擦除动作前面做了
for(k = 0; k < 512;k ++)
{
    IapProgramByte(IAP_ADDRESS + k , k );
}
IAP_ADDRESS 设置的是 0x2000,单片机是 STC15W4K56S4。加上上面调用代码,无法回读到数据;去掉上面调用的代码,读到的数据是ff(调用之前有擦除数据,ff应该是默认的吧)。请问是写入数据函数错了吗,还是其它什么问题?
回复

使用道具 举报

3

主题

14

帖子

55

积分

注册会员

Rank: 2

积分
55
发表于 2018-1-6 09:07:15 | 显示全部楼层
把你main函数发出来,看看你整个的程序流程,上面有用到IapIdle()函数,说明下出处
回复 支持 反对

使用道具 举报

101

主题

333

帖子

7428

积分

版主

Rank: 7Rank: 7Rank: 7

积分
7428
发表于 2018-1-6 09:19:51 | 显示全部楼层
    写函数有这两句: IAP_TRIG = 0X5A;   IAP_TRIG = 0X5A;  是错误的。应该是:IAP_TRIG = 0X5A;   IAP_TRIG = 0XA5; 你试下
   
回复 支持 反对

使用道具 举报

3

主题

11

帖子

53

积分

注册会员

Rank: 2

积分
53
 楼主| 发表于 2018-1-8 10:41:18 | 显示全部楼层
正是河豚 发表于 2018-1-6 09:19
写函数有这两句: IAP_TRIG = 0X5A;   IAP_TRIG = 0X5A;  是错误的。应该是:IAP_TRIG = 0X5A;   IAP_T ...

这个是我打错了,先5A,后A5,代码是对的(是在公司做的,有加密系统,所以不能复制,纯手打。添加图片太不方便了。。。)
回复 支持 反对

使用道具 举报

3

主题

11

帖子

53

积分

注册会员

Rank: 2

积分
53
 楼主| 发表于 2018-1-8 10:50:53 | 显示全部楼层
本帖最后由 HelloBbx 于 2018-1-8 10:57 编辑
指尖陀螺 发表于 2018-1-6 09:07
把你main函数发出来,看看你整个的程序流程,上面有用到IapIdle()函数,说明下出处

void main ()
{
  uint8 k;
  P1M0 &= 0X3F;
  P1M1 &= 0X3F;
  P0M0 &= 0X1F;
  P0M1 &= 0X1F;

  Uart_Init();//串口初始化
  INIT0_Init();//中断初始化,有用到中断来控制读取
  Delay(10);
  ES = 1;
  EA = 1;
  IapEraseSector(IAP_ADDRESS);//清除数据
  Delay(10);  //加上了这段for语句,都读不到数据,去掉这一段,还可以读到数据
  for(k = 0; k < 512; k++)
  {
    IapProgramByte(IAP_ADDRESS + k, k);
  }
  while(1)
  {
    USART1_TX_Puts();//中断会控制一个标志位,每次中断才调用这个一次,调用完标志位清零
  }
}

//USART1_TX_Puts()函数
void USART1_TX_Puts()
{
  uint8 a;
  if(flag)//中断控制flag
  {
    ES = 0;
    a = IapReadByte(IAP_ADDRESS + i);
    i ++;
    SendDataByUart1(a);
    SendDataByUart1(0x0d); //换行符
    SendDataByUart1(0x0a);  //换行符
    ES = 1;
    flag = FALSE;
  }
}
回复 支持 反对

使用道具 举报

3

主题

14

帖子

55

积分

注册会员

Rank: 2

积分
55
发表于 2018-1-9 09:57:30 | 显示全部楼层
建议你先不要使用那么多外设,就是不使用串口、也不使用外部中断,就是针对EEPROM进行操作,可以先对一个存储空间写一个数,之后再读取这个存储空间的值,判断是不是自己写的数,对的话控制一个用户指示灯亮,不是的话也可以通过其他指示灯来判断看看是00还是FF,这样的目的就是先确定关于EEPROM操作函数的正确性,这个调通,再加功能实现复杂些的程序就是心中有数了。
回复 支持 反对

使用道具 举报

3

主题

11

帖子

53

积分

注册会员

Rank: 2

积分
53
 楼主| 发表于 2018-1-9 15:23:23 | 显示全部楼层
指尖陀螺 发表于 2018-1-9 09:57
建议你先不要使用那么多外设,就是不使用串口、也不使用外部中断,就是针对EEPROM进行操作,可以先对一个存 ...

我新建了个工程,代码都差不多,通过读回来的数据,发现数据又写进去了。。。但是怎么验证掉电数据还在没想到办法,写入数据在主函数里面,掉电再上电,会重新执行一次主函数前面的赋值操作吧,i也会重新置0,你有什么好办法吗?
回复 支持 反对

使用道具 举报

3

主题

14

帖子

55

积分

注册会员

Rank: 2

积分
55
发表于 2018-1-10 10:51:23 | 显示全部楼层
你可以这样操作,上电先读那个固定存储单元的值,然后把读出的值累加一再写进去,这样即使断电或重新下载程序,EEPROM里面的值都会再重新上电时被累加一,这个是艾克姆例程的思路,个人感觉还是不错的。
回复 支持 反对

使用道具 举报

3

主题

11

帖子

53

积分

注册会员

Rank: 2

积分
53
 楼主| 发表于 2018-1-10 15:03:56 | 显示全部楼层
指尖陀螺 发表于 2018-1-10 10:51
你可以这样操作,上电先读那个固定存储单元的值,然后把读出的值累加一再写进去,这样即使断电或重新下载程 ...

挺不错的,谢谢。
回复 支持 反对

使用道具 举报

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

本版积分规则

QQ|手机版|官方淘宝店|930电子网 ( 皖ICP备16000695号-2 )

Copyright © 合肥艾克姆电子科技有限公司
快速回复 返回顶部 返回列表