valuntin 发表于 2020-6-13 14:40:46

求助!!使用STM32L073 IO口模拟IIC接口读写AT24CM01 程序不停...

求助各位大神:我用一块NUCLEO-L073RZ开发板IO口软件模拟IIC接口外接一个AT24CM01(1Mb内存)(如硬件图)。读写时出现问题如下:
1.关于上拉的问题,如果在AT24CM01接口处使用上拉电阻(使用了3K,4.7K,5.1K,8K,10K),出现程序重启现象。使用debug调试,发现程序执行到SwI2cClrSda();或SwI2cClrScl();时,时钟线和数据线无法被拉低。然后直接跳转到main函数的第一句。在IO初始化的时候使用的OD模式,IO设置为PULLUP和NOPULL效果没有差别。
uint8_t IOI2C_Start(uint8_t devAddr)
{
      // Start
      // Generate I2C START
      SwI2cSetScl();
      SwI2cSetSda();
      I2C_Delay;
      SwI2cClrSda();
      I2C_Delay;
      SwI2cClrScl();
      I2C_Delay;

      return IOI2C_TransmitByte(devAddr);
}

2.将上拉电阻去掉。使用IO内部的上拉模式,程序读AT24CM01的时候没有问题,但是在写入数据的时候,正确的逻辑我的理解是需要在收到应答后,时钟线拉高,延时后数据线拉高,数据的上升沿在时钟线的高电平期间停止。但是按照上面思路写程序,程序会发生重启情况,使用debug调试,在执行SwI2cSetSda()这一句时,程序跳转到main函数的第一句。感觉是数据线无法拉高。我看到很多文章写,时钟线低电平期间,数据可以发生变化。时钟线为高时,数据不变。但是这样怎么能产生停止位。在程序中,(如图停止位问题)把1和2语句对调。即SwI2cSetScl();和SwI2cSetSda();对调。程序不会重启,但这时候时钟的高电平不会采集到数据的上升沿,停止位不对,数据也写不进去。按照我的理解写程序,程序会发生重启,但是用示波器看时钟线和数据线,逻辑是按照我的想法走的。如图(争取的写时序)。这个时候,用读函数,把写的位置上的数据读出来,数据都变成了FF。把SwI2cSetScl();和SwI2cSetSda();对调,程序不重启,但是数据也写不进去。
uint8_t IOI2C_WriteBlock(uint8_t devAddr, uint8_t *pMemAddr, uint8_t memAddrLen, const uint8_t *pData, uint16_t len)
{

........
......
SwI2cClrScl();
      SwI2cClrSda();
      I2C_Delay;      
      SwI2cSetScl();
      I2C_Delay;
      //SwI2cClrScl();
      SwI2cSetSda();
      //IOI2C_Stop();      
}

总结一下:使用外部上拉时,程序会在发起始位的时候,从SCL或SDA拉低的语句跳转到main函数的第一句,整个程序不停的循环重启,
不使用外部上拉的时候,读函数没有问题,写函数会在停止位的最后,把SDA拉高的时候跳转到main函数的第一句,整个程序不停循环重启。
我是一个刚开始弄STM32单片机的菜鸟,需要各位帮助扫扫盲。谢谢了!!解决问题可以给点奖励。再次谢谢了。

陌路夕颜 发表于 2020-6-15 09:20:37

没看到你SDA引脚有切换输入与输出的过程,读取的时候需要将SDA引脚切换为输入,写的时候需要将SDA引脚切换为输出

xself 发表于 2020-6-15 09:34:32

外部接上拉不能拉低电平,硬件搭错,或者GPIO配置不对,不然不会出现这样情况。

wenyangzeng 发表于 2020-6-15 09:57:33

供电引线那么长,需要在EEPROM的VCC和GND之间增加1只滤波电容的。

butterflyspring 发表于 2020-6-17 11:43:27

STOP 和 START 是I2C 标准规定的,不能更改。如同二楼所说的,第9位检查ACK时要将SDA转换为输入口(在读入数据时刻也需要转换输入口)。 建议你看看EEPROM手册的时序图部分:)
页: [1]
查看完整版本: 求助!!使用STM32L073 IO口模拟IIC接口读写AT24CM01 程序不停...