在本教程中,我们将学习I2C通信协议的工作原理,并使用Arduino板和使用该协议的传感器制作一个实例。你可以观看下面的视频或阅读下面的书面教程。
I2C通信总线非常流行且广泛地由许多电子设备使用,因为它可以在许多电子设计中容易地实现,这些电子设计需要在主设备和多个从设备或甚至多个主设备之间进行通信。易于实现的事实是,在使用10位寻址时,在使用7位和多达几乎1024(1008)设备时,在多达几乎128(112)设备之间只需要两根电线。
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线向下拉到称为确认的条件。如果从站不会向下拉动SDA线路,则调用条件不确认,并意味着它没有成功接收到几种原因可能引起的先前序列。例如,从站可能很忙,可能无法理解接收的数据或命令,无法接收任何数据等。在这种情况下,主设备决定如何进行。
接下来是内部寄存器寻址。内部寄存器是从属存储器中包含各种信息或数据的位置。例如,ADX345加速度计具有唯一的设备地址并添加内部寄存器,用于X,Y和Z轴。因此,如果我们想读取X轴的数据,首先我们需要发送设备地址,然后是X轴的特定内部寄存器地址。这些地址可以从中找到传感器的数据表。
寻址后,数据传输序列开始从主人或奴隶取决于选择模式在R/W位。在数据完全发送后,传输将以停止条件结束,当SDA线从低到高而SCL线高时发生。
Arduino I2C的例子
作为一个例子,我将使用GY-80分支板,由5种不同的传感器和GY-521分支板组成,它包括3个不同的传感器。因此,我们可以使用带有I2C总线的两根电线从8个不同的传感器中获取数据。
您可以从下面的任何网站获取这些组件:
- ADXL345 3轴加速器...................................................................................................亚马逊/Banggood/aliexpress.
- 2合1:MPU6050 6轴陀螺仪和加速度计.....................亚马逊/Banggood/aliexpress.
- 3合1:GY-80 9轴磁场加速陀螺.........亚马逊
- 3合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 Breakout Board,我们只有一个地址,这是十六进制0x68。我们还可以使用Arduino I2C扫描仪草图来获取或检查地址,该草图可以从Arduino官方网站找到。所以如果我们上传并运行该草图,我们将获得I2C总线上连接设备的地址。
传感器部件号I2C地址
3轴加速度计模拟设备ADXL345 0x53数据表
3轴Gyrost Microelect必威lolronics L3G4200D 0x69数据表
3轴磁力计蜂蜜MC5883L 0x1E数据表
晴雨表+温度计博世BCP085 0x77数据表
在我们找到设备的地址之后,我们还需要找到其内部寄存器的地址,以便从中读取数据。例如,如果我们希望从GY-80 BESTOUT板的3轴加速度计传感器读取X轴的数据,我们需要找到存储X轴数据的内部寄存器地址。从传感器的数据表中,我们可以看到X轴的数据实际上存储在两个寄存器中,Datax0,具有十六进制地址0x32和Datax1,具有十六进制地址0x33。
Arduino I2C代码
现在让我们制作将获得X轴的数据的代码。因此,我们将使用必须在草图中包含的Arduino Wire库。在这里,首先我们必须定义传感器地址和我们之前找到的两个内部寄存器地址。这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); }