5种常见的总线通信协议

UART

概述

Universal Asynchronous Receiver Transmitter,即通用异步收发器。

是一种通用的串行异步通信总线。

该总线有两条数据线,可以实现全双工的发送和接收。

使用TTL电平信号,TTL(晶体管-晶体管逻辑电平)电平信号规定,+5V等价于逻辑“1”,0V等价于逻辑“0”。

数据按照二进制从低位到高位一位一位的传输。

通信双方需要使用一致的的波特率才能正常通信。

工作流程

发送端将来自控制设备(如 CPU)的并行数据转换为串行形式,接着将其串行传输到接收端,然后接收端将串行数据转换回并行数据以供接收设备使用。

uart工作流程

帧格式

uart帧格式

Arduino库

Serial库

Serial.begin()  //串口工作前的配置,包括波特率和数据格式
Serial.read()  //从接收缓存中读取一个字节的数据
Serial.write()  //向发送缓存里写入新字节
Serial.available()  //返回当前接收缓存(接收数组)内尚未读取的字节数
Serial.print()  //串口输出数据,写入字符数据到串口。将数据输出到串口。数据会以ASCII码形式输出
Serial.println()  //将数据输出到串口,并回车换行

更多内容请见:Serial库函数

RS-232

概述

UART的底层物理层协议。为解决UART的以下问题:

  1. UART只是对信号的时序进行了定义,而未定义接口的电气特性。
  2. UART的抗干扰能力差,通信距离极短。

RS-232规定逻辑“1”的电平为-5V~-15 V,逻辑“0”的电平为+5 V~+15 V,采用以下的9孔结构 rs232结构

由于处理器产生的是TTL信号,一般还需要MAX-232将TTL信号转化为RS-232信号。

RS-232只能实现点对点通信。

RS-485

RS232-C接口标准出现较早,难免有不足之处,包括;

  1. 接口的信号电平高,易损坏接口电路的芯片,又因为与TTL电平不兼容,故需要电平转换电路
  2. 传输速率较低
  3. 接口使用一根信号线和一根信号返回线构成的共地传输形式,容易产生共模干扰,所以抗噪声干扰性弱
  4. 传输距离有限

RS-485做出的改进:

  1. 传输方式为差分方式,逻辑“1”以两线间的电压差为+(26)V表示;逻辑“0”以两线间的电压差为-(26)V表示
  2. 不易损坏接口电路的芯片,且该电平与TTL电平兼容
  3. 传输介质是双绞线,半双工传输
  4. RS-485接口的最大传输距离标准值为4000英尺,实际上可达3000米
  5. 支持多点数据通信,采用终端匹配的总线型结构

RS-485总线结构

I2C

概述

IIC总线是一种串行、半双工总线,主要用于近距离,低速的芯片之间的通信

IIC总线有两根信号线,一根数据线SDA用于收发数据,一根时钟线SCL用于通信双方时钟的同步

IIC总线是一种多主机总线,连接在IIC总线上的器件分为主机和从机,主机可以发起和结束一次通信,而从机只能被主机呼叫

每个连接到IIC总线上的器件有一个7位地址

iic总线结构

主机发送起始信号后发送一个字节,该字节的前7位为地址,第8位为传输方向

  • 第8位为0表示主机发送数据给从机
  • 第8位为1表示从机发送数据给主机

帧格式

IIC总线通信时每个字节长度为8位,先传输高位后传输低位,发送器发送完1个字节后接收器必须 发送1位应答位来回应,即一个帧有9位。

工作过程

主机给从机发送数据

  1. 主机发送起始(START)信号
  2. 主机发送一个字节指明从机地址和后续字节传送方向
  3. 等待从机响应(ACK)
  4. 主设备发送数据给从机,一般发送的每个字节数据后会等待从机发送一个响应(ACK)
  5. 数据发送完毕后主机发送停止(STOP)信号终止传输

从机给主机发送数据

  1. 主机发送起始(START)信号
  2. 主机发送一个字节指明从机地址和后续字节传送方向
  3. 等待从机响应(ACK)
  4. 主设备接收来自从机的数据,一般接收的每个字节数据后会跟着向从机发送一个响应(ACK)
  5. 一般接收到最后一个数据后主机会发送一个无效响应(NACK),然主机发送停止(STOP)信号终止传输

协议详解

  1. 当SCL为高电平的时候,SDA线上由高到低的跳变被定义为起始信号
  2. 当SCL为高电平的时候,SDA线上由低到高的跳变被定义为停止信号
  3. 当SCL为高电平的时候,接收器从SDA读取一位数据,SDA线上的数据必须保持稳定
  4. 当SCL为低电平的时候,发送器向SDA写入一位数据,此时SDA上的数据允许发生改变 IIC详解

Arduino库

Wire库

Wire.begin()  //初始化iic连接,并作为主机或者从机设备加入iic总线
Wire.requestFrom()  //机向从机发送数据请求信号。使用 requestFrom() 后,从机端可以使用 onRequest() 注册一个事件用以响应主机的请求
Wire.beginTransmission()  //设定传输数据到指定地址的从机设备,随后可以使用 write() 函数发送数据
Wire.endTransmission()  //结束数据传输
Wire.available()  // 返回接收到的字节数
Wire.write()  //将要发送的数据加入发送队列
Wire.read()  // 读取一个字节的数据。在主机中,当使用 requestFrom() 函数发送数据请求信号后,需要使用 read() 函数来获取数据

更多请见:Wire库函数

SPI

简介

Serial Peripheral Interface,高速的、全双工同步的串行通信总线

采用主从方式工作,一般有一个主机和一个到多个从机

至少要4根线:MISO,MOSI,SCLK时钟线,CS片选线 SPI4根线

寻址方式

主机要与某个从机通信时,主机需要先向对应的从机的片选线上发送使能信号表示选中该设备 片选

通信过程

SPI总线在进行数据传送时,先传送高位后传送低位

数据线为高电平表示逻辑‘1’,低电平表示逻辑‘0’,一个字节传输完成后无需应答即可开始下个字节的传送

SPI总线采用同步方式工作,时钟线在上升沿或下降沿时发送器向数据线上发送数据,在紧接着的下降沿或上升沿接收器从数据线上读取数据,完成一位数据传送,八个时钟周期即可完成一个字节数据的传送。

极性和相位

SPI总线有四种不同的工作模式,取决于极性(CPOL)和相位(CPHL)这两个因素 CPOL表示SCLK空闲时的状态

  • CPOL=0,空闲时SCLK为低电平
  • CPOL=1,空闲时SCLK为高电平 CPHA表示采样时刻
  • CPHA=0,每个周期的第一个时钟沿采样,第二个边沿发送
  • CPHA=1,每个周期的第二个时钟沿采样,第一个边沿发送

Arduino库

SPI库

SPI.begin()
SPI.end()
SPI.beginTransaction()
SPI.endTransaction()
SPI.setBitOrder()
SPI.setClockDivider()
SPI.setDataMode()
SPI.transfer()

更多请见:SPI库函数


本文章使用limfx的vscode插件快速发布