一个不会硬件的机器学习研究者,不是一个好的软件工程师。
引子
我最近在学习STM32,正好学习到了通讯这一步,这一部分有一些很有意思的概念,抽象总结出来做个小记。
UART
UART是一个典型的串口通信协议。串口通信是一个典型的「点对点通信系统」,也就是说,这个系统能且只能支持两个设备彼此通信。
一个UART接口通常有四根线:VCC、GND、TX和RX,分别用于供电、接地、发送数据、接收数据。通常VCC和GND在两台设备之间要保持一致,这样能为两个设备带来相同的比较电压的方法。而TX线则要接到另一台设备的RX上,RX要接到TX上。
在通信之前,两台设备之间要商议好波特率(一秒传输多少数据)、数据包格式。数据包格式通常包括停止位、数据位和校验位。
空闲状态,两根数据线都保持高电平。当传输开始时,发送端要首先发送一个低电平,作为起始位,随后发送数据,低位优先,比如发送0x01,也就是00000001,要首先发送1。最后发送停止位,停止位通常是0.5、1、1.5、2,这里带小数可能难以理解,其实就是这样,0.5就是指停止位的持续时长是数据传输一个比特的时长的一半。停止位通常是将电平拉高。
I2C
UART看起来非常不错,但是也有着一个问题。如果只有两台设备还可以,如果设备一多,那么串口数量就要成倍增加,连接线的数量也要成倍增加。这个时候,就可以应用总线进行通讯,一个代表例子就是I2C总线。
I2C总线的核心是两根线,一根时钟线(SCL),一根数据线(SDA),每个外设引出两根引脚接在这两根线上。与此同时,SDA和SCL分别通过一个上拉电阻进行上拉,每一个外设中,要将推挽输入的上拉MOS管去掉,避免短路。结构如下:

SCL控制着「何时该读取信号」,由主设备控制。比如在单片机上,SCL通常是由单片机来控制的。当SCL为高电平时读取数据。在上图中,就是由微控制器控制。
当发送数据的时候,起始位、停止位、数据位规则如下:
- 起始位:SCL高时,SDA由高变低。
- 停止位:SCL高时,SDA由低变高。
- 数据位:SCL高时,SDA对应电平。
发送的时候,发送方首先要拉低SDA的电平,当发送一个起始位之后:
- 主机要发送一个七位的地址码,高位优先,比如发送0x80,也就是10000000,要先发送1,随后跟着一位读/写标志位,写置0,读置1,之后等待应答信号。
- 发送方释放SDA,SDA被上拉到高电平,从机发送0就代表收到。
- 随后是发送指令或寄存器地址,如果发送指令,发送完就发停止位即可,如果发送寄存器地址,就要等待应答信号,随后发送要存的内容,这里是和外设相关的。
- 发送停止位。
读取的时候,则主机会在读数据和应答位的时候,将SDA释放给发送方。
至于多主多从的模式,则要考虑到总线仲裁,这一点等到CAN总线的时候一并再讲。
