串口软件协议栈
- 应用层:UART、ModbusRTU、ModbusASCII、SPI、I2C
- 物理层:TTL、RS232、RS485、SPI物理链路、I2C物理链路
网络协议栈
| 应用层/表示层/会话层 | ModbusTCP | MQTT | LoRaWAN |
|---|---|---|---|
| 传输层 | TCP | TCP | 无 |
| 网络层 | IP | IP | 无 |
| 数据链路层 | CSMA/CD | CSMA/CA | ALOHA |
| 物理层 | 以太网(有线) | Wi-Fi(无线) | LoRa(无线) |
- 当报文从高层移动到链路层时,待传输报文就已经确定,并不关心物理层的介质,因此物理层其实可以有多层。
- 比如:源主机 ==(ModbusTCP)(有线)=> MQTT网关 ==(MQTT)(Wi-Fi)=> 目标主机
- 比如:源主机 ==(ModbusTCP)(有线)=> LoRaWAN网关 ==(LoRaWAN)(LoRa)=> 目标主机
软件I2C
- 协议特点:同步时序、可变的多主多从、数据高位先行、半双工
- 同步时序:时序不严格,主机什么时候操作clk都可以
- 多从:导致协议需要实现主请求和从应答
- 多主(可选):导致协议需要实现多主请求时的总线仲裁
- 可变(可选):每个机器既能做主也能做从,导致每个机器需要设置自己的从设备地址
- 半双工:由于SDA和SCL同时需要输入输出,所以采用开漏+外部弱上拉,实现线与(同时输入输出)

- scl相当于clk,sda相当于为data
- clk低电平为写总线时间,clk高电平为读总线时间
- clk只能由master控制
- master用clk来控制读/写总线时间
- data可以由master/slave控制
- 给data置1=释放总线/发送数据1,给data置0=占用总线/发送数据0
- 除了START和STOP,clk电平期间必须保持读/写data
- 硬件时序

- START/Sr状态:scl高电平 -> sda下降沿 -> scl低电平
- 低电平可写1b:(scl低电平时)写sda -> scl高电平 -> scl低电平 置高电平是为了让对方读
- 高电平可读1b:(scl低电平时)scl高电平 -> 读sda -> scl低电平
-
STOP状态:scl高电平 -> sda上升沿 -> scl高电平
-
逻辑事务
-
指定地址write:写设备地址(7b)+W(1b)->写寄存器地址8b->写数据->从机应答
-
当前地址read:读设备地址(7b)+R(1b)->从机应答=>读数据->主机不应答
-
指定地址read:读设备地址(7b)+W(1b)->读寄存器地址8b->读设备地址(7b)+R(1b)->从机应答=>读数据 ->主机不应答
- 其实是指定地址write与当前地址read的复合格式
- 首先利用write给出设备地址+W和寄存器地址,然后重新启动IIC,再利用read读当前地址
- 重新启动IIC是指进入==Sr状态==(发送中途使clk=0,data=0的状态)或者进入P->S状态
-
连续地址write:写设备地址(7b)+W(1b)->写寄存器地址8b->写数据->从机应答->写数据->从机应答->...
- 是指定地址write的复合格式,也叫BurstWrite
-
连续地址read:读设备地址(7b)+R(1b)->从机应答=>读数据->主机应答->读数据...->主机不应答
- 是指定地址read的复合格式,也叫BurstRead
-
设备寻址模式
- 7位设备寻址:寻址流程为:7位设备寻址(3b)+R/W(1b)->...
- 10位设备寻址:5+3+7位设备寻址,即寻址流程为:寻址标志位(5b)+3位设备寻址(3b)+R/W(1b)->7位设备寻址(7b)->...
- 寻址标志位=11110b时,识别为10位设备寻址模式,否则识别为7位寻址模式
硬件I2C

- 发送和接收不同时发生
-
发送和接收使用同一个buffer和移位器
-
STM32作为从机
- 自身地址寄存器:机器的第一个从设备地址,可以使用比较器与总线发出的设备地址比较
- 双地址寄存器:机器的第二个从设备地址
- STM32作为主机
- 帧错误校验:进行CRC校验,附加在数据后面
- 由于STM32上的I2C外设通过GPIO输出,所以GPIO需要设置GPIO复用输出(复用开漏模式)
软件SPI
- 协议特点:同步、全双工、固定的一主多从、高位和低位先行均可(一般高位先行)
- sck为clk,MOSI(DI)为主出从入、MISO(DO)为主入从出、SSx(CSx)为从设备选择
- master:输出MO配置为推挽输出;输入MI配置为浮空或上拉输入
- slave:输出SO接三态门,当从有效时才为推挽输出,否则浮空;输入SI配置为浮空或上拉输入
- 发送和接收的==传输特点==
- 一次传输必须同时发送和接收,若仅发送/接收,就忽略接收/发送即可
- 可以配置上升沿读写/下降沿读写
- 为了在posedge clk下实现下降沿操作,一般的解决方法是:clk分频/相位偏移为clk1
- 主从的先行方式一定要一致,否则要位反转,不然位序是反的
- SPI/QSPI时序及事务
- Read:cmd(8b)->addr(24b)->rdata
- FastRead:cmd(8b)->addr(24b)->8ClkWait->rdata
- wait周期相当于访存周期,会读设备数据到寄存器,为了后续输出

- QuadFastRead:cmd(8b)->addr(24b)->6ClkWait->rdata
- QSPI具有4根SIO线,cmd的8b只在第一根SIO上传输,rdata会在4根SIO传输

- Write:cmd(8b)->addr(8b)->wdata
- QuadWrite:cmd(8b)->addr(8b)->wdata
- QSPI具有4根SIO线,cmd的8b只在第一根SIO上传输,wdata会在4根SIO传输
- 由于不需要读设备,所以没有wait状态
- QPI时序及事务
- QPIEnter:cmd(8b)=0x35
- QPIExit:cmd(8b)=0xF5
- QPIRead:cmd(8b)->addr(24b)->4ClkWait->rdata
- QPI与QSPI不同,只有1根SIO线
- QPIFastRead:cmd(8b)->addr(24b)->6ClkWait->rdata
- QPIWrite:cmd(8b)->addr(24b)->wdata
- SPI的XIP模式
- 当启用XIP时,由SPI核自动生成SPI/QSPI/QPI事务
- 一般用于软件无法实现SPI事务时,比如读取flash中的bootloader
硬件SPI

-
分为发送buffer、接收buffer、共用的移位寄存器
-
发送和接收同时发生
-
发送buffer->移入到移位寄存器
-
从移位寄存器移出->接收buffer
