STM32的IIC通信指南
基于野火霸道V2开发板IIC通信完全开发指南野火霸道V2是一款基于STM32F103ZET6芯片的经典入门级开发板板载硬件I2C外设同时支持软件模拟IIC通信可适配EEPROM、OLED、MPU6050、温湿度传感器等绝大多数IIC协议外设。IIC通信凭借双线串行、半双工、多设备挂载、引脚占用少等优势成为嵌入式开发中最常用的短距离板级通信协议之一。本文结合野火霸道V2的硬件特性系统讲解IIC通信原理、硬件配置、软件/硬件驱动实现、实操案例及问题排查既适合零基础入门学习也可作为工程开发参考。一、IIC通信核心原理1.1 总线硬件架构IIC总线仅需两根信号线即可完成通信SCL串行时钟线和SDA串行数据线配合GND共地即可实现多设备互连。其总线特性如下总线拓扑支持单主机多从机架构。野火霸道V2作为主机可同时挂载多个IIC从设备所有设备共用SCL和SDA总线通过唯一的设备地址区分通信目标。电气特性SCL和SDA引脚必须配置为开漏输出模式总线需外接上拉电阻开发板已板载上拉电路无需额外焊接。总线空闲时保持高电平通信时通过拉低电平实现数据传输。通信速率标准模式为100 kHz最通用快速模式为400 kHz。STM32F103硬件IIC最高支持400 kHz可满足绝大多数外设需求。寻址方式默认使用7位设备地址总线最多可挂载127个从设备覆盖常规嵌入式外设。1.2 核心通信时序IIC所有通信操作均基于以下四种基础时序它们是软硬件驱动开发的根本依据起始信号STARTSCL为高电平期间SDA由高电平跳变至低电平标志通信开始。停止信号STOPSCL为高电平期间SDA由低电平跳变至高电平标志通信结束。应答信号ACK数据传输后从机拉低SDA表示接收成功无应答NACK则SDA保持高电平表示通信异常。数据位传输SCL低电平期间切换SDA数据SCL高电平期间从机读取/主机写入数据。每字节传输包含8位数据加1位应答位。二、野火霸道V2 IIC硬件资源配置2.1 硬件引脚定义野火霸道V2搭载STM32F103ZET6内置I2C1和I2C2两个硬件外设板载引脚固定无需手动焊接。核心引脚分配如下IIC外设时钟引脚SCL数据引脚SDA常用场景I2C1PB6PB7默认外设适配OLED、AT24C02、MPU6050I2C2PB10PB11扩展外设多设备同时挂载场景开发板硬件已为对应引脚配置上拉电阻完全满足IIC总线电气要求外接设备时无需额外电路。2.2 硬件配置核心要点无论是使用硬件IIC还是软件模拟IIC都必须遵循以下配置规则否则会出现通信失败或数据乱码GPIO模式SCL和SDA统一配置为开漏输出OD严禁使用推挽输出以保证总线电平可被多个设备拉低。时钟使能务必开启GPIOB时钟以及对应IIC外设时钟硬件方式或仅GPIO时钟软件方式。关键参数启用应答机制、使用7位地址模式、设置标准100 kHz通信速率通用默认值。设备地址严格匹配从设备手册中的地址部分设备地址可通过硬件引脚修改需在程序中同步配置。IIC 写操作时序图主机写入从机IIC 读操作时序图主机读取从机三、两种IIC实现方式对比野火霸道V2支持硬件IIC和软件模拟IIC两种开发方式分别适配不同场景。主要区别如下实现方式优点缺点适用场景硬件IIC硬件时序生成占用CPU少传输速率高稳定性强部分芯片存在硬件bug引脚固定调试稍复杂批量工程、高速传输、多设备长期运行软件模拟引脚任意配置时序可控调试简单无硬件兼容问题占用CPU资源速率较低依赖精准延时新手入门、低速外设、引脚资源受限四、软件模拟IIC完整实现新手推荐软件模拟IIC通过GPIO电平翻转和微秒延时来模拟标准IIC时序不依赖芯片硬件外设可适配野火霸道V2的所有IO口代码通用性强适合初学者深入理解IIC通信本质。以下为基于PB6、PB7引脚的完整驱动代码。4.1 头文件配置bsp_iic.hc#ifndef __BSP_IIC_H #define __BSP_IIC_H #include stm32f10x.h // 自定义IIC引脚野火霸道V2默认PB6、PB7 #define IIC_SCL_PIN GPIO_Pin_6 #define IIC_SDA_PIN GPIO_Pin_7 #define IIC_GPIO_PORT GPIOB #define IIC_GPIO_RCC RCC_APB2Periph_GPIOB // 电平操作宏 #define IIC_SCL_HIGH GPIO_SetBits(IIC_GPIO_PORT, IIC_SCL_PIN) #define IIC_SCL_LOW GPIO_ResetBits(IIC_GPIO_PORT, IIC_SCL_PIN) #define IIC_SDA_HIGH GPIO_SetBits(IIC_GPIO_PORT, IIC_SDA_PIN) #define IIC_SDA_LOW GPIO_ResetBits(IIC_GPIO_PORT, IIC_SDA_PIN) #define IIC_SDA_READ GPIO_ReadInputDataBit(IIC_GPIO_PORT, IIC_SDA_PIN) // 函数声明 void IIC_Init(void); // IIC引脚初始化 void IIC_Start(void); // 起始信号 void IIC_Stop(void); // 停止信号 uint8_t IIC_Write_Byte(uint8_t dat); // 写入单字节 uint8_t IIC_Read_Byte(uint8_t ack); // 读取单字节ack1应答0无应答 #endif4.2 驱动函数实现bsp_iic.cc#include bsp_iic.h #include delay.h // IIC引脚初始化 void IIC_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; RCC_APB2PeriphClockCmd(IIC_GPIO_RCC, ENABLE); GPIO_InitStruct.GPIO_Pin IIC_SCL_PIN | IIC_SDA_PIN; GPIO_InitStruct.GPIO_Mode GPIO_Mode_Out_OD; GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(IIC_GPIO_PORT, GPIO_InitStruct); // 总线初始化为高电平空闲状态 IIC_SCL_HIGH; IIC_SDA_HIGH; } // 起始信号 void IIC_Start(void) { IIC_SDA_HIGH; IIC_SCL_HIGH; delay_us(4); IIC_SDA_LOW; // SCL高电平时SDA下降沿 delay_us(4); IIC_SCL_LOW; // 拉低时钟准备传输数据 } // 停止信号 void IIC_Stop(void) { IIC_SDA_LOW; IIC_SCL_HIGH; delay_us(4); IIC_SDA_HIGH; // SCL高电平时SDA上升沿 delay_us(4); } // 写入单字节返回0表示应答成功1表示无应答 uint8_t IIC_Write_Byte(uint8_t dat) { uint8_t i; for (i 0; i 8; i) { IIC_SCL_LOW; delay_us(2); if (dat 0x80) IIC_SDA_HIGH; else IIC_SDA_LOW; dat 1; delay_us(2); IIC_SCL_HIGH; delay_us(2); } // 释放SDA等待从机应答 IIC_SCL_LOW; IIC_SDA_HIGH; delay_us(2); IIC_SCL_HIGH; delay_us(2); return IIC_SDA_READ ? 1 : 0; // 1:无应答0:应答成功 } // 读取单字节ack1发送应答ack0发送无应答 uint8_t IIC_Read_Byte(uint8_t ack) { uint8_t i, dat 0; for (i 0; i 8; i) { dat 1; IIC_SCL_HIGH; delay_us(2); if (IIC_SDA_READ) dat | 0x01; IIC_SCL_LOW; delay_us(2); } // 主机发送应答/无应答 if (ack) IIC_SDA_LOW; else IIC_SDA_HIGH; delay_us(2); IIC_SCL_HIGH; delay_us(2); return dat; }五、硬件IIC标准实现工程优选硬件IIC直接调用STM32标准库外设驱动由芯片硬件自动生成通信时序CPU无需干预稳定性和传输效率远优于软件模拟适合正式项目开发。以下为野火霸道V2 I2C1的标准库配置。5.1 硬件IIC初始化c#include stm32f10x.h #include i2c.h void I2C_Hardware_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; I2C_InitTypeDef I2C_InitStruct; // 开启GPIOB和I2C1时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); // PB6(SCL)、PB7(SDA)复用开漏输出 GPIO_InitStruct.GPIO_Pin GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_OD; GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOB, GPIO_InitStruct); // I2C参数配置 I2C_InitStruct.I2C_ClockSpeed 100000; // 100 kHz I2C_InitStruct.I2C_Mode I2C_Mode_I2C; I2C_InitStruct.I2C_DutyCycle I2C_DutyCycle_2; // 占空比2:1 I2C_InitStruct.I2C_OwnAddress1 0x00; // 主机地址忽略 I2C_InitStruct.I2C_Ack I2C_Ack_Enable; // 使能应答 I2C_InitStruct.I2C_AcknowledgedAddress I2C_AcknowledgedAddress_7bit; I2C_Init(I2C1, I2C_InitStruct); I2C_Cmd(I2C1, ENABLE); }5.2 硬件IIC读写函数c// 向从设备写入单字节数据 void I2C_Write_Data(uint8_t dev_addr, uint8_t reg_addr, uint8_t data) { while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // 等待总线空闲 I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, dev_addr, I2C_Direction_Transmitter); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1, reg_addr); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_SendData(I2C1, data); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); I2C_GenerateSTOP(I2C1, ENABLE); } // 从从设备读取单字节数据 uint8_t I2C_Read_Data(uint8_t dev_addr, uint8_t reg_addr) { uint8_t data 0; while (I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY)); // 发送写地址指定寄存器 I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, dev_addr, I2C_Direction_Transmitter); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED)); I2C_SendData(I2C1, reg_addr); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED)); // 重启总线切换为读模式 I2C_GenerateSTART(I2C1, ENABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); I2C_Send7bitAddress(I2C1, dev_addr, I2C_Direction_Receiver); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED)); // 最后一字节无应答 I2C_AcknowledgeConfig(I2C1, DISABLE); while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); data I2C_ReceiveData(I2C1); I2C_GenerateSTOP(I2C1, ENABLE); I2C_AcknowledgeConfig(I2C1, ENABLE); // 恢复应答 return data; }六、实操案例AT24C02 EEPROM读写实验AT24C02是最常用的IIC存储外设支持掉电数据保存。本实验采用软件模拟IIC实现读写测试搭配串口打印结果直观验证通信功能。6.1 硬件连接AT24C02 SCL → 霸道V2 PB6AT24C02 SDA → 霸道V2 PB7AT24C02 VCC → 3.3VAT24C02 GND → 开发板GNDAT24C02默认设备地址写地址0xA0读地址0xA1。6.2 主测试代码c#include stm32f10x.h #include bsp_iic.h #include usart.h #include led.h #include delay.h int main(void) { uint8_t write_data 0x55; uint8_t read_data 0x00; LED_Init(); USART_Init(); IIC_Init(); printf(野火霸道V2 IIC通信测试启动\r\n); // 写入0x01地址 IIC_Start(); IIC_Write_Byte(0xA0); // 设备写地址 IIC_Write_Byte(0x01); // 存储地址 IIC_Write_Byte(write_data); IIC_Stop(); delay_ms(10); // 等待写入完成 // 读取0x01地址 IIC_Start(); IIC_Write_Byte(0xA0); IIC_Write_Byte(0x01); IIC_Start(); // 重启 IIC_Write_Byte(0xA1); // 设备读地址 read_data IIC_Read_Byte(0); // 无应答 IIC_Stop(); printf(写入数据0x%02X\r\n, write_data); printf(读取数据0x%02X\r\n, read_data); // 结果指示 if (read_data write_data) { LED_GREEN; printf(IIC通信测试成功\r\n); } else { LED_RED; printf(IIC通信测试失败\r\n); } while (1) {} }6.3 实验现象程序下载运行后串口助手打印写入和读取的数据一致开发板绿色LED点亮表示IIC通信正常若数据不一致或无法输出说明通信异常需检查硬件接线或代码配置。七、常见问题排查与优化方案7.1 通信失败、无数据返回检查接线确认SCL、SDA正确对应必须共地供电为3.3V禁止接入5V外设。检查引脚模式确保GPIO为开漏输出推挽输出会导致总线失效。核对设备地址区分写地址和读地址避免地址错误。7.2 数据乱码或读写不一致延时精度软件模拟时微秒延时必须准确延时过短会破坏时序。降低速率可降低通信速率至100 kHz增加抗干扰能力。应答处理严格遵循时序中的ACK/NACK规则尤其在多字节传输时。7.3 硬件IIC总线卡死STM32F1系列硬件IIC存在经典的总线卡死问题。建议方案通信前检测总线忙状态增加超时判断异常时复位IIC外设防止程序永久阻塞。八、总结与拓展野火霸道V2的IIC通信是嵌入式外设开发的基础核心。软件模拟IIC适合新手理解时序原理且引脚可灵活配置硬件IIC则更适合工程落地兼顾效率与稳定性。本文提供的驱动代码可直接适配OLED、MPU6050、AHT10等常见IIC外设只需修改设备地址和寄存器地址即可快速移植。

相关新闻

拆解RAG召回翻车核心:从Chunk切分、混合检索到Reranker落地避坑指南

拆解RAG召回翻车核心:从Chunk切分、混合检索到Reranker落地避坑指南

文章目录前言1 文档切分:第一块多米诺骨牌1.1 你看不起的切分,比换模型管用1.2 三种经典翻车现场1.3 基线怎么搭,要不要优化1.4 语义切分是不是神药2 向量化:Embedding不是银弹2.1 两个天生的盲区2.2 模型怎么选2.3 什么时候值得微…

2026/10/18 13:11:34 阅读更多 →
支持添加外部字幕的播放器推荐

支持添加外部字幕的播放器推荐

支持添加外部字幕的视频播放器非常多,包括 VLC、PotPlayer、MX Player、nPlayer 以及全新推出的网易爆米花。它们都能导入 SRT、ASS 等主流外部字幕,且可以跨平台使用。其中,网易爆米花在网盘直连、云端字幕匹配与 AI 字幕方面表现突出&#…

2026/10/12 22:28:01 阅读更多 →
图解大模型:视觉化学习Transformer与工业实践

图解大模型:视觉化学习Transformer与工业实践

1. 为什么我们需要一本全新的《图解大模型》教材?去年我在给团队做内部培训时,发现一个尴尬的现象:当我讲到Transformer架构的细节时,大部分工程师都能点头示意理解,但让他们在白板上画出完整的计算流程图时&#xff0…

2026/10/16 6:10:46 阅读更多 →

最新新闻

C语言数据结构入门:从栈队列到链表的工程实践指南

C语言数据结构入门:从栈队列到链表的工程实践指南

简介:本资源是面向C语言初学者与算法进阶学习者的数据结构与算法实践合集,聚焦线性表、栈、队列、树、图、查找、排序等核心模块的C语言原生实现,覆盖高校课程教学与工程实践双重需求。压缩包共558个文件,以80个.c源码文件为主体&…

2026/10/18 13:10:49 阅读更多 →
市容检测数据集19263张图,VOC/YOLO双格式目标检测训练避坑指南

市容检测数据集19263张图,VOC/YOLO双格式目标检测训练避坑指南

简介:面向智慧城市市容巡检与目标检测模型训练,这份资源包含街道涂鸦、垃圾堆放、故障路灯等11类市容问题的完整检测数据集。共19263张jpg图片,每张均配有Pascal VOC格式xml与YOLO格式txt标注,可直接用于YOLO系列、MMDetection等主…

2026/10/18 13:10:49 阅读更多 →
MySQL数据库课后实验指南:建库建表、索引优化与事务避坑

MySQL数据库课后实验指南:建库建表、索引优化与事务避坑

简介:数据库课后实验(崔巍编著)资源包为数据库课程配套的查询脚本合集,面向高校学生,适用于课后复习、实验参考与期末备考;资源共五个文件,全部为查询脚本,压缩包仅五千字节&#xf…

2026/10/18 13:10:49 阅读更多 →
C语言数据结构与算法入门:从链表开始的实战指南

C语言数据结构与算法入门:从链表开始的实战指南

简介:本资源是面向C语言初学者与算法进阶学习者的数据结构与算法实践合集,聚焦于核心数据结构的C语言实现与典型算法编码训练,适用于高校课程实验、自学巩固及面试刷题准备。压缩包共558个文件,以80个.c源码文件为核心&#xff0c…

2026/10/18 13:10:49 阅读更多 →
timm库实战指南:模型加载、微调与迁移学习

timm库实战指南:模型加载、微调与迁移学习

timm这个库,但凡做过图像分类、目标检测或者自监督学习的同学,多少都听说过。我最早接触它的时候,它还只是某个图像模型库的附属品,没想到几年下来,它已经成了PyTorch生态里离不开的模型弹药库。项目标题就一句话“Pyt…

2026/10/18 13:10:49 阅读更多 →
【OpenClaw】创建一个每日热点新闻 Skill:从 SKILL.md 到定时任务与网关配置

【OpenClaw】创建一个每日热点新闻 Skill:从 SKILL.md 到定时任务与网关配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 13:09:48 阅读更多 →

日新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/18 0:00:55 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/18 0:00:55 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/18 0:00:55 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 0:55:02 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/17 17:22:31 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/18 12:16:16 阅读更多 →