犯了一个低级错误,大家看看是否能雾里看花不迷糊

[复制链接]
9349|43
急驰的蚂蚁 发表于 2009-11-15 21:17 | 显示全部楼层
呵呵,大家按18楼老X的提示去找,很快能找到.
古道热肠 发表于 2009-11-15 10:39

我还是没看出来呀
高手 告诉我下,发消息我也行
急驰的蚂蚁 发表于 2009-11-15 21:25 | 显示全部楼层
假如ucCount很大时
EEPROM的存储不够,会出现问题
是这个问题吗?
ppsen 发表于 2009-11-15 22:47 | 显示全部楼层
32位,16位?
yewuyi 发表于 2009-11-16 08:56 | 显示全部楼层
那可能就是这两行中的uiTemp++造成的问题了,返回出去的都是++后的地址。
EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)& 0xff);
FDB_Current.DIR_FileSize += EEPROMread(uiTemp++);
t.jm 发表于 2009-11-16 09:17 | 显示全部楼层
FDB_Current.DIR_FileSize = EEPROMread(uiTemp++)<<24;
FDB_Current.DIR_FileSize += EEPROMread(uiTemp++)<<16;
这两句溢出了,要强制类型转换.
xwj 发表于 2009-11-16 09:17 | 显示全部楼层
本帖最后由 xwj 于 2009-11-16 09:47 编辑

yewuyi没找对哦,再去找!

LZ的本意就是要返回++后的地址,每次调用地址是自动增量的——这个不算BUG,BUG出在其他的低级错误上哦~
ppsen 发表于 2009-11-16 09:44 | 显示全部楼层
嘿嘿,EEPROMread返回的是uchar.........
huangqi412 发表于 2009-11-16 09:51 | 显示全部楼层
FDB_Current.DIR_FileSize += EEPROMread(uiTemp++);
*uiEEPROMAddress = uiTemp;

这个不要加加了吧,加加成下一个地址了
inter_zhou 发表于 2009-11-16 09:53 | 显示全部楼层
EEPROM写了之后是需要演示的!
EEPROM真正写的动作是在STOP命令之后,当EEPROM器件接收到STOP之后,内部的升压电路才会打开,从内部升压电路打开到烧写完成时需要时间的,上面的代码在写完一个字节后根本没有延时的动作又马上执行下一次的写,所以会导致写入部成功。

较好的做法是不用单个字节写,而是多个字节的连续写。写完之后并检测是否写入成功(POLLING)
inter_zhou 发表于 2009-11-16 09:56 | 显示全部楼层
所以楼主会有时候好像写入,然后读出都是对的,有时不读!

不同的EEPROM读写速度会有差异,就算是相同的型号,不同批次,也会有差异!
 楼主| 古道热肠 发表于 2009-11-16 10:56 | 显示全部楼层
哈哈,BUG已被识破,总结一下.

25楼"t.jm"网友指出了读函数中存在的硬性BUG,属此题正解.

22楼"急驰的蚂蚁"提到的EEPROM空间溢出是有可能,但这个在上层主调函数书写时会自己控制长度的,就象将指针指向内存数组,写数组尤其要小心,弄不好指针跨界,程序重启或出现怪异的现象.

29楼"inter_Zhou"提到的EEPROM函数写可能出错,应考虑批次差异性并校验,这个说法是对的,不过这个处理应该是在EEPROM的写驱动底层函数中完成.该函数目前以Void返回,较为理想的是应该返时写是否成功的结果信息给主调函数进行错误处理.
 楼主| 古道热肠 发表于 2009-11-16 11:01 | 显示全部楼层
贴上测试合格的可用代码,大家一看就明白了,哈哈,老X一眼就看出来了,实战经验丰富.
void WriteFileInfoToEEPROM(uint *uiEEPROMAddress)
{
        uint uiTemp;
       
        uiTemp = *uiEEPROMAddress;

        EEPROMwrite(uiTemp++,(FDB_Current.DIR_FstClusLO)>>8);
        EEPROMwrite(uiTemp++,(FDB_Current.DIR_FstClusLO)&0xff);                                //
        EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)>>24);
        EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)>>16);
        EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)>>8);
        EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)& 0xff);
        *uiEEPROMAddress = uiTemp;
}

#if 0
//Old        have a Bug in this Function
void ReadFileInfoFromEEPROM(uint *uiEEPROMAddress)
{
        uint uiTemp;
       
        uiTemp = *uiEEPROMAddress;

        FDB_Current.DIR_FstClusLO = EEPROMread(uiTemp++)<<8;
        FDB_Current.DIR_FstClusLO += EEPROMread(uiTemp++);
        FDB_Current.DIR_FileSize = EEPROMread(uiTemp++)<<24;
        FDB_Current.DIR_FileSize += EEPROMread(uiTemp++)<<16;
        FDB_Current.DIR_FileSize += EEPROMread(uiTemp++)<<8;
        FDB_Current.DIR_FileSize += EEPROMread(uiTemp++);

        *uiEEPROMAddress = uiTemp;
}
//
#endif

//Test        OK
#if 1
void ReadFileInfoFromEEPROM(uint *uiEEPROMAddress)
{
        uint uiTemp;
       
        uiTemp = *uiEEPROMAddress;

        FDB_Current.DIR_FstClusLO = EEPROMread(uiTemp++)<<8;
        FDB_Current.DIR_FstClusLO += EEPROMread(uiTemp++);
        FDB_Current.DIR_FileSize = ((ulong)EEPROMread(uiTemp++))<<24;
        FDB_Current.DIR_FileSize += ((ulong)EEPROMread(uiTemp++))<<16;
        FDB_Current.DIR_FileSize += ((ulong)EEPROMread(uiTemp++))<<8;
        FDB_Current.DIR_FileSize += EEPROMread(uiTemp++);

        *uiEEPROMAddress = uiTemp;
}
#endif
 楼主| 古道热肠 发表于 2009-11-16 11:03 | 显示全部楼层
文件很小时不出错,文件一长就出错.根源就在以下写法并未真正完成预期的功能
    FDB_Current.DIR_FileSize = EEPROMread(uiTemp++)<<24;
        FDB_Current.DIR_FileSize += EEPROMread(uiTemp++)<<16;
 楼主| 古道热肠 发表于 2009-11-16 11:05 | 显示全部楼层
实事上,2楼网友"ejack"的直觉和猜测也是对的.
 楼主| 古道热肠 发表于 2009-11-16 11:09 | 显示全部楼层
为什么
FDB_Current.DIR_FstClusLO = EEPROMread(uiTemp++)<<8;
        FDB_Current.DIR_FstClusLO += EEPROMread(uiTemp++);
不出错了,菜鸟可以试一试,Keil-C51在做这种操作时真不出错,实际上这是一个数据类型的默认转换物性的把握的问题,当然最好的写法是无法确实转换是否有效时,加上强制类型转换,保证万无一失,永不迷糊和犯低级错误.
desert_hawk 发表于 2009-11-16 11:20 | 显示全部楼层
void WriteFileInfoToEEPROM(uint *uiEEPROMAddress)
void ReadFileInfoFromEEPROM(uint *uiEEPROMAddress)
为什么参数要用指针传递呢?直接传uint型数据就行吧。
而且看了半天,貌似没找到EEPROMread和EEPROMwrite的原型。
LYXQ 发表于 2009-11-16 11:38 | 显示全部楼层
这个程序是写EEPROM的,程序传递的也是指针,按道理那个变量应该是指针才有意义
void WriteFileInfoToEEPROM(uint *uiEEPROMAddress)
{
        uint *uiTemp;
        
        uiTemp = uiEEPROMAddress;

        EEPROMwrite(uiTemp++,(FDB_Current.DIR_FstClusLO)>>8);
        EEPROMwrite(uiTemp++,(FDB_Current.DIR_FstClusLO)&0xff);                                //
        EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)>>24);
        EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)>>16);
        EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)>>8);
        EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)& 0xff);
        uiEEPROMAddress = uiTemp;
}
 楼主| 古道热肠 发表于 2009-11-16 14:26 | 显示全部楼层
36# desert_hawk
主发是为了采用传址方式,将子程序中修改的结果传回主调程序.
 楼主| 古道热肠 发表于 2009-11-16 14:34 | 显示全部楼层
37# LYXQ
传入的是变量的地址.
gz04022167 发表于 2009-11-16 15:12 | 显示全部楼层
EEPROMread()该函数应该返回的是U8吧。不错的确是溢出问题,而且是UINT32 DIR_FileSize将得不到正确数据
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部