I2C(inter-integrated circuit,也简称为IIC)总线类型是由飞利浦半导体公司在20世纪80年代设计出来的。如图8-7所示,使用I2C协议可以通过两根双向的总线(数据线SDA和时钟线SCL)使得LaunchPad可以连接最多128个I2C从机设备。在实现这种总线连接时,唯一需要的外部器件是每根总线上的上拉电阻。在选购I2C设备的时候,要查看其相关手册,查看其是否已经内置了上拉电阻,如果没有则需要在总线和I2C设备之间添加一个上拉电阻。
图8-7 I2C总线示意图
1)I2C主机、从机和引脚
与UART的一对一通信方式不同,I2C总线通信通常有主机(master)和从机(slave)之分。通信时,主机负责启动和终止数据发送,同时还要输出时钟信号;从机被主机寻址,并且响应主机的通信请求。
UART通信中双方需要事先约定同样的波特率才能正常进行通信,而在I2C通信中,通信的速率由主机控制的,主机通过SCL引脚输出时钟信号供总线上的所有从机使用。
同时I2C是一个半双工通信方式,即总线上的设备通过SDA引脚传输数据,数据的发送和接收由主机控制,切换进行。
I2C上的所有通信都是由主机发起的,总线上的设备都应该有各自的地址。主机可以通过这些地址向总线上的任一设备发起连接,从机响应请求并建立连接后,便可进行数据传输。
2)Wire类库成员函数
对于I2C总线的使用,Energia IDE自带了一个类库Wire。在Wire类库中定义的成员函数如下。
(1)begin()。
功能:初始化I2C连接,并作为主机或从机设备加入I2C总线。
语法:Wire.begin();
Wire.begin(address)。
参数:address,一个7位的从机地址,取值范围0~127。当没有该参数时,设备会以主机模式加入I2C总线;当填写了该参数时,设备会以从机模式加入I2C总线。
返回值:无。
(2)requestFrom()。
功能:主机向从机发送数据请求信号。使用requestFrom()后,从机端可以使用onRequest()注册一个事件用以响应主机的请求,主机可以通过available()和read()函数读取这些数据。
语法:Wire.request From(address,quantity);
Wire.request From(address,quantity,stop)。
参数:address,设备地址;
quantity,请求的字节数;
stop,boolean类型,当其值为true时将发送一个停止信息,释放I2C总线;当其值为false时,将发送一个重新开始信息,并继续保持I2C总线的有效连接。
返回值:无。
(3)begin Transmission()。
功能:设定传输数据到指定的从机设备。随后可以使用write()函数发送数据,并搭配end Transmission()函数结束数据传输。
语法:Wire.begin Transmission(address)。
参数:address,需发送的从机的7位地址。
返回值:无。
(4)end Transmission()。
功能:结束数据传输。
语法:Wire.end Transmission();
Wire.end Transmission(stop)。
参数:stop,当其值为true时将发送一个停止信息,释放I2C总线;当没有填写stop参数时,等效使用true;当其值为false时,将发送一个重新开始信息,并继续保持I2C总线的有效连接。
返回值:byte类型,表示本次传输的状态,取值如下。
0:成功。
1:数据过长,超出发送缓存区。
2:在地址发送时接收到NACK信号。
3:在数据发送时接收到NACK信号。
4:其他错误。
(5)write()。
功能:当为主机状态时,主机将要发送的数据加入发送队列;当为从机状态时,从机发送数据至发送请求的主机。
语法:Wire.write(value);
Wire.write(string);
Wire.write(data,length)。
参数:value,以单字节发送;
string,以一系列字节发送;
data,以字节形式发送数值;
length,传输的字节数。
返回值:byte类型,返回输出的字节数。
(6)available()。
功能:返回收到的字节数。在主机中,一般用于主机发送数据请求后;在从机中,一般用于数据接收事件中。
语法:Wire.available()。
参数:无。
返回值:可读取的字节数。
(7)read()。
功能:读取1字节的数据。在主机中,当使用request From()函数发送数据请求信号后,需要使用read()函数来读取数据;在从机中需要使用该函数读取主机发送来的数据。
用法:Wire.read()。
参数:无。
返回值:读到的数据。
(8)onReceive()。
功能:该函数可在从机端注册一个事件,当从机收到发送的数据时被触发。(www.xing528.com)
语法:Wrie.on Receive(handler)。
参数:handler,可被触发的事件。该事件带有一个int型参数(从主机读到的字节数)且没有返回值,如void my Handler(int numBytes)。
返回值:无。
(9)onRequest()。
功能:注册一个事件,当从机接收到主机的数据请求时即触发。
语法:Wire.on Request(handler)。
参数:handler,可被触发的事件。该事件不带参数且没有返回值,如void my Handler()。
返回值:无。
3)I2C连接方式
MSP430G2 LaunchPad使用第14(P1.6)和15(P1.7)号引脚作为I2C通信的SCL和SDA引脚。如图8-8所示,两个MSP430G2 LaunchPad可以通过将SCL、SDA引脚一一对应连接起来建立I2C连接。注意:此时绿色LED上面的跳线帽要拔掉。
如果需要有更多的I2C设备,也可以将它们连入总线中来。
4)主机写数据,从机接收数据
本实验要将两个LaunchPad分别配置为主机和从机,主机向从机传输数据,从机收到数据后再输出到串口显示。主、从机两端的I2C控制程序实现流程图如图8-9所示。
图8-8 两个LaunchPad间的I2C连接
图8-9 主机发送数据,从机接收数据
(1)主机部分。在菜单栏中打开“File”→“Examples”→“Wire”→“master_writer”,这时在编辑窗口会出现程序,如表8-4所示。
表8-4 I2C通信示例“msterwriter”程序清单
(续表)
(2)从机部分。在菜单栏中打开“File”→“Examples”→“Wire”→“slave_receiver”,这时在编辑窗口会出现程序如表8-5所示。
表8-5 I2C通信示例“slavereceiver”程序清单
使用两个LaunchPad,分别上传表8-4、表8-5中的程序,并将主、从机相连后,打开从机端的串口监视器,则可以看到如图8-10所示的输出信息,从机输出了从主机发送来的数据。
5)从机发送数据,主机接收数据
本实验仍然用两个LaunchPad分别配置为主机和从机,主机在向从机获取数据后,使用串口输出获得的数据。主、从机两端的I2C控制程序实现流程图如图8-11所示。
(1)主机部分。在菜单栏中打开“File”→“Examples”→“Wire”→“master_reader”,这时在编辑窗口会出现程序,如表8-6所示。
图8-10 从机输出从主机发来的数据
图8-11 从机发送数据,主机读取数据
表8-6 I2C通信示例“masterreader”程序清单
(2)从机部分。
在菜单栏中打开“File”→“Examples”→“Wire”→“slave_sender”,这时在编辑窗口会出现程序,如表8-7所示。
表8-7 I2C通信示例“slavesender”程序清单
(续表)
使用两个LaunchPad,分别上传程序,并将主、从机相连后,打开主机端的串口监视器,则可以看到如图8-12所示的输出信息,主机输出了从机发送来的数据。
图8-12 主机输出由从机发送来的数据
图8-13 BH1750FVI实物图
在实际应用中,一般LaunchPad作为主机,一些支持I2C协议的传感器作为从机。本次实验选用数字式环境光传感器BH1750FVI(见图8-13)作为I2C从机。
BH1750主要特征:
(1)I2C数字接口,支持速率最大为400 kbps。
(2)输出量为光照度(illuminance)。
(3)测量范围1~65 535 lx[1],分辨率最小到1 lx。
(4)低功耗(Power Down)功能。
(5)屏蔽50/60 Hz市电频率引起的光照变化干扰。
(6)支持两个I2C地址,通过ADDR引脚选择。
(7)较小的测量误差(精度误差最大值±20%)。
BH1750FVI的工作电压VCC取值范围2.4~4.5 V,I2C参考电压1.65~VCC。BH1750FVI支持单次或连续两种测量模式,每种测量模式又提供了0.5 lx、1 lx、4 lx三种分辨率供选择。分辨率越高,一次测量所需的时间就越长。在单次测量模式时,每次测量之后传感器都自动进入Power Down模式。
表8-8所示代码测试了传感器在一次测量高分辨率模式下的功能,更详细的信息请查阅产品的datasheet。
表8-8 BH1750应用示例程序清单
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。