GD32F303 GPIO 模拟 I2C & I2C 时钟延展问题

[复制链接]
2675|2
 楼主| sxjgo 发表于 2020-4-14 19:00 | 显示全部楼层 |阅读模式
本帖最后由 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 中多了一个时钟信号,这导致了主机这边还没有开始读数据,从机这边就已经开始发数据了,这是导致数据不正确的原因。
857045e958cfaa43a9.png
269175e958d1d38124.png
2、使用 PB3 标识信号,发现是在 SCL 引脚由输入切换成输出后,信号被拉低了。这就解释了为什么多出来一个时钟信号。
gpio_init(GPIO_SCL, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ,  GPIO_Pin_SCL);
847565e95902463ee6.png

3、对代码做了一下调整,代码中读数据的过程中,去掉了最后一个 SCL 信号。数据还是不正确,分析,数据开始输送了,SDA 这边还没有开始读数据。
265925e95932278b04.png

4、应该在 SCL 被拉低之前 SDA 开始读数据,为了避免在 SDA 读数据之前信号被拉低,在切换 SCL引脚成输出模式之前,加 iic_scl_high() 这样就避免了 SCL 引脚被拉低。这样操作后,读取的数据才是正确的。
601255e958ee90d2c2.png
269245e9593cb146df.png







607305e958f3430907.png
424175e95997cb9efa.png

GD32F303_I2C_DEMO.zip

407.99 KB, 下载次数: 80

guangzi8531 发表于 2020-4-15 12:19 | 显示全部楼层
楼主,为啥不用I2C模块读写呢,全自动完成,很方便,不用延时等待。
lcpdeb 发表于 2020-4-22 21:52 | 显示全部楼层
我也是gd32f303,硬件配的i2c连使能都不行,i2c0寄存器全是0
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

5

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部