24lc256 eeprom page write 问题

hjiongh 2009-03-17 05:40:20
大家好,

我现在用24lc256 eeprom. byte write/read 都没问题。
但是page write现在有问题,哪位大哥能帮忙一下,谢谢了

按照时序图,应该是以下7个步骤:
1) start bit
2) control byte + ACK
3) high address + ACK
4) low address + ACK
5) the first data + ACK
6) the second data and the third data, ......
7) the last data + ACK + stop bit

我现在想问一下,第6步中data byte 1 --- data byte 63 ,每个data之间需要ack吗?
我加ACK 和 不加ACK都试过,都不行,CLK在发送完第一个byte0后就没有了,不知道为什么,我并没有关闭i2c,并且因为是测试程序,所以只有i2c的代码,速度是100k

pReg[] 是对寄存器的操作,我是lpc2478的cpu

pReg[I2C_CONCLR] = (I2CONCLR_STAC|I2CONCLR_SIC|I2CONCLR_AAC);
pReg[I2C_CONSET] = I2CONSET_I2EN; //enable I2C as master
pReg[I2C_CONSET] = I2CONSET_STA; //send start condition

while(pReg[I2C_STAT] != 0x8);
pReg[I2C_DAT] = 0xA0; //set SLA+W:1010000+0
pReg[I2C_CONCLR] = (I2CONCLR_SIC|I2CONCLR_STAC); //clear SI bit to transmit SLA+W

while(pReg[I2C_STAT] != 0x18);
pReg[I2C_DAT] = highaddress; //write address to eeprom
pReg[I2C_CONCLR] = I2CONCLR_SIC; //clear SI bit to transmit address

while(pReg[I2C_STAT] != 0x28);
pReg[I2C_DAT] = lowaddress; //write address to eeprom
pReg[I2C_CONCLR] = I2CONCLR_SIC; //clear SI bit to transmit address

while(pReg[I2C_STAT] != 0x28); //stat must be 0x28
pReg[I2C_DAT] = *padr; //write data to eeprom
pReg[I2C_CONCLR] = I2CONCLR_SIC; //clear SI bit to transmit data

iLen--;
padr++;


do{
while(pReg[I2C_STAT] != 0x28); //stat must be 0x28
pReg[I2C_DAT] = *padr; //write data to eeprom
//pReg[I2C_CONCLR] = I2CONCLR_SIC; //clear SI bit to transmit data

iLen--;
padr++;

}while(iLen>0);


DelayMs(1,1); //wait to send data to eeprom

pReg[I2C_CONCLR] = I2CONCLR_SIC;
pReg[I2C_CONSET] = I2CONSET_STO; //set STO bit to stop transmit

DelayMs(1,2);

...全文
527 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
zyzhang365 2009-03-18
  • 打赏
  • 举报
回复
貌似被slave给拉住了,总线挂死了。 可能你的EEPROM有问题。
建议你连续多几个byte看有,这样也好查查是不是程序的问题。
hjiongh 2009-03-18
  • 打赏
  • 举报
回复
zyzhang365:

我用的是LPC2478

I2CONCLR_STAC 是 START flag Clear bit
I2CONCLR_SIC 是 I2C Interrupt Clear bit

所以I2CONCLR_STAC 我只要一开始发送起始位后,收到ACK后清掉即可,后面不需要考虑这个BIT了

并且while(1){i2c page write函数,little time delay;}; 我PAGE WRITE后是加了 delay time 的。

现在问题是为何“我写页启动,抓到的波形,在起始位,SLA+W, high address 0x00, low address 0x00, the first byte --- 0xaa ,都是没问题,但是the second byte --- 0xbb却没有,并且此时SCL 线常低了,也就是时钟都没有了,但是此时的确是在向I2C_DAT寄存器写数据,不应该没有时钟阿。 没有时钟,后面的数据都没有了,包括最后的停止位都不出来了,那么整个时序就破坏了,也就写失败了。 ”
j2mej2se 2009-03-18
  • 打赏
  • 举报
回复
ding
zyzhang365 2009-03-18
  • 打赏
  • 举报
回复
其实I2C的时序要求是很宽松的,如果slave设备没有准备好的时候,一般会主动把SCL拉住的。
1. 检查硬件是否有问题,不过可能性比较小,因为你可以BYTE读。
2. 程序的问题:
pReg[I2C_CONCLR] = (I2CONCLR_SIC|I2CONCLR_STAC);
pReg[I2C_CONCLR] = I2CONCLR_SIC;//这里就只有I2CONCLR这一位置位(清零??),这样别的位全为零了,不知道这是不是你需要的。不知道你的寄存器是怎么定义的,不好说。
Heaven_Redsky 2009-03-17
  • 打赏
  • 举报
回复
既然是否检查ACK都试过了 看来不是这方面的问题
不妨在while里加点点延时看一下
hjiongh 2009-03-17
  • 打赏
  • 举报
回复
我现在是只写了64个bytes ,我现在每个字节加入了ack检查,但是从scl,sda波形上看到的写一页有问题。

我现在在地址0x0000处开始写0xaa,0xbb,0xcc,0x00....0x00...0x00 , 共64个字节。 因为 A0,A1,A2都是接地,因此从0x0000开始写总归是第一页的第一个地址了。

我写页启动,抓到的波形,在起始位,SLA+W, high address 0x00, low address 0x00, the first byte --- 0xaa ,都是没问题,但是the second byte --- 0xbb却没有,并且此时SCL 线常低了,也就是时钟都没有了,但是此时的确是在向I2C_DAT寄存器写数据,不应该没有时钟阿。 没有时钟,后面的数据都没有了,包括最后的停止位都不出来了,那么整个时序就破坏了,也就写失败了。

但是问题我这是仅仅测试,未加入其他代码,在硬件初始化后,就直接while(1){i2c page write函数,little time delay;}; 了,根本就不存在关闭i2c功能的操作。
这是为什么呢/?
zyzhang365 2009-03-17
  • 打赏
  • 举报
回复
还没有仔细看代码,ACK是接收数据的一方送出的,发送的一方需要检查ACK/NACK。
PAGE mode写时,是指从开始写的地址只能连续写page个字节,否则地址回滚,这主要是内部的地址寄存器溢出造成的。

21,602

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧