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_SCLPB7     ------> 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结束条件。

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


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

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

SCL挂死

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

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/160319.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

美国航空公司飞行员工会遭受勒索软件攻击

导语&#xff1a;近日&#xff0c;美国航空公司的飞行员工会遭受了一次勒索软件攻击。这次攻击对于全球最大的独立飞行员工会——美国航空公司飞行员协会&#xff08;APA&#xff09;造成了一定影响。让我们一起来了解详情。 背景介绍 美国航空公司飞行员协会成立于1963年&…

项目实战之安装依赖npm install

文章目录 nvmdeasync包和node-gyp报错deasync包node-gyp报错 前言&#xff1a;有些人看着还活着其实已经凉了好一会儿了。 初拿到项目 初拿到项目肯定是先看配置 package.json的啦&#xff0c;看看都需要安装什么依赖&#xff0c;然后 npm install,OK结束 皆大欢喜。 ————…

【LeetCode】118. 杨辉三角

118. 杨辉三角 难度&#xff1a;简单 题目 给定一个非负整数 *numRows&#xff0c;*生成「杨辉三角」的前 numRows 行。 在「杨辉三角」中&#xff0c;每个数是它左上方和右上方的数的和。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]]示例…

Global-aware siamese network for change detection on remote sensing images

遥感图像中的变化检测是以有效的方式识别观测变化的最重要的技术选择之一。CD具有广泛的应用&#xff0c;如土地利用调查、城市规划、环境监测和灾害测绘。然而&#xff0c;频繁出现的类不平衡问题给变化检测应用带来了巨大的挑战。为了解决这个问题&#xff0c;我们开发了一种…

【入门Flink】- 03Flink部署

集群角色 Flik提交作业和执行任务&#xff0c;需要几个关键组件&#xff1a; 客户端(Client)&#xff1a;代码由客户端获取并做转换&#xff0c;之后提交给JobManger JobManager&#xff1a;就是Fink集群里的“管事人”&#xff0c;对作业进行中央调度管理&#xff1b;而它获…

【C语法学习】5 - fputc()函数

文章目录 1 函数原型2 参数3 返回值4 比较5 示例5.1 示例15.2 示例25.3 示例3 1 函数原型 fputc()&#xff1a;将一个字符发送至指定流stream&#xff0c;函数原型如下&#xff1a; int fputc(int c, FILE *stream);2 参数 fputc()函数有两个参数c和stream&#xff1a; 参数…

Spring Data Redis + RabbitMQ - 基于 string 实现缓存、计数功能(同步数据)

目录 一、Spring Data Redis 1.1、缓存功能 1.1.1、分析 1.1.2、案例实现 1.1.3、效果演示 1.2、计数功能&#xff08;Redis RabbitMQ&#xff09; 1.2.1、分析 1.2.2、案例实现 一、Spring Data Redis 1.1、缓存功能 1.1.1、分析 使用 redis 作为缓存&#xff0c; M…

甘特图组件DHTMLX Gantt用例 - 如何拆分任务和里程碑项目路线图

创建一致且引人注意的视觉样式是任何项目管理应用程序的重要要求&#xff0c;这就是为什么我们会在这个系列中继续探索DHTMLX Gantt图库的自定义。在本文中我们将考虑一个新的甘特图定制场景&#xff0c;DHTMLX Gantt组件如何创建一个项目路线图。 DHTMLX Gantt正式版下载 用…

系列五、映射文件xxxMapper.xml

一、概述 mapper映射文件是mybatis中最重要的部分&#xff0c;涉及到的细节也非常多。 1.1、parameterType 表示输入参数的类型。例如&#xff1a; <select id"getUserById" parameterType"integer" resultType"org.star.entity.model.UserDO&…

C语言 程序环境 编译和链接

目录 1.程序的翻译环境和执行环境 2.详解C语言程序的编译和链接 2.1翻译环镜 2.2翻译的几个阶段 2.2.1预编译 2.2.2编译 词法分析 符号汇总 2.2.3汇编 生成符号表 2.3链接 1.合并段表 2.合并符号表和重定位 2.4运行环境 1.程序的翻译环境和执行环境 在ANSI C的任…

【Linux】 ps 命令使用

ps &#xff08;英文全拼&#xff1a;process status&#xff09;命令用于显示当前进程的状态&#xff0c;类似于 windows 的任务管理器。 语法 ps [选项] ps命令 -Linux手册页 著者 ps最初由布兰科兰克斯特撰写<lankestefwi.uva.nl>。迈克尔K约翰逊<johnsonmred…

2.Spark的工作与架构原理

概述 目标&#xff1a; spark的工作原理spark数据处理通用流程rdd 什么是rddrdd 的特点 spark架构 spark架构相关进程spark架构原理 spark的工作原理 spark 的工作原理&#xff0c;如下图 图中中间部分是spark集群&#xff0c;也可以是基于 yarn 的&#xff0c;图上可以…