MSP430是德州仪器(TI)为嵌入式项目提供的功能强大的平台,它的多功能性使其能够找到许多应用程序的方法,并且该阶段仍在继续。如果您一直在关注我们的MSP430教程,那么您会发现我们已经从基础开始涵盖了有关该微控制器的各种教程。从现在开始,我们已经涵盖了基础知识,我们可以进入更有趣的内容,例如通信门户。
在庞大的嵌入式应用系统中,没有微控制器可以独自执行所有活动。在某些时候它必须与其他设备进行通信以共享信息,有许多 不同类型的通信协议 可以共享这些信息,但是最常用的是 USART,IIC,SPI和CAN。每个通信协议都有其自身的优点和缺点。现在让我们专注于 I2C部分 ,因为这是我们将在本教程中学习的内容。
什么是I2C通信协议?
IIC一词代表“内部集成电路”。在某些地方,它通常表示为I2C或I平方C或什至表示为2线接口协议(TWI),但它们的含义相同。I2C是同步通信协议,这意味着共享信息的两个设备必须共享一个公共时钟信号。它只有两根导线可以共享信息,其中一根用于塞子信号,另一根用于发送和接收数据。
I2C通信如何工作?
I2C通信最初是由Phillips引入的。如前所述,它有两条线,这两条线将跨两个设备连接。在这里,一个设备称为 主机 ,另一设备称为 从机。通讯应该并且将始终在两个 主机和一个从机之间进行。I2C通信的优势在于,一个主设备可以连接多个从设备。
完整的通信通过这两条线进行,即串行时钟(SCL)和串行数据(SDA)。
串行时钟(SCL): 与从机共享主机产生的时钟信号
串行数据(SDA): 在主机和从机之间发送数据。
在任何给定时间,只有主站才可以发起通信。由于总线中有多个从站,因此主站必须使用不同的地址引用每个从站。当被寻址时,只有具有该特定地址的从站将回复信息,而其他从站则退出。这样,我们可以使用同一条总线与多个设备进行通信。
I2C的电压电平未预定义。I2C通信非常灵活,这意味着由5v电压供电的设备可以将5v用于I2C,而3.3v设备可以将3v用于I2C通信。但是,如果两个运行在不同电压下的设备需要使用I2C通信怎么办?甲5V I2C总线不能与3.3V装置连接。在这种情况下,电压转换器用于匹配两个I2C总线之间的电压电平。
有一些构成交易的条件。传输的初始化从SDA的下降沿开始,这在下图中定义为“ START”条件,在该图中,主机将SCL设置为高电平时将SCL保持为高电平。
如下图所示,
SDA的下降沿是START条件的硬件触发。此后,同一总线上的所有设备都进入监听模式。
以相同的方式,SDA的上升沿停止传输,如上图所示,状态为“ STOP”,主机将SCL置于高电平,同时释放SDA变为高电平。因此,SDA的上升沿停止了传输。
R / W位指示后续字节的传输方向,如果为高电平,则表示从机将发送;如果为低电平,则表示主机将进行发送。
每个位在每个时钟周期发送一次,因此发送一个字节需要8个时钟周期。在发送或接收每个字节之后,将为ACK / NACK(已确认/未确认)保留第9个时钟周期。ACK位由从机或主机根据情况产生。对于ACK位,主机或从机在第9个时钟周期将SDA设置为低电平。因此,它被认为是ACK否则为NACK较低。
在哪里使用I2C通讯?
I2C通信仅用于 短距离通信。它一定程度上是可靠的,因为它具有同步时钟脉冲以使其变得智能。该协议主要用于与必须向主机发送信息的传感器或其他设备进行通信。当微控制器必须使用最少的电线与许多其他从模块通信时,这非常方便。如果您要进行远程通信,则应尝试RS232;如果要寻找更可靠的通信,则应尝试SPI协议。
MSP430中的I2C:控制AD5171数字电位器
Energia IDE是对MSP430进行编程的最简单的软件之一。与Arduino IDE相同。您可以在此处了解有关使用Energia IDE的MSP430入门的更多信息。
因此,要在Energia IDE中使用I2C,我们仅需包含 wire.h 头文件。引脚声明(SDA和SCL)位于线库中,因此我们无需在 设置 函数中进行声明。
示例示例可在IDE的“示例”菜单中找到。下面说明了其中一个示例:
本示例说明如何控制通过I2C同步串行协议进行通信的Analog Devices AD5171数字电位器。使用MSP的I2C线库,数字电位器将逐步穿越64级电阻,使LED褪色。
首先,我们将包括负责i2c通信的库,即Wire库
#包括
在 设置 函数中,我们将通过 .begin() 函数来初始化电线库。
void setup(){ Wire.begin(); }
然后初始化一个变量 val 以存储电位计的值
字节val = 0;
在 循环 功能中,我们将通过指定IC数据表中给出的设备地址,开始传输至i2c从设备(在本例中为数字电位器IC)。
void loop(){ Wire.beginTransmission(44); //传输到设备#44(0x2c)
随后,将队列字节(即要发送到IC的数据 ) 与 write() 函数一起传输 。
Wire.write(字节(0x00)); //发送指令字节Wire.write(val); //发送电位器值字节
然后通过调用 endTransmission() 传输它们。
Wire.endTransmission(); //停止传输val ++; //如果(val == 64)则递增值{//如果到达第64个位置(最大值)val = 0; //从最低值开始} delay(500); }