news 2026/5/1 8:45:03

学习笔记——I2C(Inter-Intergrated Circuit)总线详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
学习笔记——I2C(Inter-Intergrated Circuit)总线详解

I2C(Inter-Intergrated Circuit)总线详解

一、I2C总线基本概念

1.1 I2C简介

I2C(Inter-Integrated Circuit)是由Philips公司开发的一种串行、同步、半双工的通信总线。主要特点:

  • 两根线:SDA(数据线)和SCL(时钟线)

  • 多主多从结构

  • 7位/10位地址寻址

  • 标准模式(100kbps)、快速模式(400kbps)、高速模式(3.4Mbps)

1.2 物理层特性

SDA ─────┬─────────┐ │ │ 上拉 上拉 │ │ SCL ─────┴─────────┘ 主机 从机

二、I2C通信时序

2.1 基本时序单元

// 开始信号:SCL高电平时,SDA从高变低 void i2c_start(void) { SDA_HIGH(); SCL_HIGH(); DELAY(); SDA_LOW(); DELAY(); SCL_LOW(); } // 停止信号:SCL高电平时,SDA从低变高 void i2c_stop(void) { SDA_LOW(); SCL_HIGH(); DELAY(); SDA_HIGH(); DELAY(); }

2.2 数据传输格式

开始信号 + 7位地址 + 1位R/W + ACK + 数据 + ACK + ... + 停止信号
  • 地址位:7位从机地址(0x00-0x7F)

  • R/W位:0-写,1-读

  • ACK位:每个字节后接收方应答

三、i.MX6UL的I2C控制器

3.1 寄存器概览

// I2C相关寄存器定义(从原代码提取) #define I2CR_IEN (1 << 7) // I2C使能位 #define I2CR_MSTA (1 << 5) // 主从模式选择位 #define I2CR_MTX (1 << 4) // 收发模式位 #define I2CR_TXAK (1 << 3) // 应答类型位 #define I2CR_RSTA (1 << 2) // 重复起始信号 #define I2SR_ICF (1 << 7) // 数据传输完成标志 #define I2SR_IBB (1 << 5) // 总线忙标志 #define I2SR_IAL (1 << 4) // 仲裁丢失标志 #define I2SR_IIF (1 << 1) // 中断标志 #define I2SR_RXAK (1 << 0) // 接收应答标志

3.2 初始化流程(从原代码分析)

void i2c_init(I2C_Type *base) { // 1. 引脚复用配置 IOMUXC_SetPinMux(IOMUXC_UART4_RX_DATA_I2C1_SDA, 1); // SDA IOMUXC_SetPinMux(IOMUXC_UART4_TX_DATA_I2C1_SCL, 1); // SCL // 2. 电气特性配置(上拉、驱动能力等) IOMUXC_SetPinConfig(IOMUXC_UART4_RX_DATA_I2C1_SDA, 0x10B0); IOMUXC_SetPinConfig(IOMUXC_UART4_TX_DATA_I2C1_SCL, 0x10B0); // 3. I2C控制器初始化 base->I2CR &= ~I2CR_IEN; // 先失能I2C base->IFDR = 0x15; // 设置时钟分频(384KHz) base->I2CR |= I2CR_IEN; // 使能I2C }

四、I2C写操作实现分析

4.1 完整的写数据流程

// 原代码中的i2c_write函数分析 void i2c_write(I2C_Type *base, unsigned char dev_addr, unsigned char reg_addr, unsigned char *data, unsigned int len) { int stat = 0; // 0. 清除状态标志 base->I2SR &= ~(I2SR_IAL | I2SR_IIF); // 1. 设置为发送模式 base->I2CR |= I2CR_MTX; // 2. 产生START信号(设置为主机模式) base->I2CR |= I2CR_MSTA; // 3. 发送从机地址(写模式) base->I2DR = ((dev_addr << 1) | 0); // 地址左移1位,最低位0表示写 stat = wait_i2c_iif(base); // 等待传输完成 // 4. 发送寄存器地址 base->I2DR = reg_addr; stat = wait_i2c_iif(base); // 5. 循环发送数据 for (int i = 0; i < len; i++) { base->I2DR = data[i]; stat = wait_i2c_iif(base); } // 6. 产生STOP信号 stop: base->I2CR &= ~I2CR_MSTA; // 清除主机模式,产生STOP while ((base->I2SR & I2SR_IBB) != 0) // 等待总线空闲 { // 超时处理(原代码中待完善) } delay_ms(5); // 延时确保STOP完成 }

4.2 等待中断标志函数

// 等待传输完成的中断标志 int wait_i2c_iif(I2C_Type *base) { // 等待IIF(中断标志)置位 while ((base->I2SR & I2SR_IIF) == 0){ // 建议添加超时机制 // if(timeout) return -2; } // 清除中断标志 base->I2SR &= ~I2SR_IIF; // 检查ACK(应答) if ((base->I2SR & I2SR_RXAK) != 0) { return -1; // NACK,从机未应答 } return 0; // ACK,传输成功 }

五、常见问题与调试技巧

5.1 常见问题

  1. 无应答(NACK)

    • 检查从机地址是否正确

    • 确认从机设备是否上电

    • 检查上拉电阻(通常4.7KΩ)

  2. 仲裁丢失

    • 多个主机同时尝试控制总线

    • 总线被意外干扰

  3. 时钟速率问题

    • 确保IFDR寄存器配置正确

    • 考虑总线电容导致的信号完整性

5.2 调试建议

// 添加调试信息的改进版本 void i2c_write_debug(I2C_Type *base, ...) { printf("I2C Write Start - Device: 0x%02X, Reg: 0x%02X\n", dev_addr, reg_addr); // ... 原有代码 ... if (stat == -1) { printf("ERROR: NACK received at byte %d\n", i); // 可以检查具体状态寄存器 printf("I2SR: 0x%02X\n", base->I2SR); printf("I2CR: 0x%02X\n", base->I2CR); } printf("I2C Write Complete\n"); }

六、实际应用示例

6.1 EEPROM(AT24C02)操作

// 向EEPROM写入数据 void eeprom_write_page(uint8_t dev_addr, uint8_t mem_addr, uint8_t *data, uint8_t len) { // AT24C02的器件地址:0xA0(7位地址为0x50) uint8_t eeprom_addr = 0x50; // 1010000b // 页写入(最多8字节) if (len > 8) len = 8; // 使用原代码的i2c_write函数 i2c_write(I2C1, eeprom_addr, mem_addr, data, len); // EEPROM需要写入周期时间(5ms) delay_ms(5); } // 从EEPROM读取数据 void eeprom_read_byte(uint8_t dev_addr, uint8_t mem_addr, uint8_t *data, uint8_t len) { // 需要先发送要读取的地址,然后重新开始读操作 // 这里需要扩展原代码支持读操作 }

总结

I2C总线是一种简单高效的串行通信协议,特别适合板内低速外设通信。原代码实现了基本的写操作,但还有以下可以完善的地方:

  1. 缺少读操作:需要实现完整的读功能

  2. 错误处理不足:需要添加超时、重试机制

  3. 调试支持:添加状态输出便于调试

  4. 中断支持:可以考虑使用中断方式提高效率

理解I2C协议的关键是掌握其时序:START→地址+R/W→ACK→数据→ACK→...→STOP。在实际应用中,要特别注意时序的严格性和错误处理的完备性。

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

大数据领域Spark在餐饮行业的数据分析应用

大数据领域Spark在餐饮行业的数据分析应用 关键词:大数据、Spark、餐饮行业、数据分析、应用 摘要:本文聚焦于大数据领域中Spark在餐饮行业数据分析的应用。首先介绍了研究的背景、目的、预期读者等内容,接着阐述了Spark和餐饮行业数据分析的核心概念及联系,详细讲解了相关…

作者头像 李华
网站建设 2026/5/1 8:37:28

炸裂开局!AI应用架构师引领AI驱动流程自动化新方向

炸裂开局&#xff01;AI应用架构师引领AI驱动流程自动化新方向&#xff1a;用大语言模型重构业务流程 告别僵化规则&#xff0c;拥抱认知智能&#xff1a;构建能理解、会决策、可进化的下一代自动化流程。 第一部分&#xff1a;引言与基础 标题&#xff1a; 超越RPA&#xff1a…

作者头像 李华
网站建设 2026/5/1 6:07:09

深度学习篇---图像分类任务

核心比喻&#xff1a;超级快速的“看图说话”游戏想象一下&#xff0c;你正在和一个反应极快的朋友玩一个游戏&#xff1a;游戏规则&#xff1a;你快速翻动手机相册里的照片&#xff0c;每张照片只给他看 0.1秒他必须立刻喊出照片里最主要的东西是什么只能说一个最确定的答案一…

作者头像 李华
网站建设 2026/5/1 6:02:05

Java计算机毕设之基于springboot的线上超市购物管理系统基于SpringBoot的网上购物超市商城管理系统(完整前后端代码+说明文档+LW,调试定制等)

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华
网站建设 2026/5/1 6:09:14

Java毕设选题推荐:基于Spring Boot的眼科健康管理与咨询系统设计与实现基于springboot的眼科医院管理系统的设计与实现【附源码、mysql、文档、调试+代码讲解+全bao等】

博主介绍&#xff1a;✌️码农一枚 &#xff0c;专注于大学生项目实战开发、讲解和毕业&#x1f6a2;文撰写修改等。全栈领域优质创作者&#xff0c;博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围&#xff1a;&am…

作者头像 李华