打印

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

[复制链接]
楼主: 古道热肠
手机看帖
扫描二维码
随时随地手机跟帖
21
呵呵,大家按18楼老X的提示去找,很快能找到.
古道热肠 发表于 2009-11-15 10:39

我还是没看出来呀
高手 告诉我下,发消息我也行

使用特权

评论回复
22
急驰的蚂蚁| | 2009-11-15 21:25 | 只看该作者
假如ucCount很大时
EEPROM的存储不够,会出现问题
是这个问题吗?

使用特权

评论回复
23
ppsen| | 2009-11-15 22:47 | 只看该作者
32位,16位?

使用特权

评论回复
24
yewuyi| | 2009-11-16 08:56 | 只看该作者
那可能就是这两行中的uiTemp++造成的问题了,返回出去的都是++后的地址。
EEPROMwrite(uiTemp++,(FDB_Current.DIR_FileSize)& 0xff);
FDB_Current.DIR_FileSize += EEPROMread(uiTemp++);

使用特权

评论回复
25
t.jm| | 2009-11-16 09:17 | 只看该作者
FDB_Current.DIR_FileSize = EEPROMread(uiTemp++)<<24;
FDB_Current.DIR_FileSize += EEPROMread(uiTemp++)<<16;
这两句溢出了,要强制类型转换.

使用特权

评论回复
26
xwj| | 2009-11-16 09:17 | 只看该作者
本帖最后由 xwj 于 2009-11-16 09:47 编辑

yewuyi没找对哦,再去找!

LZ的本意就是要返回++后的地址,每次调用地址是自动增量的——这个不算BUG,BUG出在其他的低级错误上哦~

使用特权

评论回复
27
ppsen| | 2009-11-16 09:44 | 只看该作者
嘿嘿,EEPROMread返回的是uchar.........

使用特权

评论回复
28
huangqi412| | 2009-11-16 09:51 | 只看该作者
FDB_Current.DIR_FileSize += EEPROMread(uiTemp++);
*uiEEPROMAddress = uiTemp;

这个不要加加了吧,加加成下一个地址了

使用特权

评论回复
29
inter_zhou| | 2009-11-16 09:53 | 只看该作者
EEPROM写了之后是需要演示的!
EEPROM真正写的动作是在STOP命令之后,当EEPROM器件接收到STOP之后,内部的升压电路才会打开,从内部升压电路打开到烧写完成时需要时间的,上面的代码在写完一个字节后根本没有延时的动作又马上执行下一次的写,所以会导致写入部成功。

较好的做法是不用单个字节写,而是多个字节的连续写。写完之后并检测是否写入成功(POLLING)

使用特权

评论回复
30
inter_zhou| | 2009-11-16 09:56 | 只看该作者
所以楼主会有时候好像写入,然后读出都是对的,有时不读!

不同的EEPROM读写速度会有差异,就算是相同的型号,不同批次,也会有差异!

使用特权

评论回复
31
古道热肠|  楼主 | 2009-11-16 10:56 | 只看该作者
哈哈,BUG已被识破,总结一下.

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

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

29楼"inter_Zhou"提到的EEPROM函数写可能出错,应考虑批次差异性并校验,这个说法是对的,不过这个处理应该是在EEPROM的写驱动底层函数中完成.该函数目前以Void返回,较为理想的是应该返时写是否成功的结果信息给主调函数进行错误处理.

使用特权

评论回复
32
古道热肠|  楼主 | 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

使用特权

评论回复
33
古道热肠|  楼主 | 2009-11-16 11:03 | 只看该作者
文件很小时不出错,文件一长就出错.根源就在以下写法并未真正完成预期的功能
    FDB_Current.DIR_FileSize = EEPROMread(uiTemp++)<<24;
        FDB_Current.DIR_FileSize += EEPROMread(uiTemp++)<<16;

使用特权

评论回复
34
古道热肠|  楼主 | 2009-11-16 11:05 | 只看该作者
实事上,2楼网友"ejack"的直觉和猜测也是对的.

使用特权

评论回复
35
古道热肠|  楼主 | 2009-11-16 11:09 | 只看该作者
为什么
FDB_Current.DIR_FstClusLO = EEPROMread(uiTemp++)<<8;
        FDB_Current.DIR_FstClusLO += EEPROMread(uiTemp++);
不出错了,菜鸟可以试一试,Keil-C51在做这种操作时真不出错,实际上这是一个数据类型的默认转换物性的把握的问题,当然最好的写法是无法确实转换是否有效时,加上强制类型转换,保证万无一失,永不迷糊和犯低级错误.

使用特权

评论回复
36
desert_hawk| | 2009-11-16 11:20 | 只看该作者
void WriteFileInfoToEEPROM(uint *uiEEPROMAddress)
void ReadFileInfoFromEEPROM(uint *uiEEPROMAddress)
为什么参数要用指针传递呢?直接传uint型数据就行吧。
而且看了半天,貌似没找到EEPROMread和EEPROMwrite的原型。

使用特权

评论回复
37
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;
}

使用特权

评论回复
38
古道热肠|  楼主 | 2009-11-16 14:26 | 只看该作者
36# desert_hawk
主发是为了采用传址方式,将子程序中修改的结果传回主调程序.

使用特权

评论回复
39
古道热肠|  楼主 | 2009-11-16 14:34 | 只看该作者
37# LYXQ
传入的是变量的地址.

使用特权

评论回复
40
gz04022167| | 2009-11-16 15:12 | 只看该作者
EEPROMread()该函数应该返回的是U8吧。不错的确是溢出问题,而且是UINT32 DIR_FileSize将得不到正确数据

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则