I2C通信的实践,学习笔记

本文是我自己实际工作中,对I2C通信协议的学习,实现过程的一个总结。它记录了我从对I2C一无所知到最终能够熟练实现I2C协议的一个过程。希望能够帮到不了解I2C通信协议却正好要使用I2C的一些小伙伴们。叙述的方式还是一点一点来,尽量简单,用到哪儿再详细说哪儿。


一提到通信我们自然会想到要有两个设备,在它们之间相互传递数据的过程就叫通信。那么它们怎么传递数据呢?硬件上怎么连接?什么时候开始发送数据?什么时候结束发送?先发送高位还是低位?等等这一系列问题都要事先约定好,设备双方才能进行通信,那么这一系列事先约定好的通信规则就叫做通信协议,这里我们介绍的通信协议叫I2C通信协议

我们要将协议中规定的这些规则告诉这两个设备,以便它们在互相通信时能按照这套规则进行运转,最终达到收发数据的目的。怎么告诉它们呢?设备听不懂中国话,英国话......,但是它们能听懂C语言(当然最终会由编译器转换为机器指令),我们使用C语言编写程序,程序的功能是让这两个设备按照I2C协议规定的规则进行收/发数据,那么这个过程就叫做在这两个设备上实现I2C通信协议。为了分辨两个设备,我们把一个叫做主机(Master),另一个叫做从机(Slaver),它们的行为不太一样,所以所需要的程序也不同,一个叫做主机端的I2C协议实现,另一个叫做从机端的I2C协议实现,也就是说我们要写两套程序。注意:在实际项目中一般我们只涉及到一端。

对于通信协议的实现,其实最终的表现形式就是提供几个用于通信的接口函数,以便主程序通过调用这些接口来实现在两个设备间通信的目的。在I2C中一般应提供如下最基本的通信接口函数:

void i2c_master_init(char addr); /*设置从机的地址,即,对方的地址*/

void i2c_master_read(char* buf, int len);

void i2c_master_write(char* buf, int len);

void i2c_slaver_init(char addr); /*初始化自己的地址*/

void i2c_slaver_read(char* buf, int len);

void i2c_slaver_write(char* buf, int len);

通过函数名称我们可以知道它们的作用。例如,如果Master想要向Slaver发送数据,就可以调用i2c_master_write(...)函数,如果想从Slaver接收数据,就调用i2c_master_read(...)。I2C的主机一般无需设置地址,随着对I2C的逐步理解,我们自然会明白为什么。


讲到这里,我们要开始学习一点协议了,因为我们要让设备按照协议中规定的规则运转,那么作为开发人员首先我们自己应该懂协议,才能使用C语言编写程序来控制设备。在I2C协议中,物理上在两个设备之间由两条线连接——数据线(SDA),时钟线(SCL)。GND和VCC那是硬件上的事,和协议无关,编程时当然也不涉及,所以我们不管。

那么这两条线有什么作用呢?SDA用来传递数据——高电平代表1,低电平代表0。SCL用来控制时序——按照一定频率荡起来。

我们再来聊一聊时钟线的作用,为什么在通信过程中时钟线一定要均匀稳定的荡起来才行?只用一根数据线行不行?如果你传输的是0101010...或101010...那还是可以的,但如果传输了一串0或一串1,那么接收方怎么知道你到底传输了多少位0或1呢。如果有了时钟就可以解决这个问题了,在一个时钟周期内采样得到的数据就是对方要传输的位数据,如果一共进行了4个周期的采样,那对方就是发送了4个bit,也就是说我们可以以时钟的脉冲为单位去对数据线采样,I2C协议规定在SCL为高电平时对SDA进行采样。在I2C协议中,主机可以控制(拉低或者释放)SDA和SCL这两条线,而从机只能控制SDA线。当主机发送数据时,从机会适时地将SDA拉低或释放(拉高)。主机向从机发送数据前要先发送一个起始信号,发送完数据后发送一个结束信号。(这一段描述的有错误,之所以要有时钟,简单的说是因为计算机的相关器件需要一个0到1的上升沿,这样各个器件才会集体工作一下。就像军训时教官喊1,我们摆左臂,教官喊2,我们摆右臂......<

### 关于蓝桥杯嵌入式比赛中的I2C学习资料和技术笔记 在准备蓝桥杯嵌入式的比赛中,掌握I2C协议及其应用是非常重要的。以下是针对I2C相关内容的学习建议以及参考资料: #### 一、基础知识 I2C(Inter-Integrated Circuit)是一种用于短距离通信的串行总线协议,广泛应用于嵌入式系统中设备间的通信。其特点包括支持多主控和多从机模式,通过SDA(数据线)和SCL(时钟线)实现双向传输[^1]。 #### 二、具体应用场景 在蓝桥杯嵌入式竞赛中,通常涉及以下两个典型场景: 1. **读取24C02 EEPROM存储器** 使用I2C协议与24C02芯片交互,完成数据的写入和读取操作。这需要理解地址帧结构、起始条件、停止条件等基本概念[^2]。 2. **控制MCP4017可编程电阻** MCP4017是一款基于I2C接口的数字电位计,能够通过软件调整阻值。参赛者需熟悉如何配置寄存器并发送命令字节来改变输出电压。 #### 三、推荐学习资源 1. **博客文章** - @maosql 提供了一系列有关蓝桥杯嵌入式比赛的技术分享,其中包含了对常见硬件模块的操作指南及调试经验总结。 - 文章链接:视频教程 2. **官方文档或开源项目** - 参考 `iic-hal.c` 和 `iic-hal.h` 文件作为驱动开发的基础框架,在实际工程项目中可根据需求对其进行适配修改[^3]。 - 将上述源码迁移到 BSP (Board Support Package) 目录下,并遵循团队内部统一命名规范以便维护管理。 3. **实践案例分析** 结合理论知识动手搭建实验平台验证功能正确性至关重要。例如尝试编写一段简单的程序初始化 I²C 总线并与外设建立连接;或者模拟真实赛场环境测试时间效率等问题解决能力提升效果显著。 #### 四、注意事项 - 编程过程中要特别留意端口方向设置及时序参数调节以确保信号质量稳定可靠; - 防止因拉高/拉低电流过大损坏器件引脚; - 对异常情况进行充分预判处理以免影响整体性能表现。 ```c // 示例代码片段展示基础收发流程 #include "iic_hal.h" void iic_init(void){ // 初始化GPIO及相关寄存器状态... } uint8_t iic_start(uint8_t slave_addr){ // 发送启动信号并指定目标设备地址返回应答标志位 } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值