news 2026/6/14 16:48:51

016、I2C驱动开发:软件模拟I2C与硬件I2C外设实现(以STM32为例)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
016、I2C驱动开发:软件模拟I2C与硬件I2C外设实现(以STM32为例)

I2C驱动开发:软件模拟I2C与硬件I2C外设实现(以STM32为例)

一、从一次诡异的EEPROM读写失败说起

去年做一款工业传感器采集板,STM32F103通过I2C挂载AT24C02存储校准参数。硬件I2C外设配置完,读出来的数据总是隔三差五出现0xFF——典型的“总线卡死”症状。示波器抓波形,SCL时钟正常,SDA在第九个时钟后莫名其妙被拉低。查了三天,最后发现是I2C外设的“时钟延展”功能没处理好,从机拉低SCL等待内部操作完成时,主机直接超时复位了。

这个坑让我意识到:硬件I2C外设不是万能的,软件模拟I2C在某些场景下反而更可靠。今天就把这两种实现方式的工程细节掰开揉碎,结合STM32实战,把那些文档里不会写的“潜规则”讲清楚。

二、软件模拟I2C:裸奔的时序控制

2.1 为什么还要用软件模拟?

硬件I2C外设虽然方便,但遇到以下场景就抓瞎:

  • 引脚复用冲突:某个I2C引脚被其他外设占用,只能用普通GPIO模拟
  • 总线频率特殊:需要非标速率(比如12kHz),硬件外设分频器算不出来
  • 从机行为怪异:某些国产传感器时序不标准,硬件外设的自动状态机处理不了

2.2 核心代码:别被网上那些“优雅”写法骗了

网上很多模拟I2C代码喜欢用delay_us()做精确延时,实际工程中千万别这么干——系统调度、中断抢占会导致时序抖动。正确的做法是用循环等待+超时保护

// 模拟I2C的SCL/SDA引脚定义(别用PB3/PB4这种JTAG复用脚,踩过坑)#defineI2C_SCL_PINGPIO_PIN_6#defineI2C_SDA_PINGPIO_PIN_7#defineI2C_GPIO_PORTGPIOB// SCL高低电平控制(别用HAL_GPIO_WritePin,直接操作ODR寄存器更快)#defineI2C_SCL_H()(I2C_GPIO_PORT->BSRR=I2C_SCL_PIN)#defineI2C_SCL_L()(I2C_GPIO_PORT->BRR=I2C_SCL_PIN)// SDA输入输出切换(这里有个坑:切换前必须确保引脚状态稳定)staticvoidI2C_SDA_OUT(void){GPIO_InitTypeDef gpio={0};gpio.Pin=I2C_SDA_PIN;gpio.Mode=GPIO_MODE_OUTPUT_OD;// 开漏输出,别用推挽!gpio.Pull=GPIO_PULLUP;gpio.Speed=GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(I2C_GPIO_PORT,&gpio);}staticvoidI2C_SDA_IN(void){GPIO_InitTypeDef gpio={0};gpio.Pin=I2C_SDA_PIN;gpio.Mode=GPIO_MODE_INPUT;// 输入模式gpio.Pull=GPIO_PULLUP;HAL_GPIO_Init(I2C_GPIO_PORT,&gpio);}

关键点:SDA输出必须用开漏模式(OD),配合外部上拉电阻。用推挽输出的话,多个设备同时驱动SDA会短路——别问我怎么知道的。

2.3 起始信号:时序容差要留够

// I2C起始信号(这里延时用循环计数,别用HAL_Delay)voidI2C_Start(void){I2C_SDA_OUT();// 确保SDA为输出模式I2C_SDA_H();// SDA高I2C_SCL_H();// SCL高delay_loop(10);// 至少4.7us(100kHz标准模式)I2C_SDA_L();// SDA拉低delay_loop(10);// 至少4usI2C_SCL_L();// SCL拉低,准备传输数据}

delay_loop(10)这个值要根据主频调整。我习惯用示波器实测:在100kHz下,每个循环大约0.5us(72MHz主频),10次就是5us,留了余量。别用精确的us延时函数,中断一来就废了。

2.4 字节发送:

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/14 16:46:59

Windows更新管理终极指南:使用WuMgr实现高效系统更新控制

Windows更新管理终极指南:使用WuMgr实现高效系统更新控制 【免费下载链接】wumgr Windows update managemetn tool for windows 10 项目地址: https://gitcode.com/gh_mirrors/wu/wumgr 在Windows 10系统中,微软取消了传统的更新管理界面&#xf…

作者头像 李华
网站建设 2026/6/14 16:45:04

MPC8272通信处理器AAL2与以太网控制器驱动开发实战解析

1. 项目概述在嵌入式网络设备开发领域,尤其是那些需要处理多种网络协议融合的网关、接入服务器或早期电信设备,通信处理器的选型与底层驱动设计是决定系统性能与稳定性的基石。今天要深入探讨的,是飞思卡尔(现恩智浦)M…

作者头像 李华
网站建设 2026/6/14 16:45:03

MPC8313E安全引擎:硬件加速IPSec与SSL/TLS的架构与驱动实践

1. MPC8313E安全引擎:嵌入式系统的硬件安全基石在嵌入式网络设备、工业控制网关或任何需要处理加密流量的场景里,CPU常常被繁重的加解密和哈希运算压得喘不过气。一个典型的例子是,当你的设备需要建立一条IPSec VPN隧道,或者处理H…

作者头像 李华
网站建设 2026/6/14 16:44:01

5分钟终极指南:BepInEx如何彻底改变你的游戏体验

5分钟终极指南:BepInEx如何彻底改变你的游戏体验 【免费下载链接】BepInEx Unity / XNA game patcher and plugin framework 项目地址: https://gitcode.com/GitHub_Trending/be/BepInEx 想为心爱的游戏添加新功能却担心技术门槛?厌倦了游戏固定玩…

作者头像 李华
网站建设 2026/6/14 16:44:00

暗黑破坏神2存档编辑器:5分钟掌握终极修改技巧

暗黑破坏神2存档编辑器:5分钟掌握终极修改技巧 【免费下载链接】d2s-editor 项目地址: https://gitcode.com/gh_mirrors/d2/d2s-editor 暗黑破坏神2存档编辑器是一款基于Vue.js构建的免费开源工具,专为暗黑2单机玩家设计。这款强大的暗黑破坏神2…

作者头像 李华
网站建设 2026/6/14 16:38:16

MPC8280 DMA控制器与时钟架构:链式传输与双PLL配置实战解析

1. MPC8280 DMA控制器:从寄存器到链式传输的深度解析在嵌入式系统,尤其是像MPC8280 PowerQUICC II这类通信处理器中,DMA(直接内存访问)控制器是性能的基石。它解放了CPU,让数据搬运这种“体力活”交给专门的…

作者头像 李华