基本信息
文件名称:Arduino 系列:Arduino Uno 系列 (基于 ATmega328P)_(10).I2C通信协议.docx
文件大小:29.77 KB
总页数:21 页
更新时间:2025-06-17
总字数:约1.22万字
文档摘要

PAGE1

PAGE1

I2C通信协议

1.I2C通信协议概述

I2C(Inter-IntegratedCircuit)通信协议是一种用于短距离通信的串行总线协议,由Philips公司在1980年代开发。I2C协议允许单片机(例如ArduinoUno)与多个外围设备进行通信,而不需要过多的引脚。I2C总线使用两根线进行通信:一根数据线(SDA)和一根时钟线(SCL)。这两根线都是双向的,可以同时发送和接收数据。

I2C协议的主要特点包括:

简单性:只需要两根线即可实现多设备通信。

多主设备:多个主设备可以共享总线,但需要解决仲裁问题。

多从设备:每个从设备都有一个唯一的地址,主设备可以通过地址选择与特定的从设备进行通信。

可扩展性:可以轻松添加新的从设备,而不会占用额外的引脚。

低速通信:标准模式下支持100kbps的通信速率,快速模式下支持400kbps的通信速率,高速模式下支持3.4Mbps的通信速率。

2.I2C总线的工作原理

I2C总线的工作原理基于主从架构。主设备发起通信并控制时钟线,从设备响应主设备的命令。以下是I2C总线的基本工作流程:

起始条件:主设备首先发送起始信号,通知总线上所有设备即将开始通信。

地址帧:主设备发送7位或10位的从设备地址,地址的最后一位是读/写位,用于指示是读取还是写入数据。

应答位:从设备在接收到正确的地址后发送一个应答位(ACK),表示准备就绪。

数据传输:主设备和从设备之间进行数据传输。每个数据字节后都有一个应答位。

停止条件:通信结束后,主设备发送停止信号,通知总线上所有设备通信结束。

3.I2C通信的硬件连接

在ArduinoUno上,I2C通信的引脚如下:

SDA:模拟引脚A4

SCL:模拟引脚A5

为了确保通信的稳定性,通常需要在SDA和SCL线上加上一个上拉电阻(4.7kΩ至10kΩ之间)。上拉电阻的作用是将总线拉高到逻辑高电平,确保总线在没有设备拉低时保持高电平。

4.I2C通信的软件库

Arduino提供了一个名为Wire的库来简化I2C通信的编程。以下是Wire库的主要函数和用法:

Wire.begin():初始化I2C通信,设置Arduino为I2C主设备。

Wire.beginTransmission(address):开始向指定地址的从设备发送数据。

Wire.write(value):发送一个字节的数据。

Wire.endTransmission():结束数据传输。

Wire.requestFrom(address,quantity):从指定地址的从设备请求数据,quantity表示请求的数据字节数。

Wire.read():读取从设备发送的数据字节。

Wire.onRequest():设置一个函数,当从设备收到主设备的请求时调用该函数。

Wire.onReceive():设置一个函数,当从设备收到主设备的数据时调用该函数。

5.I2C通信的示例

5.1读取温度传感器数据

假设我们有一个I2C温度传感器(如TMP102),并且它的I2C地址为0x48。以下是一个示例代码,展示如何通过I2C通信读取温度传感器的数据。

#includeWire.h

#defineTMP102_ADDRESS0x48//TMP102的I2C地址

voidsetup(){

Serial.begin(9600);//初始化串口通信

Wire.begin();//初始化I2C通信

}

voidloop(){

int16_ttemperature;

Wire.beginTransmission(TMP102_ADDRESS);//开始向TMP102发送数据

Wire.write(0x00);//选择温度寄存器

Wire.endTransmission();//结束数据传输

Wire.requestFrom(TMP102_ADDRESS,2);//请求2个字节的数据

if(Wire.available()==2){

uint8_tMSB=Wire.read();//读取高字节

uint8_tLSB=Wire.read();//读取低字节

temperature=(int16_t)((MSB8)|LSB);//组合两个字节