解决GD32 MCU的I2C通讯遇到总线卡死的情况

PDA一直低电平,SCL一直高电平。BUSY标志一直置位。有人说STM32核支持I2C不好,这个卡死不如用软I2C模拟解决。这个恐怕不能照搬GD的例程引脚设置,开漏还是推挽输出看电路设计。

想用软I2C模拟替换硬I2C可以搜我发的资源:GD32F103 软件模拟 I2C 发送。

如果在使用GD32 MCU的IIC通信过程中遇到总线卡死的情况,可以尝试以下两种软件方法来解决:

方法一:将SDA和SCL配置为推挽输出,强制输出stop信号

在I2C主机复位后,如果主机检测到I2C总线一直为BUSY状态,并且超过设定的时间,就会锁死总线。可以通过将I2C的SCL和SDA引脚初始化为普通GPIO功能,并配置为推挽输出。首先将SCL信号拉高,然后拉高SDA信号,模拟产生一个STOP信号,最后再将引脚配置为I2C的引脚复用功能。代码示例如下:

void i2c_bus_reset() {
    GPIO_BC(GPIOB) |= GPIO_PIN_6 | GPIO_PIN_7;
    gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6|GPIO_PIN_7);
    __nop();
    __nop();
    __nop();
    __nop();
    __nop();
    GPIO_BOP(GPIOB) |= GPIO_PIN_6;
    __nop();
    __nop();
    __nop();
    __nop();
    __nop();
    GPIO_BOP(GPIOB) |= GPIO_PIN_7;
    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
}

void check_bus_status(void) {
    while(i2c_flag_get(I2C0,I2C_FLAG_I2CBSY)) {
        if(--time_out == 0){
            i2c_bus_reset();
        }
    }
}

方法二:将SCL配置为推挽输出,强制输出9个clk

在I2C主机中增加一个I2C总线恢复程序,在每次I2C主设备复位后,如果检测到SDA数据线被拉低,就控制I2C中的SCL时钟线产生9个时钟脉冲(针对8位数据的情况),让I2C从设备完成被挂起的操作,从死锁状态中恢复过来。首先将SCL引脚初始化为普通GPIO功能,并配置为推挽输出,发送连续的9个时钟脉冲。为保证后续的I2C正常通信,先将I2C模块复位,再置位,最后再将引脚配置为I2C的引脚复用功能。代码示例如下:

void i2c_bus_reset() {
    uint8_t i = 0;
    gpio_init(GPIOB, GPIO_MODE_OUT_PP, GPIO_OSPEED_50MHZ, GPIO_PIN_6); /* SCL output clock signal */
    for(i = 0; i < 10; i++){
        gpio_bit_reset(GPIOB, GPIO_PIN_6);
        delay_1us(2);
        gpio_bit_set(GPIOB, GPIO_PIN_6);
        delay_1us(2);
    }
    /* reset I2C */
    i2c_software_reset_config(I2C0, I2C_SRESET_RESET);
    i2c_software_reset_config(I2C0, I2C_SRESET_SET);
    gpio_init(GPIOB, GPIO_MODE_AF_OD, GPIO_OSPEED_50MHZ, GPIO_PIN_6 | GPIO_PIN_7);
}

void check_bus_status(void) {
    while(i2c_flag_get(I2C0,I2C_FLAG_I2CBSY)) {
        if(--time_out == 0){
            i2c_bus_reset();
        }
    }
}

以上就是解决GD32 MCU碰到IIC总线卡死的两种软件方法,可以根据具体情况选择合适的方法来解决问题。如果还有其他问题或建议,欢迎在评论区讨论。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值