I2C EEPROM位敲击:写正常,但仅当未设置第一位时


9

我目前正在使用位撞击驱动SDA和SCL线的I2C EEPROM项目。

我的读取功能可以正常工作,但是每当我写任何以“ 1”开头的字节时,我总会读回FF。即使该字节之前已经用其他方式编程过。领先的“ 0”是完美的。这不是我的阅读习惯;正如我在示波器上看到的那样,它返回FF。

我正在寻找关于为什么会这样的建议。有什么明显的我可能会引起问题的原因吗?[我无法发布代码-公司机密... :(]

我看到的每个波形都完全符合规范。我正在去耦EEPROM。我的引体向上是2.2k,所以在规格范围内。在此原型中,我的时钟频率约为500 Hz。芯片正在向我的每个字节发送ACK,以便识别它们。但这是行不通的...

我正在使用Microchip 24LC256

一个字节的简化写入算法:

wait
SDA low
SCL low
wait
for each bit
    if bit is set:   SDA high
    if bit is unset: SDA low
    wait
    SCL high
    wait
    wait
    SCL low
    wait
wait
SDA high 
SCL high
wait
wait
check ACK status
SDA low
SCL low
wait
return ACK status

一个字节的简化读取算法:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high
    wait
    wait
    SCL low
    wait
    check and store received bit
    wait
do a NACK or ACK depending on if it is the last byte

1
@Justin-我想他是说将值0x7F写入任何地址都可以,但是将0x80写入任何地址均不起作用。
Rocketmagnet 2012年

1
这样的事情让我讨厌I2C。
Rocketmagnet 2012年

1
我有一种疯狂的预感。在您的每个位代码中,您是否无意中使用了右移操作进行符号扩展?如果您是,那么您的领先者将在进行7次移位操作后最终为您留下0xFF。
vicatcu'8

3
具有讽刺意味的是,这里是“公司机密”代码。对他们来说很有价值。这里的其他所有人共享有效的代码。使该公司的代码与其他代码区分开的原因是它无法正常工作。
gbarry 2012年

2
很难想象为什么一家公司迫切需要对一些I2C敲打代码进行保密。互联网上有很多东西。
Rocketmagnet 2012年

Answers:


4

时钟再次变低后,您正在读取数据。您必须在使时钟变高和变低之间进行操作。时钟为低电平后,允许从机更改数据线,而不是为高电平。

在此处输入图片说明

所以阅读应该是这样的:

wait
SCL low
SDA high
for each bit (8 bits)
    SCL high                      <--------
    wait
    check and store received bit  <--------
    wait
    SCL low                       <--------
    wait
    wait
do a NACK or ACK depending on if it is the last byte

那是个很好的观点; 我会解决的。但是,我的数据在我的示波器上仍然显示为全(FF),所以我的读不会成为问题... :(
Thomas O

3

最终的问题是,由于时序混乱,在某些情况下我无意中发送了STOP条件。我放弃使用示波器,退出了逻辑分析仪,并能够在15分钟内解决问题,因为它突出显示了本不应该存在的STOP。我将根据最有帮助的答案选择将赏金提供给谁。感谢您提供的所有解决方案。


很高兴您通过“验证写入时机”解决了它

3
我告诉你,这可以通过查看波形来解决。
Rocketmagnet 2012年

@Rocketmagnet我一直在看波形,但以前从未注意到过。
Thomas O

是的,但你并没有表现出我们的波形,尽管我们反复询问你。您本可以在几天前解决此问题。
Rocketmagnet 2012年

@火箭-我同意。我希望我当时有可用的相机。我使用的Tek DPO有软盘驱动器,但没有软盘。如果可以的话,我会张贴一张照片。
Thomas O

2

好了,您的示波器证明进入PIC的第一个字节是错误的,因此不是PIC读取功能。

您是否在接收端确认写入时序正常?

在以下两种模式下都失败吗?

- Byte mode sequential
- Page mode Sequential

规范显示“首先发送最高有效位(MSB)'b7'”。当b7 = 1时,整个字节读回为FF,这也是一致的。因此,要么不写而是仅在b7 = 1时擦除(故障条件),否则无论先前的内容如何,​​它都会读回为FF。由于每次写操作在写之前都是字节宽的擦除操作,因此写操作还是读错误还是第一个字节的时序不同。

建议: 在写/读期间验证PTC信号,以确保正常运行。 在此处输入图片说明

可以选择使用外部时钟来使用PTC来定时E / W周期的时间。 您是否尝试过使用此功能?

tE / W循环时间

  • 内部振荡器7ms typ
  • 外部时钟4〜10 ms min〜max

是否通过此标准?


1

听起来可能是几件事情:

  1. 公共汽车上还有什么?可能与另一个处于复位或未初始化状态的设备发生总线争用吗?
  2. 您是否正确更改了I / O引脚的方向?如果在输出情况下工作正常,则可能会无意间忘记了将引脚的方向更改为输入,并且始终会读取0xFF。当您从总线读取数据时,该引脚可以留作驱动总线的输出。
  3. 引脚本身和/或I / O线上是否有内部上拉电路?微控制器通常会提供一定范围的电阻,而不是固定值。您可能希望禁用微控制器上的上拉电阻,而仅在总线上使用分立的上拉电阻,因为您可以从分立的组件获得更精确的上拉电阻。
  4. 时钟极性-您确定要在时钟/数据之间的右边缘/相位上进行测量吗?您可能会在示波器上逐出最适合您的内容,但是如果阶段不对,则您的所有EEPROM都将看到0xFFs(并且很可能会返回相同的值,因为它可能是无效的命令/条件)。

1.仅EEPROM和MCU。2.是的,我相信我可以,因为EEPROM能够将SDA / SCL保持在低电平。3.靠近EEPROM的板上有2.2k 5%的上拉电阻。
Thomas O

对于#2,您确定EEPROM是将总线保持低电平的EEPROM吗。EEPROM在数据表中是否有任何条件可返回所有0xFFs?也请参阅我上面的编辑。
Joel B

#4。EEPROM正在“确认”我的请求,并且可以使用某些单词,但不是全部。
Thomas O

0

我在上面以评论的形式提交,但是我对答案的信心一直在我的内心深处悄然增长,因此我将其推广为答案。

我有一个疯狂的预感,那就是几乎可以肯定这是一个与某些变量的符号性有关的底层软件错误。在您的每个位代码中,您是否无意中使用了右移操作进行符号扩展?如果您是,那么您的领先者将在进行7次移位操作后最终为您留下0xFF。

史蒂文(Steven)在评论中提到了这一点,但是您是否亲眼目睹了在示波器上进行写操作的神圣性,还是仅假设它们在看起来不错的一半回读基础上起作用?如果您没有尝试查看值0xAA的写入操作,那可能是一件好事。

如果您可以提供内部循环和相关变量声明的实际代码,我们也许可以发现一个错误。


我的写作很好。我可以在示波器上看到这一点。另一个怪异现象:领先的MSB的地址还可以。只有数据会导致问题!我想尽快发布代码。
Thomas O

1
为了支持此答案:如果这是C代码,请将所有“ char”声明更改为“ unsigned char”,然后重试。
Wouter van Ooijen
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.