GD32 单片机 硬件I2C死锁解决方法

这篇具有很好参考价值的文章主要介绍了GD32 单片机 硬件I2C死锁解决方法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

死锁的复现方式

  • 在I2C恢复函数下个断点(检测到I2C多次超时之后,应该能跳转到I2C恢复函数)
  • 使用镊子,将SCL与SDA短接,很快就能看到程序停到恢复函数的断点上,此时再执行恢复函数,看能否正常走出(可在回复函数中写个死循环,只有I2C正常才跳出,检测I2C正常的办法,可以读从设备的ID)
  • void HAL_I2C_MspInit(I2C_HandleTypeDef *i2cHandle)
    {
    
      GPIO_InitTypeDef GPIO_InitStruct = {0};
      if (i2cHandle->Instance == I2C1)
      {
        /* USER CODE BEGIN I2C1_MspInit 0 */
    
        /* USER CODE END I2C1_MspInit 0 */
    
        __HAL_RCC_GPIOB_CLK_ENABLE();
    
        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
        GPIO_InitStruct.Pull = GPIO_NOPULL;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
        for (int i = 0; i < 10; ++i)
        {
          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
          HAL_Delay(1);
          HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_RESET);
          HAL_Delay(1);
        }
    
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6, GPIO_PIN_SET);
        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, GPIO_PIN_SET);
    
        HAL_Delay(1);
        i2cHandle->Instance->CR1 |= I2C_CR1_SWRST; //复位I2C控制器
        HAL_Delay(1);
        i2cHandle->Instance->CR1 = 0; //解除复位(不会自动清除)
    
        /**I2C1 GPIO Configuration    
        PB6     ------> I2C1_SCL
        PB7     ------> I2C1_SDA 
        */
        GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
        GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
        GPIO_InitStruct.Pull = GPIO_PULLUP;
        GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
        GPIO_InitStruct.Alternate = GPIO_AF4_I2C1;
        HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
        /* I2C1 clock enable */
        __HAL_RCC_I2C1_CLK_ENABLE();
        /* USER CODE BEGIN I2C1_MspInit 1 */
    
        /* USER CODE END I2C1_MspInit 1 */
      }
    }
    
    
    /* USER CODE BEGIN 1 */
    void I2C_Reset()
    {
      HAL_I2C_MspDeInit(&hi2c1);
      hi2c1.State = HAL_I2C_STATE_RESET;
      MX_I2C1_Init();
      // 硬件i2c会出现死锁,当超时次数达到一定数量,即很有可能是发生了死锁
      // 所谓死锁是指主机与从机互相等待,主机以为总线在从机手上控制,从机以为总线在主机手上控制,一直再等待对方释放总线
    }
    

    死锁的解决方法

  1. 释放IO口为GPIO,复位句柄状态标志,改为IO方式
  2. 将SDA改为高电平 
  3. 将SCK发送9个时钟  为高电平时,测试SDA是否为低电平完成死锁。

通过模拟几种情形来实际体会一下(从机对SDA的操作红色表示):

如果在地址字节第9个CLK拉高后主机复位。在模拟的第一个时钟低电平期间就可以看到SDA的释放,随后主机先拉低SDA,再模拟一个STOP结束条件。

GD32 单片机 硬件I2C死锁解决方法,嵌入式硬件,单片机

在数据字节第2个CLK拉高后主机复位,在第二个模拟的时钟低电平期间才看到SDA释放

GD32 单片机 硬件I2C死锁解决方法,嵌入式硬件,单片机


在数据字节第6个CLK拉高后主机复位,在第三个模拟的时钟低电平期间才看到SDA释放

GD32 单片机 硬件I2C死锁解决方法,嵌入式硬件,单片机

通过以上三种情况的分析,想必你已经非常清楚改如何处理了,最后附上一个程序处理流程图:

GD32 单片机 硬件I2C死锁解决方法,嵌入式硬件,单片机

SCL挂死

I2C从机主动拉低SCL线在规范中是一个合法的行为,称之为Clock Stretching(时钟扩展,我一般叫他时钟同步)。通常是主机请求数据( 收或者发)后从机需要一些时间处理,且没有多余Buffer可以接收接或者提供接下来的数据的时候从机则会拉低SCL一段时间直到有新的数据准备好。

SCL挂死(也就是前面所说一直拉低SCL)这种情况在标准I2C从器件上基本不会出现,因为只要芯片还在正常工作buffer总算有准备好的时候,自然就就释放SCL了。往往是使用用户使用MCU作为I2C从机时,程序设计上的问题导致MCU无法读取&填充buffer而导致,重点分析MCU I2C中断服务程序。文章来源地址https://www.toymoban.com/news/detail-745815.html

  1. I2C中断服务程序被意外屏蔽
  2. 中断服务程序中陷入了一些标志位查询的while(flag != xxx)死循环
  3. I2C功能系统被意外禁止

到了这里,关于GD32 单片机 硬件I2C死锁解决方法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 51单片机——模拟I2C总线与AT24C02通信

    目录 一、写在前面 二、功能描述 三、主要模块介绍 3.1 I2C总线介绍 3.2 I2C总线协议 3.2.1数据有效规定 3.2.2起始信号和停止信号  3.2.3 发送应答和接收应答 3.2.4 主机发送一个字节和接收一个字节 3.3 AT24C02介绍 3.3 字节写和随机读 四、测试文件test.c 五、现象描述 AT24C02芯片有I

    2024年02月14日
    浏览(53)
  • 嵌入式中I2C 相关的硬件问题汇总及死锁解决办法

    本文主要介绍如何解决I2C设备硬件设计上的各种问题,希望对大家有所帮助! 关于I2C协议详细的讲解,可以参考之前的推文:全面解析 I2C 通信协议 一般情况下, i2c 设备焊接没什么问题,按照设备手册一步步来,基本上就顺风顺水能够用起来。如果这么一个简单的东西,有

    2024年02月19日
    浏览(58)
  • 【单片机】UART、I2C、SPI、TTL、RS232、RS422、RS485、CAN、USB、SD卡、1-WIRE、Ethernet等常见通信方式

    在单片机开发中,UART、I2C、RS485等普遍在用,这里做一个简单的介绍 UART口指的是一种物理接口形式(硬件)。 UART是异步(指不使用时钟同步,依靠帧长进行判断),全双工(收发可以同时进行)串口总线。它比同步串口复杂很多。有两根线,一根TXD用于发送,一根RXD用于接收

    2024年02月11日
    浏览(39)
  • STM32硬件I2C通信外设

    本文主要介绍stm32自带的I2C通信外设,对比与软件模拟I2C,硬件I2C可以自动生成时序,时序的操作更加及时规范,可以实现更加高性能的IIC通信。 本文内容与I2C软件通信有诸多类似之处,I2C软件通信可见:https://blog.csdn.net/qq_53922901/article/details/136662006?spm=1001.2014.3001.5501 在8位指

    2024年04月08日
    浏览(96)
  • 【STM32】入门(七):I2C硬件控制方式

    之所以叫“I2C硬件控制方式”是与“软件控制方式”相对。I2C软件控制,就是写程序直接操作两个GPIO引脚,分别作为时钟线SCL和数据线SDA,按照I2C协议的时序要求,操作GPIO输入、输出、高电平、低电平。 听着就很复杂,好在STM32中有I2C的硬件实现,即通过简单的操作寄存器

    2023年04月08日
    浏览(47)
  • GD32F103硬件I2C0通讯

    GD32F103的I2C模块有I2C0和I2C1;本程序使用I2C0功能模块; I2C0引脚复用和重映射: 当I2C0_REMAP=0时,I2C0引脚复用功能,I2C0_SCL映射到PB6引脚,I2C0_SDA映射到PB7引脚; 当I2C0_REMAP=1时,I2C0引脚重映射,I2C0_SCL映射到PB8引脚,I2C0_SDA映射到PB9引脚; I2C1引脚只有复用引脚: I2C1_SCL映射到PB10引脚,I2C1_SDA映射到

    2024年02月13日
    浏览(54)
  • STM32 HAL FreeRTOS 硬件I2C 使用

    因为某个项目想要颜色识别,去识别球的颜色,但是又不想多来个摄像头,所以想尝试一下颜色传感器的方案。但是经过尝试,HAL库生成的 FreeRTOS 硬件 I2C 读写一直在报错。 刚好手头上有九轴陀螺仪的例程代码。最后用FreeRTOS 硬件 I2C 读取数据。 这里提到了阻塞式 HAL 函数(

    2024年02月20日
    浏览(49)
  • STM32 SHT40驱动源码(使用硬件I2C)

    目录 简介: SHT40.c: SHT40.h 测试结果:         SHT40是瑞士Sensirion公司推出的第四代温湿度传感器,内部集成加热器用于去除表面微小液滴。集成I2C接口,典型的相对湿度精度1.8%RH,典型温度精度0.2℃,运行在0-100%RH和-40-125℃的环境中。 主控:STM32H7B0VBT6 平台:STM32CubeIDE SHT4

    2024年03月19日
    浏览(72)
  • STM32F407系列硬件I2C笔记

    STM32F407系列有3个硬件I2C: I2C1:该接口位于GPIOB引脚上,包括PB6(I2C1_SCL)和PB7(I2C1_SDA)。 I2C2:该接口位于GPIOB引脚上,包括PB10(I2C2_SCL)和PB11(I2C2_SDA)。 I2C3:该接口位于GPIOA和GPIOC引脚上,包括PA8(I2C3_SCL)和PC9(I2C3_SDA)。   硬件I2C的速度比软件I2C更快,硬件I2C通常可以

    2024年02月04日
    浏览(46)
  • STM32F030硬件I2C代码及解析

    刚接触STM32的时候,第一个学习的就是I2C,当时去网上学习别人写得I2C代码,虽然能用,但是当时并不理解为什么要这么配置,特别希望有人把代码掰碎了讲讲看,今天突然想起来,就把以前写的I2C代码拿出来掰碎了捋捋,希望对新手有些帮助。 先说说STM32的I2C: ST的M3系列还

    2024年02月08日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包