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

PAGE1

PAGE1

I2C通信

介绍

I2C(Inter-IntegratedCircuit)通信协议是一种简单的双向同步串行总线,用于连接微控制器和各种外部设备。I2C总线由两根线组成:SCL(串行时钟线)和SDA(串行数据线)。这种协议广泛应用于各种传感器、显示器、存储器等设备的通信中,因为它只需要少量的引脚,并且支持多设备通信。

在ArduinoUno中,I2C通信由内置的TWI(Two-WireInterface)模块实现。TWI模块使用两个引脚(A4和A5)来实现I2C通信。其中,A4引脚连接到SDA,A5引脚连接到SCL。

I2C通信的基本原理

I2C总线上的设备分为两类:主设备和从设备。主设备负责启动通信并生成时钟信号,从设备则响应主设备的请求。I2C通信的基本步骤如下:

启动信号:主设备拉低SDA线,然后拉低SCL线。

发送地址:主设备发送7位的从设备地址和1位的读/写位。

发送/接收数据:主设备和从设备之间交换数据,每次传输一个字节。

停止信号:主设备拉低SCL线,然后释放SDA线。

I2C数据传输

I2C协议使用8位数据传输。数据在时钟的上升沿被捕获。每一字节数据传输后,接收方需要发送一个应答位(ACK),表示数据已成功接收。如果从设备无法接收数据,它会发送一个非应答位(NACK)。

ArduinoUno上的I2C通信

ArduinoUno提供了两个库来处理I2C通信:Wire.h库用于主设备和从设备的通信,TWI.h库则提供了更底层的控制。本教程主要使用Wire.h库,因为它更简单易用。

Wire库的使用

Wire.h库提供了以下主要函数:

Wire.begin():初始化I2C通信,作为主设备或从设备。

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

Wire.write(value):写入一个字节的数据。

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

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

Wire.read():读取一个字节的数据。

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

Wire.onRequest(function):设置一个函数,当从设备被请求发送数据时调用。

示例:主设备与从设备通信

主设备代码

下面是一个主设备代码示例,该代码向一个从设备发送数据并读取响应。

#includeWire.h

//从设备地址

#defineSLAVE_ADDRESS0x04

voidsetup(){

//初始化I2C通信

Wire.begin();

//初始化串口通信,用于调试

Serial.begin(9600);

Serial.println(I2CMasterInitialized);

}

voidloop(){

//向从设备发送数据

Wire.beginTransmission(SLAVE_ADDRESS);

Wire.write(H);//发送字符H

Wire.endTransmission();

//从从设备请求数据

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

if(Wire.available()){

charc=Wire.read();//读取数据

Serial.print(Receivedfromslave:);

Serial.println(c);//打印接收到的数据

}

delay(1000);//每秒执行一次

}

从设备代码

下面是一个从设备代码示例,该代码接收主设备发送的数据并发送一个响应。

#includeWire.h

//从设备地址

#defineSLAVE_ADDRESS0x04

voidsetup(){

//初始化I2C通信,设置从设备地址

Wire.begin(SLAVE_ADDRESS);

//设置接收数据的回调函数

Wire.onReceive(receiveEvent);

//设置发送数据的回调函数

Wire.onRequest(sendEvent);

//初始化串口通信,用于调试

Serial.begin(9600);

Serial.println(I2CSlaveInitialized);

}

void