一、串行通信与并行通信
并行通信是指多个比特同时通过并行线进行传输,这种方式的传输速率较高,但会占用大量的芯片资源;
串行通信是指将数据拆分成一个个比特,按照先后次序在一根总线上进行发送,串行通信有着系统占用资源少,结构简单等优点,是主机间通信的常用方式。
串口通信(Serial Port)是串行通信的一种,属于串行通信中的异步通信。
串口通信是串行通信的一种具体实现,指的是使用串行通信接口(如RS-232、RS-485、USB串行接口等)进行的数据传输。串口通信通常涉及一个物理接口,如电脑上的COM端口或微控制器的UART(通用异步收发传输器)接口,用于将并行数据转换为串行数据,以便通过串行链路进行传输。串口通信可以是全双工(同时发送和接收数据)、半双工(发送和接收数据不能同时进行)或单工(仅在一个方向上传输数据)。
主机间通信无论采用并行还是串行方式,都无法避免一个物理现象:导线内阻不为零造成的电压衰减,传递的信号会减弱。主机之间的距离会造成高电平在接收端出现衰减现象和串扰(指不同信号之间相互干扰导致信号失真)影响。
- TTL电平: TTL(Transistor-Transistor Logic)电平是微处理器和许多数字电路中常用的信号电平标准。在TTL电平中,逻辑“1”通常表示为+5V,逻辑“0”表示为0V。随着技术的发展,也有3.3V TTL电平,逻辑“1”为3.3V。TTL电平信号可以直接连接到微控制器的GPIO引脚,但是它的驱动能力和抗干扰能力较弱,不适合长距离传输。
- RS232: RS232是最早被广泛使用的串行通信标准之一,主要用于PC和其他设备之间的短距离通信。RS232采用负逻辑电平,即逻辑“1”表示为-3V至-15V,逻辑“0”表示为+3V至+15V。这种电平标准提高了信号的抗干扰能力,适合于长距离通信(尽管实际上距离有限,一般不超过15米)。RS232接口通常需要一个电平转换芯片(如MAX232)将TTL电平转换为RS232电平,反之亦然。
- RS485和RS422: RS485和RS422是两种差分信号通信标准,相比RS232,它们提供了更好的抗噪声性能和更远的传输距离。两者的主要区别在于RS485支持半双工通信,而RS422支持全双工通信。在RS485和RS422中,信号是通过一对差分线传输的,逻辑“1”表示为两线之间的正电压差,逻辑“0”表示为负电压差,通常电压差为±2V至±6V。RS485和RS422同样需要电平转换芯片将TTL电平转换为差分电平。
strlen()计算字符数组的字符数,以"\0"为结束判断,不计算为'\0'的数组元素。
而sizeof计算数据(包括数组、变量、类型、结构体等)所占内存空间。
二、串口通信
在实际应用中,串口通信通常采用异步模式,而对于通信方式,RS-232通常支持全双工通信,而RS-485可以配置为半双工或全双工(通过适当的硬件设计),RS-422则默认支持全双工通信。
作为常用的串行通信方式,以TTL为例,串口通信在不同主机之间的数据格式为:
- 空闲时数据线为高电平;
- 发送发发送一个低电平表示起始位;
- 发送的第一个比特是最低为(最右边);
- 校验位分为奇校验,偶校验和无校验。奇偶校验时数据位1的格式为奇数或者偶数时对应的奇偶校验位为1;
- 为保证下一个字节发送前的起始位能够表现出来,校验位之后发送一个停止位1。
三、IIC
一种同步串行半双工通信总线方式。该总线允许同时连接多个设备(芯片)。每块芯片在总线上拥有特定的地址。
IIC总线在某一时刻,总线只允许有一个设备处于发送状态,所发出的数据被总线上所有的设备所接收。IIC通信协议包含有设备地址,只有发送方携带的地址与某个接收方的地址相同时,接收方才真正执行相关的指令。
IIC总线规定,设备在空闲时,两根总线都处于高电平状态。为保证这种状态,数据线SDA和时钟线SCL都要外接上拉电阻。上拉电阻的阻值一般位4.7~10K。 距离越远,上拉电阻阻值配置越小,越近阻值越大。
IIC的时序
1.起始位
由于空闲时SDA和SCL都是高电平状态,每次通信前,发送方首先发送一个“起始”信号,其实信号就是在SCL为高电平时,SDA发送一个低电平。当其它设备接收到这个其实信号后,将进行一次“总线仲裁”。意思就是设备(除发送其实信号的那个设备以外的)都将处于聆听状态。
2.数据位
IIC总线进行数据传送时,时钟线(SCL)上的信号为高电平期间,数据线(SDA)上的数据必须保持稳定。只有在时钟线(SCL)上的信号为低电平期间,数据线(SCL)上的高电平或低电平状态才允许变化。同时,SCL信号由数据启动发送的设备提供。输出到数据线(SDA)上的每个字节必须是8位。数据传送时,先传送最高位(MSB),后传送最低位(LSB),与串口通信刚好相反。
3.应答位
发送器每发送一个字节(8个bit),就在时钟脉冲 9 期间释放数据线,由接收器反馈一个应答信号。 主机SCL拉高,读取从机SDA的电平。对于反馈有效应答位ACK的要求是:接收器在第9个时钟脉冲之前的低电平期间将数据线SDA拉低,并且确保在该时钟的高电平期间为稳定的低电平。
应答分两种情况:数据线(SDA)为低电平时,规定为有效应答位(ACK,简称应答位),表示接收器已经成功地接收了该字节;数据线(SDA)为高电平时,规定为非应答位(NACK),表示接收器没有成功接收该字节。
4.停止位
当发送方发送完最后一个bit后,需要发送一个结束标志来终止整个通信过程。当时钟线SCL 为高电平时,数据线SDA 由低电平向高电平跳变(与起始信号刚好相反)。
完整时序图
IIC的设备地址
由于IIC总线的多设备设计,为了能够在通信时能够将数据发送给正确的设备,每个设备都具有一个独一无二的地址。并且IIC在每次启动通信后的第一个字节就是需要接收数据的设备的地址。这一个字节的地址中其实真正的地址只有7位,最低位事实上代表的是方向位用来表示接下来数据传输的方向。0表示主设备向从设备(write)写数据,1表示主设备向从设备(read)读数据。例如某个IIC芯片的设备地址为0xA0,当主机发送0xA0时表示要向该设备写入数据,当主机发送0xA1时,表示要从该设备读取数据。
使用IIC具体收发过程
写(发)数据操作:
- 开始信号;
- 发送 I2C 设备地址,每个 I2C 器件都有一个设备地址,通过发送具体的设备地址来决定访问哪个 I2C 器件。这是一个 8 位的数据,其中高 7 位是设备地址,最后 1 位是读写位,为1 的话表示这是一个读操作,为 0 的话表示这是一个写操作;
- I2C 器件地址后面跟着一个读写位,为 0 表示写操作,为 1 表示读操作;
- 从机发送的 ACK 应答信号;
- 重新发送开始信号;
- 发送要写写入数据的寄存器地址;
- 从机发送的 ACK 应答信号;
- 发送要写入寄存器的数据;
- 从机发送的 ACK 应答信号;
- 停止信号
读(收)数据操作分为 4 大步:
第一步是发送设备地址
第二步是发送要读取的寄存器地址
第三步重新发送设备地址
最后一步就是 I2C 从器件输出要读取的寄存器值
- 主机发送起始信号;
- 主机发送要读取的 I2C 从设备地址;
- 读写控制位,因为是向 I2C 从设备发送数据,因此是写信号;
- 从机发送的 ACK 应答信号;
- 重新发送 START 信号;
- 主机发送要读取的寄存器地址;
- 从机发送的 ACK 应答信号;
- 重新发送 START 信号;
- 重新发送要读取的 I2C 从设备地址;
- 读写控制位,这里是读信号,表示接下来是从 I2C 从设备里面读取数据;
- 从机发送的 ACK 应答信号;
- 从 I2C 器件里面读取到的数据;
- 主机发出 NO ACK 信号,表示读取完成,不需要从机再发送 ACK 信号了;
- 主机发出 STOP 信号,停止 I2C 通信。