本帖最后由 sxjgo 于 2020-4-14 19:10 编辑
最近基于 GD32F303 的 GPIO 口模拟I2C 信号,读取 SHT20 的温湿度数据:在调试过程中,给 SENSOR 写数据并没有问题。读数据的时候,遇到有 I2C 时钟延展的问题,当发送完读命令后,SENSOR 开始准备数据, SENSOR 在准备数据的过程中会把 SCL 信号拉低,等到 SCL 变为高的时候再开始读数据。在读取数据的过程中发现了读数不正确。在此整理一下调试的出来,小伙伴们遇到类型的问题可以参考一下,有什么问题也可以共享一下。
GPIO 口说明: PB7:I2C SDA PB6:I2C SCL PB3:作为标识信号,一般会置低,有以下两种使用场景: SCL 引脚切换为输入判断电平,但检测到高电平时PB3 置高,随后 SCL 引脚会被切换成输出模式,此时 PB3 置低。
SDA 开始读数据前 PB3 置高,SDA 读数据结束后,PB3 置低。
调试过程: 1、 刚开始把SCL 口变成输入,判断 SCL 口的电平,变成高电平后开始读数据,发现读的数据并不对,用逻辑分析仪进行了抓数据,发现MCU 读的数据,与 I2C 总线的数据不对,SCL 中多了一个时钟信号,这导致了主机这边还没有开始读数据,从机这边就已经开始发数据了,这是导致数据不正确的原因。
2、使用 PB3 标识信号,发现是在 SCL 引脚由输入切换成输出后,信号被拉低了。这就解释了为什么多出来一个时钟信号。 gpio_init(GPIO_SCL, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_Pin_SCL);
3、对代码做了一下调整,代码中读数据的过程中,去掉了最后一个 SCL 信号。数据还是不正确,分析,数据开始输送了,SDA 这边还没有开始读数据。
4、应该在 SCL 被拉低之前 SDA 开始读数据,为了避免在 SDA 读数据之前信号被拉低,在切换 SCL引脚成输出模式之前,加 iic_scl_high() 这样就避免了 SCL 引脚被拉低。这样操作后,读取的数据才是正确的。
|