在本教程中,我们将学习I2C通信协议的工作原理,并使用Arduino板和使用该协议的传感器制作一个实例。你可以观看下面的视频或阅读下面的书面教程。
I2C通信总线非常流行,被许多电子设备广泛使用,因为它可以很容易地在许多需要在一个主设备和多个从设备之间通信的电子设计中实现。当使用7位寻址时,最多128(112)个设备之间的通信只需要两根电线,而当使用10位寻址时,最多1024(1008)个设备之间的通信只需要两根电线。
betway
怎么可能,这么多设备之间的通信只是电线?每个设备都有预设ID或唯一的设备地址,因此主站可以选择哪些设备将是通信的。
这两条线叫做串行时钟(或SCL)和串行数据(或SDA)。SCL线是时钟信号,它同步I2C总线上设备之间的数据传输,由主设备产生。另一条是承载数据的SDA线。
两条线是“开漏”,这意味着需要将电阻连接到它们,使线路高,因为I2C总线上的设备处于高电平。电阻器的常用值为2K,在约400kbps的速度下为较高的速度,以10k为10k,速度为约100kbps。
I2C协议
数据信号以8位的序列传输。所以在一个特殊的开始条件发生后,出现了第一个8位序列,它指示了被发送的数据的奴隶的地址。在每个8位序列后面跟着一个称为确认的位。在大多数情况下,第一个确认位之后是另一个寻址序列,但这一次是为从设备的内部寄存器。紧跟在寻址序列之后的数据序列,直到数据被完全发送,它以一个特殊的停止条件结束。
让我们更仔细地看看这些事件。启动条件发生在数据线下降低而时钟线仍然高的时候。在此之后,时钟开始,每个数据位在每个时钟脉冲期间被传输。
使用最高有效位(MSB)的设备寻址序列恒星,并以最低有效位(LSB)结尾,实际上由7位组成,因为8th位用于指示是否主将写到从(逻辑低)或从它(逻辑高)读。
下一个位AKC/ NACK被从设备用来指示它是否成功地接收了先前的位序列。因此,此时主设备将SDA线的控制权交给从设备,如果从设备已经成功地接收到先前的序列,它将把SDA线拉到称为确认的条件。如果slave没有拉下SDA线,这个条件被称为not Acknowledge,这意味着它没有成功接收到之前的序列,这可能是由几种原因造成的。例如,从机可能很忙,可能不理解接收到的数据或命令,不能接收更多的数据等等。在这种情况下,主设备决定它将如何进行。
接下来是内部寄存器寻址。内部寄存器是在从机的内存中包含各种信息或数据的位置。例如,ADX345加速计有一个唯一的设备地址,并为X、Y和Z轴添加了内部寄存器地址。所以如果我们想要读取x轴的数据,首先我们需要发送设备地址,然后是x轴的特定的内部寄存器地址。这些地址可以从传感器数据表。
寻址后,数据传输序列开始从主人或奴隶取决于选择模式在R/W位。在数据完全发送后,传输将以停止条件结束,当SDA线从低到高而SCL线高时发生。
Arduino I2C的例子
作为一个例子,我将使用GY-80分接板,它包含5个不同的传感器和GY-521分接板,它包含3个不同的传感器。因此,我们可以从8个不同的传感器获得数据,只需要两根电线与I2C总线。
您可以从下面的任何网站获取这些组件:
- ADXL345 3轴加速器...................................................................................................亚马逊/Banggood/aliexpress.
- 2在1:MPU6050六轴陀螺仪和加速度计 .....................亚马逊/Banggood/aliexpress.
- 3中1:GY-80九轴磁场加速度陀螺仪.........亚马逊
- 3 in 1: GY-86 10DOF MS5611 HMC5883L MPU6050模块.........Banggood/aliexpress.
必威外围提钱披露:这些是联盟链接。作为亚马逊助理,我从合格购买中获得。
下面是我们将如何连接板。Arduino板的串行时钟引脚将连接到两个分接板的串行时钟引脚,串行数据引脚也一样,我们将用Arduino板的Gnd和5V引脚给板供电。注意这里我们没有使用上拉电阻,因为breakout board已经有。
为了与这些芯片或传感器通信,我们需要知道它们的唯一地址。我们可以从传感器的数据表上找到他们。对于GY-80分接板,我们有以下4个地址:3轴加速度计传感器的十六进制0x53, 3轴陀螺仪的十六进制0x69, 3轴磁力计的十六进制0x1E,以及气压计和温度计传感器的十六进制0x77。
对于GY-521分接板,我们只有一个地址,那是一个十六进制0x68。我们也可以通过Arduino官方网站上的Arduino I2C Scanner sketch获取或检查地址。因此,如果我们上传并运行这个草图,我们将获得I2C总线上连接设备的地址。
传感器部件号I2C地址
3轴加速度计模拟器件ADXL345 0x53数据表
3轴Gyrost Microelect必威lolronics L3G4200D 0x69数据表
3轴磁力计蜂蜜MC5883L 0x1E数据表
气压计+温度计Bosch BMP085 0x77数据表
在我们找到设备的地址之后,我们还需要找到其内部寄存器的地址,以便从中读取数据。例如,如果我们希望从GY-80 BESTOUT板的3轴加速度计传感器读取X轴的数据,我们需要找到存储X轴数据的内部寄存器地址。从传感器的数据表中,我们可以看到X轴的数据实际上存储在两个寄存器中,Datax0,具有十六进制地址0x32和Datax1,具有十六进制地址0x33。
Arduino I2C代码
现在让我们编写代码来获取X轴的数据。因此,我们将使用Arduino线库,这必须包括在草图中。首先,我们必须定义传感器地址和先前找到的两个内部寄存器地址。这Wire.begin ()功能将启动线路库,并且我们还需要启动串行通信,因为我们将使用串行监视器显示来自传感器的数据。
在环形()我们将从Wire.beginTransmission ()功能将开始传输到特定传感器,在我们的情况下3轴加速度计。然后与我们一起Wire.write()函数我们将从X轴的两个寄存器请求特定的数据。这Wire.endTransmission ()将结束传输并传输来自寄存器的数据。现在Wire.requestFrom ()函数从两个寄存器请求传输的数据或两个字节。
这wire.available()函数将返回可用于检索的字节数,如果该数字与我们所请求的字节相匹配,请在我们的情况下使用2个字节,使用wire.read()功能我们将从X轴的两个寄存器中读取字节。最后,我们将将数据打印到串行监视器中。这是数据,但请记住,这是原始数据,需要进行一些数学以获得X轴的正确值。您可以在我的下一个教程中找到更多详细信息,以便使用与Arduino板的加速度计,因为我不想过载本教程,因为它的主要目标是解释Arduino I2C通信的工作原理。
/ * * I2C通信协议如何运作 - Arduino I2C教程* *由Dejan,www.www.mfxpo.com * * / #includbet188官方网站eint adxladdress = 0x53;//设备地址,其中还包括用于选择模式的第8位,在这种情况下读取。#define x_axis_register_datax0 0x32 // Datax0内部寄存器的HexadeCima地址。#define x_axis_register_datax1 0x33 // Datax1内部寄存器的HexadeCima地址。#define power_register 0x2d //电源控制寄存器int x0,x1,x_out;void setup(){wire.begin();//发起线条库序列号.Begin(9600);延迟(100);//启用测量线.BegintRansmission(ADXLADDRESS);wire.write(power_register); // Bit D3 High for measuring enable (0000 1000) Wire.write(8); Wire.endTransmission(); } void loop() { Wire.beginTransmission(ADXLAddress); // Begin transmission to the Sensor //Ask the particular registers for data Wire.write(X_Axis_Register_DATAX0); Wire.write(X_Axis_Register_DATAX1); Wire.endTransmission(); // Ends the transmission and transmits the data from the two registers Wire.requestFrom(ADXLAddress,2); // Request the transmitted two bytes from the two registers if(Wire.available()<=2) { // X0 = Wire.read(); // Reads the data from the register X1 = Wire.read(); } Serial.print("X0= "); Serial.print(X0); Serial.print(" X1= "); Serial.println(X1); }