究竟该怎样正确读写EEPROM?
./emotion/em078.gif大家好!
小弟在使用mega128时需要将一些程序运行中需要的一些初始设置值存放到EEPROM中,但是在调试中遇到如下问题:
调试环境:ICC6.31A+AVRstudio4.11
1)在AVRstudio下仿真,在程序里先把数据写入EEPROM,此时在仿真环境下EEPROM中观察到的数据变化是正确的;
2)然后把 程序里的数据写入EEPROM语句屏蔽,再用ICC编译后再用AVRstudio仿真,程序运行后,读出的EEPROM对应的数据全变为为0xFF。
为什么重新下载程序后,会读EEPROM内容不对??
我使用的是mega128手册中的EEPROM_write(x,x)和EEPROM_read(xx)程序。小弟在论坛里看了相关的一些帖子,还是有些地方弄得不太懂,.
1.ICCAVR编译后的.eep文件( INTEL HEX 格式文件包含了EEPROM 的初始化数据),这个文件到底该怎么用,能否详细的说明一下。
2.在AVRstudio中该如何设置图中画框的选项。
3.UP/DownloadDebugPlatformMemory这个选项应该在什么情况下使用?
请了解的朋友指教指教,不胜感谢!!!!!!!
http://cache.amobbs.com/bbs_upload782111/files_2/armok0154688.jpg .eep文件直接在上面的窗口中写入eeprom即可。
好象程序要和EEPROM一起写入才行,如果只写一个另外的那个好像也被檫除了,变成了FF 榕寺位eesave选了没?没选就嚓掉了 每次仿真的时候会把eeprom檫掉的 还是不行呐,我现在都有点糊涂了,哪位朋友能不能肯定的给个操作流程,尽量详细点,谢谢了!
我现在的操作流程是:1.在程序里先把数据写入EEPROM,在AVRstudio中编译,然后选择UP/DownloadDebugPlatformMemory这个选项将写好数据后的.eep文件保存;2.然后把 程序里的数据写入EEPROM语句屏蔽,改为读EEPROM中的指定位,用ICC编译将生成的.eep文件换为前次保存的.eep文件;3.在到AVRstudio中同时将程序文件和.eep文件写入芯片,但是运行仿真查看时还都是0xFF,这是怎么回事,是我的操作有问题吗?请指教
-----此内容被stronghold于2005-06-29,20:47:42编辑过 我也想知道如何操作,并请教.eep文件如何生存?请高手指点. LZ的问题偶也不知道怎么解决,在这里提供一个对EEPROM进行读、写操作的思路,仅供参考。如果EEPROM中需要存储的有用的数据不多的时候,可以采用如下的方法对EEPROM进行读、写,基本上可以避免出错。
向EEPROM中写数据时,每个数据都写在EEPROM的连续3个单元中,写完后再将刚才写入的内容读出,与之前写的数据进行比较,不一致则重写。
/*****************************************
向EEPROM中写数据子程序
*****************************************/
void write_eeprom(void)
{
uint i;
uchar CheckCount=0;
uchar CheckStatus1=0;
uchar CheckStatus2=1;
for(i=0;i<3;i++) //将新的设置写入到EEPROM 的3个连续单元中
EEPROM_WRITE(i,WrEeprom);
while(CheckStatus1 == 0)
{
for(i=0;i<3;i++) //将刚才写入的数据读出
EEPROM_READ(i,EepromData);
for(i=0;i<3;i++)
{
if(EepromData != WrEeprom)
//比较刚才写入的数据与设置值WrEeprom是否一致
{
CheckStatus2=0; //如果不一致,则改变标志位,并重新写入数据
EEPROM_WRITE(i,WrEeprom);
}
}
if(CheckStatus2 == 0)//如果检测到有数据不一致的情况,则要重新进行比较
{
CheckStatus1 = 0;
CheckStatus2 = 1;
CheckCount++;
}
else //否则将标志位置1,跳出循环
{
CheckStatus1 = 1;
CheckCount=0;
}
if(CheckCount == 100)
//如果连续写EEPROM 100次都有数据不一致的情况,则发消息给上位机,并跳出循环
{
CheckCount=0;
CheckStatus1 = 1;
}
}
读EEPROM的数据时,读EEPROM的连续3个单元,读完后将这3个单元的内容进行比较,有两个一致的数据则认为是正确的数据。
/*****************************************
读EEPROM中数据子程序
*****************************************/
void read_eeprom(void)
{
uint i;
for(i=0;i<3;i++)
EEPROM_READ(i,EepromData); //读EEPROM中的数据
if(EepromData == EepromData)//如果第0个与第1个数据一致
{
if(EepromData == EepromData)//再比较第0个与第2个数据是否一致
EepromStatus=1; //如果3个数据完全一致,则置标志位为1
else if(EepromData != EepromData)//如果第2个数据与第0个不一致
{
EepromData= EepromData;
//则认为第2个数据有误,用第0个数据覆盖掉第2个数据
EEPROM_WRITE(2,EepromData); //将数据重新写入EEPROM EepromStatus=2; //并将标志位置为2
}
}
else if(EepromData != EepromData) //如果第0个与第1个数据不一致
{
if(EepromData == EepromData)//再判断第0个数据与第2个数据是否一致
{
EepromData= EepromData;
//如果一致,则认为第1个数据有误,用第0个数据覆盖掉第1个数据
EEPROM_WRITE(1,EepromData); //将数据重新写入EEPROM
EepromStatus=2; //同时将标志位置为2
}
else if(EepromData != EepromData)//如果第0个数据与第2个数据也不一致
{
if(EepromData == EepromData)
//再判断第1个数据与第2个数据是否一致
{
EepromData= EepromData;
//如果一致,则认为第0个数据有误,用第1个数据覆盖掉第0个数据
EEPROM_WRITE(0,EepromData); //将数据重新写入EEPROM
EepromStatus=2; //同时将标志位置为2
}
else if(EepromData != EepromData)
//如果第1个数据与第2个数据也不一致,说明3个数据都不一致,则EEPROM数据出错
EepromStatus=0; //将标志位置为0
}
}
switch(EepromStatus)
{
case 0x00: //3个数据都不一致
******;
break;
case 0x01: //3个数据完全一致
******;
break;
case 0x02: //有一个数据出错
******;
break;
}
}
-----此内容被LOVEMCU于2005-11-23,09:03:23编辑过 进入仿真模式后就自动把EEPROM给清除了啊!当然没有了。用JTAG坊真其实就是把程序烧到单片机了运行的,不信你把仿真器拔下来,程序肯定就运行了,所以进仿真模式和烧程序到单片机了效果是一样的,EEPROM已经被清除了。 jtag会擦出eeprom,isp不会 在防真的时候,JTAG ICE Options中Debug下Preserve EEPROM contenes when reprograming device 选项,有没有选呀,如果没选,那就会丢失的. 向6楼问下?
如果有大量数据要在EEPROM里进行读写该怎么办啊? 我觉得对于3中取2的问题,分成3个区域进行操作比“连续3个单元”更合理,例如以下的程序片段:
//定义内部 EEPROM 的地址分配
//MEGA16内部有512字节EEP,地址范围 0x0000 - 0x01FF
// 输出映像为 0x0011 - 0x0080 (112BYTE)
// 备份1 0x0081 - 0x00F0
// 备份2 0x00F1 - 0x0160
//3个区域互为备份
#defineEEpModuleId 0x0011 //modbus模块地址编号
#defineEEpWdtComp 0x0012 //看门狗门值
#defineEEpWdtAct 0x0013 //看门狗动作类型
#defineEEpIAPAct 0x0014 //升级标志 55H有效
#defineEEpOffLineStat 0x0015 //离线标志
……
这样在定义EEP地址时,可以连续排列,而不需要注意以3为模的问题,以下是读写函数:
/* ***************************************************************
**函数名称:ApEepRead()
**函数功能:读出数据 字节方式
**入口参数:wAddr操作地址
**出口参数:经过3中取2的数据
**备 注: 若有需要,自动更新备份文件
*************************************************************** */
uint8 ApEepRead(uint16 wAddr)
{
uint8 temp1,temp2,temp3;
temp1 = eeprom_read_byte(wAddr);
temp2 = eeprom_read_byte(wAddr + 0x70);
temp3 = eeprom_read_byte(wAddr + 0xF0);
if ((temp1 == temp2) && (temp2 == temp3))
{
return temp1;
}
else if ((temp1 == temp2) || (temp1 == temp3))
{
ApEepWrite(wAddr, temp1);
return temp1;
}
else if (temp2 == temp3)
{
ApEepWrite(wAddr, temp2);
return temp2;
}
else
{
ApEepWrite(wAddr, 0); //如果3个都不同的处理
return 0;
}
}
/* ***************************************************************
**函数名称:ApEepWrite()
**函数功能:写入数据 字节方式
**入口参数:wAddr待写入的地址wDate待写入的数据
**出口参数:
**备 注: 自动写备份文件
*************************************************************** */
void ApEepWrite(uint16 wAddr, uint8 wDate)
{
/* 先读出数据,如果一致就不需要再次写入 */
……
/* 写3次数据 */
eeprom_write_byte (wAddr, wDate);DelayNMs(10);
eeprom_write_byte (wAddr + 0x70, wDate);DelayNMs(10);
eeprom_write_byte (wAddr + 0xF0, wDate);DelayNMs(10);
}
以前在使用24Cxx时,总觉得3个数据连续挨着受破坏的概率要大于分散在3个不同的区域,测试的结果好象也映证了这一点。AVR的内部EEP没有经过这方面的测试
-----此内容被xrb3115于2006-04-04,23:08:17编辑过
-----此内容被xrb3115于2006-04-04,23:21:43编辑过 在JTAG ICE Options中Debug下Preserve EEPROM contenes when reprograming device 选项,选上那么就不会丢失了.
我之前也试过. 容丝位要设定为烧写时不擦除 一般就没有问题了 你尝试过在接收到串行中断请求“写全部EEPROM”指令后,先给上位机发送应答帧后,立即
写380字节,写EEPROM不出错吗?注:定时中断每隔20ms触发。 /********************************************************************
;*子程序名称: uint08 ReadEepromByte(uint16 addr)
;*程序功能: 读一字节数据从 EEPROM
;*输入参数:
;*输出参数:
;*调用函数:
;*******************************************************************/
uData08 ReadEepromByte_CLI(uData08 addr)
{
uData08 result;
uData08 temp=SREG;
while(EECR & (1<<1) );
__disable_interrupt();
result=ReadEepromByte(addr);
SREG=temp;
return result;
} http://cache.amobbs.com/bbs_upload782111/files_7/armok01163038.JPG
我用的下载软件和你使用的不一样.这里一定要注意熔丝位EESAVE要进行编程,也就是EESAVE=0,另外不要在烧写时对EEPROM擦除,我的软件设置就是不要在program option里的EEPROM打勾 新下载的MuCodeISP有些默认的熔丝位的设置要修改,记住修改后要点旁边的write键才能生效.
PS:MuCodeISP是并口下载软件 mark {:loveliness:}{:loveliness:}{:loveliness:} {:handshake:}。好学问~ 用ISP下载并设置好不会擦除EEPROM 不错 学习下
页:
[1]