嵌入式硬件篇---IIC

news2025/5/16 23:55:01

文章目录

  • 前言
  • 1. I²C协议基础
    • 1.1 物理层特性
      • 两根信号线
        • SCL
        • SDA
        • 支持多主多从
      • 标准模式
      • 电平
    • 1.2 通信流程
      • 起始条件(Start Condition)
      • 从机地址(Slave Address)
      • 应答(ACK/NACK)
      • 数据传输:
      • 停止条件(Stop Condition)
    • 1.3 典型通信序列
      • 写数据
      • 读数据
  • 2. STM32F103RCT6的I²C硬件配置
    • 2.1 硬件连接
    • 2.2 CubeMX配置
  • 3. HAL库代码实现
    • 3.1 I²C初始化
    • 3.2 基本读写函数
      • (1) 写入1字节数据
      • (2) 读取1字节数据
      • (3) 连续读写
  • 4. 软件模拟I²C(GPIO模拟)
    • 4.1 初始化GPIO
    • 4.2 模拟时序函数
  • 5. 常见问题与调试
    • 5.1 I²C通信失败原因
      • 从机地址错误:
      • 上拉电阻未接:
      • 时序问题:
      • 硬件冲突:
    • 5.2 逻辑分析仪抓取波形
  • 6. 完整示例:读取MPU6050的WHO_AM_I寄存器
  • 总结
    • 硬件I²C
    • 软件模拟I²C
    • 调试关键


前言

I²C(Inter-Integrated Circuit)是一种同步、半双工串行通信协议,广泛用于连接微控制器与传感器、EEPROM低速外设。以下是I²C协议的详细说明及在STM32F103RCT6上的代码实现。


1. I²C协议基础

1.1 物理层特性

两根信号线

SCL

SCL(Serial Clock):时钟线,由主机控制。

SDA

SDA(Serial Data):数据线,双向传输。

支持多主多从

支持多主多从:通过地址寻址区分设备。

标准模式

  1. 100 kHz(低速)
  2. 400 kHz(快速模式)
  3. 1 MHz(高速模式,STM32F103支持最高400kHz)

电平

电平:开漏输出(需外接上拉电阻,通常4.7kΩ)。

1.2 通信流程

起始条件(Start Condition)

SCL高电平时,SDA由高→低。

从机地址(Slave Address)

7位地址 + 1位读写方向(0:写,1:读)。

应答(ACK/NACK)

每传输1字节后,接收方**拉低SDA(ACK)**表示成功。

数据传输:

主机发送数据或从机返回数据

停止条件(Stop Condition)

SCL高电平时,SDA由低→高。

1.3 典型通信序列

写数据

START → 从机地址(写) → ACK → 寄存器地址 → ACK → 数据 → ACK → STOP

读数据

START → 从机地址(写) → ACK → 寄存器地址 → ACK →
START → 从机地址(读) → ACK → 数据 → NACK → STOP

2. STM32F103RCT6的I²C硬件配置

STM32F103RCT6有2个I²C接口(I2C1、I2C2),支持主/从模式。以下以I2C1(PB6=SCL, PB7=SDA)为例:

2.1 硬件连接

I²C信号 STM32引脚
SCL PB6
SDA PB7
GND 共地
上拉电阻 4.7kΩ至3.3V

2.2 CubeMX配置

启用I2C1(模式:I2C)。
配置SCL/SDA引脚(PB6/PB7)。
设置时钟速度(如100kHz)。
启用中断(可选,用于事件处理)。

3. HAL库代码实现

3.1 I²C初始化

#include "stm32f1xx_hal.h"

I2C_HandleTypeDef hi2c1;

void MX_I2C1_Init(void) {
  hi2c1.Instance = I2C1;
  hi2c1.Init.ClockSpeed = 100000;          // 100kHz
  hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;  // 50%占空比
  hi2c1.Init.OwnAddress1 = 0;              // 主机模式无需地址
  hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  
  if (HAL_I2C_Init(&hi2c1) != HAL_OK) {
    Error_Handler();
  }
}

3.2 基本读写函数

(1) 写入1字节数据

HAL_StatusTypeDef I2C_WriteByte(uint8_t devAddr, uint8_t regAddr, uint8_t data) {
  return HAL_I2C_Mem_Write(&hi2c1, devAddr, regAddr, I2C_MEMADD_SIZE_8BIT, &data, 1, 100);
}
参数:
devAddr:从机地址(7位,左对齐,如0x68 << 1)。
regAddr:寄存器地址。
data:待写入数据。

(2) 读取1字节数据

HAL_StatusTypeDef I2C_ReadByte(uint8_t devAddr, uint8_t regAddr, uint8_t *data) {
  return HAL_I2C_Mem_Read(&hi2c1, devAddr, regAddr, I2C_MEMADD_SIZE_8BIT, data, 1, 100);
}

(3) 连续读写

// 写入多字节
HAL_I2C_Mem_Write(&hi2c1, 0x68<<1, 0x00, I2C_MEMADD_SIZE_8BIT, buffer, 4, 100);

// 读取多字节
HAL_I2C_Mem_Read(&hi2c1, 0x68<<1, 0x00, I2C_MEMADD_SIZE_8BIT, buffer, 4, 100);

4. 软件模拟I²C(GPIO模拟)

如果硬件I²C不可用,可用GPIO模拟:

4.1 初始化GPIO

void I2C_GPIO_Init() {
  GPIO_InitTypeDef GPIO_InitStruct = {0};
  // SCL=PB6, SDA=PB7
  GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD; // 开漏输出
  GPIO_InitStruct.Pull = GPIO_PULLUP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
  HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
  
  // 初始状态:SDA和SCL高电平
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_6 | GPIO_PIN_7, GPIO_PIN_SET);
}

4.2 模拟时序函数

// 起始信号
void I2C_Start() {
  SDA_HIGH();
  SCL_HIGH();
  Delay_us(5);
  SDA_LOW();  // SCL高时SDA拉低
  Delay_us(5);
  SCL_LOW();  // 准备数据传输
}

// 停止信号
void I2C_Stop() {
  SDA_LOW();
  SCL_HIGH();
  Delay_us(5);
  SDA_HIGH(); // SCL高时SDA拉高
  Delay_us(5);
}

// 发送1字节
void I2C_WriteByte(uint8_t data) {
  for (uint8_t i = 0; i < 8; i++) {
    SCL_LOW();
    if (data & 0x80) SDA_HIGH();
    else SDA_LOW();
    Delay_us(2);
    SCL_HIGH();
    Delay_us(5);
    SCL_LOW();
    data <<= 1;
  }
  // 等待ACK
  SDA_HIGH(); // 释放SDA
  SCL_HIGH();
  Delay_us(2);
  if (HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7) { // 检测ACK
    // NACK处理
  }
  SCL_LOW();
}

5. 常见问题与调试

5.1 I²C通信失败原因

从机地址错误:

确保地址正确(如MPU6050的7位地址是0x68,写入时左移1位:0x68 << 1)。

上拉电阻未接:

SDA/SCL必须接4.7kΩ上拉电阻

时序问题:

检查时钟速度是否匹配(从机是否支持400kHz?)。

硬件冲突:

确保没有多个设备同时驱动总线

5.2 逻辑分析仪抓取波形

使用Saleae或PulseView观察:

  1. 起始/停止条件是否正常?
  2. ACK/NACK是否正确?
  3. 数据线是否被意外拉低?

6. 完整示例:读取MPU6050的WHO_AM_I寄存器

uint8_t who_am_i;
if (HAL_I2C_Mem_Read(&hi2c1, 0x68<<1, 0x75, I2C_MEMADD_SIZE_8BIT, &who_am_i, 1, 100) == HAL_OK) {
  printf("MPU6050 ID: 0x%02X\n", who_am_i); // 正确应返回0x68
}

总结

硬件I²C

硬件I²C:使用HAL库的HAL_I2C_Mem_Read/Write最方便。

软件模拟I²C

软件模拟I²C:灵活但占用CPU资源。

调试关键

调试关键:检查地址、上拉电阻、逻辑分析仪波形
通过上述方法,可稳定实现STM32F103RCT6与I²C设备的通信。


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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Window下Jmeter多机压测方法

1.概述 Jmeter多机压测的原理&#xff0c;是通过单个jmeter客户端&#xff0c;控制多个远程的jmeter服务器&#xff0c;使他们同步的对服务器进行压力测试。 以此方式收集测试数据的好处在于&#xff1a; 保存测试采样数据到本地机器通过单台机器管理多个jmeter执行引擎测试…

视频图像压缩领域中 DCT 的 DC 系数和 AC 系数详解

引言 在数字图像与视频压缩领域&#xff0c;离散余弦变换&#xff08;Discrete Cosine Transform, DCT&#xff09;凭借其卓越的能量集中特性&#xff0c;成为JPEG、MPEG等国际标准的核心技术。DCT通过将空域信号映射到频域&#xff0c;分离出DC系数&#xff08;直流分量&…

能源设备数据采集

在全球可持续发展目标与环境保护理念日益深入人心的时代背景下&#xff0c;有效管理和优化能源使用已成为企业实现绿色转型、提升竞争力的关键路径。能源设备数据采集系统&#xff0c;作为能源管理的核心技术支撑&#xff0c;通过对各类能源生产设备运行数据的全面收集、深度分…

Go语言安装proto并且使用gRPC服务(2025最新WINDOWS系统)

1.protobuf简介 protobuf 即 Protocol Buffers&#xff0c;是一种轻便高效的结构化数据存储格式&#xff0c;与语言、平台无关&#xff0c;可扩展可序列化。protobuf 性能和效率大幅度优于 JSON、XML 等其他的结构化数据格式。protobuf 是以二进制方式存储的&#xff0c;占用空…

[Linux性能优化] 线程卡顿优化。Linux加入USB(HID)热插拔线程占用CPU优化。Linux中CPU使用率过高优化

文章目录 [Linux性能优化] 线程卡顿优化。0、省流版本一、问题定位&#xff1a;CPU 资源分析二、线程卡顿现场复现线程优化前图片 三、线程卡顿优化方向1.如果是轮询方式2.如果是事件驱动方式 四、修改方式线程优化后图片 [Linux性能优化] 线程卡顿优化。 0、省流版本 如果采…

Ubuntu20.04下如何源码编译Carla,使用UE4源码开跑,踩坑集合

一、简介 作为一个从事算法研究的人员,无人驾驶仿真一直是比较重要的一部分,但是现在比较常见的算法验证都是在carla这个开源仿真平台上做的,所以我有二次开发carla的需求,今天就来讲讲编译CARLA。 网上的教材很多,但还是推荐大家看官网教程:Linux build - CARLA Simul…

26考研——中央处理器_数据通路的功能和基本结构(5)

408答疑 文章目录 三、数据通路的功能和基本结构数据通路的功能数据通路的组成组合逻辑元件&#xff08;操作元件&#xff09;时序逻辑元件&#xff08;状态元件&#xff09; 数据通路的基本结构CPU 内部单总线方式CPU 内部多总线方式专用数据通路方式 数据通路的操作举例通用寄…

区块链大纲笔记

中心化出现的原因是由于网络的形成&#xff08;不然就孤立了&#xff0c;这显然不符合现实&#xff0c;如&#xff0c;社会&#xff0c;计算机网路&#xff09;&#xff0c;接着由于网络中结点能力一般不对等同时为了便于管理等一系列问题&#xff0c;导致中心化网络的出现。&a…

浏览器自动化:RPA 解决方案的崛起

1. 引言 在 2025 年&#xff0c;浏览器自动化已成为企业和开发者不可或缺的工具。从网页数据抓取到自动化测试&#xff0c;这项技术不仅提高了效率&#xff0c;还推动了 Web 生态的发展。然而&#xff0c;随着浏览器指纹识别和反机器人检测的进步&#xff0c;传统的本地自动化…

手机换地方ip地址会变化吗?深入解析

在移动互联网时代&#xff0c;我们经常带着手机穿梭于不同地点&#xff0c;无论是出差旅行还是日常通勤。许多用户都好奇&#xff1a;当手机更换使用地点时&#xff0c;IP地址会随之改变吗&#xff1f;本文将深入解析手机IP地址的变化机制&#xff0c;帮助您全面了解这一常见但…

AI工具分享篇 | recraft.ai + figma 复刻技术路线图

recraft 介绍 recraft.ai 主要生成和编辑适合网站、印刷和营销的各种风格的矢量艺术、图标、3d图像和插图。其矢量化功能可将路线图转化为一个矢量图。 recraft 的注册流程非常的简单&#xff0c;邮箱注册即可&#xff0c;无需科学上网&#xff0c;3分钟就能搞定。看不懂英文…

部署安装jenkins.war(2.508)

实验目的&#xff1a;部署jenkins&#xff0c;并与gitlab关联bulid 所需软件&#xff1a;jdk-17_linux-x64_bin.tar.gz jenkins.war apache-tomcat-10.1.40.tar.gz 实验主机&#xff1a;8.10具有java环境,内存最少为4G&#xff0c;cpu双核 目录 jdk安装 …

JS手写代码篇---手写 Object.create

JS手写代码篇 在做手写题的时候&#xff0c;我们要思考两个问题 这个代码的作用是什么能够实现的效果是什么样子 1. 手写 Object.create 思路&#xff1a;创造一个对象&#xff0c;类似于Object.create()方法>将obj作为原型 // 手写 Object.create function create (ob…

spring boot Controller 和 RestController 的区别

spring boot Controller 和 RestController 的区别 5.3.1常用注解 Spring MVC控制器中常使用的注解有如下几种。 Controller Controller 标记在类上。使用Controller 标记的类表示是Spring MVC的Controller对象。分发处理器将会扫描使用了该注解的类&#xff0c;并检测其中的…

LeRobot 项目部署运行逻辑(七)—— ACT 在 Mobile ALOHA 训练与部署

全部流程为&#xff1a;硬件配置 -> 环境安装 -> 遥操作数据采集 -> 数据集可视化 -> 策略训练 -> 策略评估 在之前的笔记中已经完成了绝大部分&#xff0c;最后再记录一下最后的训练部署&#xff0c;算是最简单的部分了 目录 1 ACT 训练 2 ALOHA 部署 3 更…

高频交直流电流测量技术:射频PA与MEMS测试的简单解决方案

随着5G通信和智能传感器技术的快速发展&#xff0c;传统电流测量手段已难以满足现代电子设备的测试需求。最新一代交直流混合测量探头通过突破性的技术创新&#xff0c;正在重新定义射频功率器件和微机电系统的测试标准。 射频功率放大器测试新范式&#xff1a; 在5G基站等高…

原生微信小程序 textarea组件placeholder无法换行的问题解决办法

【问题描述】 微信小程序原生代码&#xff0c;使用文本域&#xff0c;placeholder使用\n 没有效果&#xff0c;网上找了一堆方案说使用 也没有效果 最后在一个前端大佬博客&#xff0c;找到解决办法&#xff0c;CSS设置word-wrap: break-word; white-space: pre-line; 【解决办…

网络协议分析 实验二 IP分片与IPv6

文章目录 索引及重要内容实验2 IP 高级实验实验2.1 IPv4协议分片实验实验2.2 IPV6协议实验2.3 ARP初级 索引及重要内容 实验2 IP 高级实验 实验2.1 IPv4协议分片实验 icmp的不可达报文 实验2.2 IPV6协议 实验2.3 ARP初级 arp –a 查看ARP缓存表内容 arp –s IP地址(格式&…

QT6 源(101)篇一:阅读与注释 QPlainTextEdit,其继承于QAbstractScrollArea,属性学习与测试

&#xff08;1&#xff09; &#xff08;2&#xff09; &#xff08;3&#xff09;属性学习与测试 &#xff1a; &#xff08;4&#xff09; &#xff08;5&#xff09; 谢谢

工业大数据的定义

目录 工业大数据的定义 工业大数据发展历程 工业大数据的特征 工业大数据的处理流程 工业大数据在处理上面临的挑战 工业大数据的有效处理方案 工业大数据处理相关案例 数益工联 x TDengine 中天钢铁 x TDengine 广州某企业工业互联网项目 x TDengine 格创东智 x TD…