打印

外围EEPROM写入错误

[复制链接]
2900|9
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
46621295|  楼主 | 2009-8-29 10:31 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
主IC通过I2C对外围EEPROM24LC515写入数据,数据量较大,有64800个字节,如果把这些数据先定义成一个rom unsigned char HZ[],就会收我另外一贴中提到的MPLAB的长度限制,出现编译错误。所以我把64800个字节定义成了两个rom unsigned char HZ1[]和rom unsigned char HZ2[],长度分别是32000字节、32800字节,这样编译就可以成功了,我写了两个程序来实现这些数据的写入,第一个程序写入HZ1,第二个程序写入HZ2,写入地址分别对应0x0000、0x7d00。
但新的问题出现了,无论先写HZ1(即地址0x0000)还是先写HZ2(即地址07d00),写完后读取检查每个字节写入内容都是正确的,但接着烧录执行写入剩下的一部分时,目标地址和目标内容都是写入成功的,但会使上次写入的内容出错,原来写入的内容被擦除了,新的数据是该次要写入的数据好像统一往后移了几个字节写入的。比如,该次要写入是0x00、0x01、0x02、0x03,那原来写入的正确的内容可能被替换成了0x01、0x02、0x03。
我考虑是不是两次写太多数据不行,就把两次写入综合到一个程序里,可问题依旧,仍然是在后边写入的数据会错移覆盖前边写入地址的内容。
请各位指点一下。谢谢!

相关帖子

沙发
一级菜鸟| | 2009-8-29 10:42 | 只看该作者
6.2 Page Write
The write control byte, word address, and the first data
byte are transmitted to the 24XX515 in the same way
as in a byte write. But instead of generating a Stop
condition, the master transmits up to 63 additional
bytes, which are temporarily stored in the on-chip page
buffer and will be written into memory after the master
has transmitted a Stop condition. After receipt of each
word, the six lower Address Pointer bits are internally
incremented by one. If the master should transmit more
than 64 bytes prior to generating the Stop condition, the
address counter will roll over and the previously
received data will be overwritten. As with the byte write
operation, once the Stop condition is received, an
internal write cycle will begin (Figure 6-2).

使用特权

评论回复
板凳
46621295|  楼主 | 2009-8-29 10:54 | 只看该作者
单页64字节我已经处理了,否则也不会一次写入32000字节时完全正确。0x0000和0x7d00都是处在每页的开头,所以我在每次写入次数达到64时就会关掉I2C,然后重新写入地址继续写入数据,就是说32000字节我是循环了500次写完。

使用特权

评论回复
地板
chunyang| | 2009-8-29 11:00 | 只看该作者
检查程序中关于写入地址方面的代码,估计在这一部分出错。

使用特权

评论回复
5
46621295|  楼主 | 2009-8-29 11:08 | 只看该作者
4# chunyang

这个可能性不大吧。因为我第二次要写入0x7d00~0xfd1f,这部分的写入是没有错误的,但是会覆盖到第一次已经写入的0x0000~0x6cff。
同样如果先写了0x7d00~0xfd1f,第二次再写入0x0000~0x6cff,那结果就是0x7d00~0xfd1f的内容被覆盖了。

使用特权

评论回复
6
46621295|  楼主 | 2009-8-29 11:52 | 只看该作者
真是奇了怪了。我每次写16000个字节,做了个两种情况实验。第一种,先从0x0000写,再从0x3e80写,没有出现覆盖,一切正常;第二种先从0x0000写,再从0x7d00写,结果0x0000处开始被覆盖。
我还做了一个实验,同一个程序内先从0x0000写16000字节,再从0x3e80写16000字节,然后从0x7d00写800个字节,结果0x0000~0x0800中的内容部分被覆盖了。
看来是一经过0x7d00就出错。谁能解惑啊?

使用特权

评论回复
7
46621295|  楼主 | 2009-8-29 13:07 | 只看该作者
真是奇了怪了。我每次写16000个字节,做了个两种情况实验。第一种,先从0x0000写,再从0x3e80写,没有出现覆盖,一切正常;第二种先从0x0000写,再从0x7d00写,结果0x0000处开始被覆盖。
我还做了一个实验,同一个程序内先从0x0000写16000字节,再从0x3e80写16000字节,然后从0x7d00写800个字节,结果0x0000~0x0800中的内容部分被覆盖了。
看来是一经过0x7d00就出错。谁能解惑啊?

使用特权

评论回复
8
46621295|  楼主 | 2009-8-29 17:21 | 只看该作者
本帖最后由 46621295 于 2009-8-29 17:23 编辑

离问题又近了一步。
24LC515的存储空间是512Kbits,即0x0000~0xffff。datasheet中有这样一句话:“Reads may be
sequential within address boundaries 0000h to 7FFFh and 8000h to FFFFh.”
我就想到把第二段数据库从0x8000开写,即ADDR_2定义成0x8000。程序如下:
EEPageWrite(0x0000,HZ1,1600);//每次写入2个汉字 20*20点阵 16位真彩色
EEPageWrite(ADDR_2,HZ2,1600);
其中EEPageWrite(515目标地址,源数据库指针,写入的字节数)。
结果发现先行写入的0x0000开始的1600个字节的数据被后写入到0x8000的1600字节数完全覆盖,即0x0000和0x8000开始的1600字节时完全相同的。
如果每次只写0x0000或者0x8000,然后烧录第二个程序再写0x8000或者0x0000,结果还是后写的内容覆盖了前写的内容,不管写入的字节数是多少。
为了验证可能是0x8000造成的问题,我把ADDR_2定义成了0x7000,即全都在24LC515的前半段空间内,再次执行程序,一切正常了。
请帮忙分析分析。难不成是我的EEPROM实际上不是512kbits,而是256kbits?!

使用特权

评论回复
9
john_light| | 2009-8-29 18:23 | 只看该作者
很简单的做法:用通用编程器读写一下该芯片,一切都清楚了。

使用特权

评论回复
10
46621295|  楼主 | 2009-8-29 21:15 | 只看该作者
问题解决了。原来是对EEPROM的地址写入错误了,24LC515的寻址的第15位是和其它14位独立的,叫做block select bit,读写的时候我忘记修改了,每次都是block select bit为0,所以只能在0~0x7FFF范围内操作。

使用特权

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

本版积分规则

56

主题

100

帖子

1

粉丝