分享

​嵌入式系统低速接口-SPI(完结)

 云深无际 2023-08-13 发布于内蒙古

嵌入式系统低速接口-SPI

继续说SPI,SPI来说就是没有IIC那么固定。它就是设计了一种二进制流的交互方式,所以这也是为什么它那么灵活的原因。它可以在任何两个嵌入式的设备之间交换消息。

但是话又说回来了,SPI和UART都是串行的,那有啥区别呢?

SPI的优点:

  • 速度快,可达数十Mbps

  • 接口简单,只需要三根线(SCLK、MOSI、MISO)

  • 多设备支持简单,通过CS线选择从机

  • 更好的实时控制能力

  • 支持全双工通信

  • 推挽驱动(跟漏极开路正相反)提供了比较好的信号完整性和较高的速度

  • 比I²C或SMBus吞吐率更高

  • 协议非常灵活支持“位”传输

    • 不仅限于8-bit一个字节的传输

    • 可任意选择的信息大小、内容、以及用途

  • 异常简单的硬件接口:

    • 一般来讲比I²C或SMBus需要的功耗更低,因为需要更少的电路(包括上拉电阻)

    • 没有仲裁机制或相关的失效模式

    • “从设备”采用的是“主设备”的时钟,不需要精确的晶振

    • “从设备”不需要一个单独的地址 — 这点不像I²C或GPIB或SCSI

    • 不需要收/发器

  • 在一个IC上只用了4个管脚, 板上走线和布局连接都比并行接口简单很多

  • 每个设备最多只有一个单独的总线信号(片选);其它的都是共享的

  • 信号都是单方向的,非常容易进行电流隔离

  • 对于时钟的速度没有上限,有进一步提高速度的潜力

SPI的缺点:

  • 通信距离短,不适合长距离通信

  • 通常需要额外的片选信号增加从机数量

  • 全双工通信复杂度较高

  • 相比于I²C总线需要更多的管脚, 即便是只用到3根线的情况下

  • 没有寻址机制,在共享的总线连接时需要通过片选信号支持多个设备的访问

  • 从设备侧没有硬件流控机制(主设备一侧可以通过延迟到下一个时钟沿以降低传输的速率)

  • 从设备无法进行硬件“应答”(主设备传送的信息无法确定传递到哪里,是否传递成功)

  • 一般只支持一个主设备(取决于设备的硬件构成)

  • 没有查错机制

  • 没有一个正式的标准规范,无法验证一致性

  • 相对于RS-232, RS-485, 或CAN-总线,只能近距离传输

  • 存在很多的变种,很难能够找到开发工具(例如主适配卡)支持这所有的变种

  • SPI不支持热交换(动态地增加一个节点).

  • 如果想使用“中断”,只有通过SPI信号以外的其它信号线,或者采用类似USB1.1或2.0中的周期性查询的欺骗方式

  • 有一些变种比如多路I/O SPI和下面定义的三线串行总线都是半双工的

UART的优点:

  • 只需要两根线(TX、RX),连接简单

  • 可支持较远距离的通信

  • 更简单的全双工通信机制

  • 已经得到广泛应用,资料丰富

UART的缺点:

  • 速率较慢,通常在Mbps量级

  • 单主机与单从机通信,扩展难度大

  • 对时序信号敏感,容易出现误码

  • 不具备同步通信能力

总体来说,SPI更适合需要高速的数据交互和实时控制的场景;而UART更适合简单的远距离串行通信。

SPI偏向大数据流,UART可以长距离的控制。

假如是自己的封装的一个SPI的收发协议呢?

用结构体封装一个这样的东西,别问是啥?就这样

发送

接收

所以大概要实现的功能

在应用层的时候,这样使用

以上这些函数就可以实现,两个MCU之间的自定义协议的通讯。

在数据在处理上面,还有一个小细节,就是SPI和IIC的传感器,有时候里面的data要使用二进制的补码。

就像这样

使用二进制补码表示数据的好处主要有:
兼容有符号数据表示
二进制补码可以直接表示传感器采集的有符号数据(负数),无需额外处理。比如温度值可以直接用二进制补码形式表示正负温度。
提高数据处理效率
如果使用纯二进制表示无符号数据,CPU进行有符号数的运算和比较需要额外处理。使用补码可以直接进行算术运算,提高效率。
节省通信带宽
如果使用ASCII等编码,数据存储和传输会膨胀很多。二进制补码表示可以高效利用每一位。
简化数据解析
补码形式的数据可以直接作为int16、int32等有符号类型解析,无需复杂解码。
减少出错概率
ASCII编码需要进行 num-to-ascii 和 ascii-to-num 的转换,容易引入错误。二进制补码可以避免这类问题。
统一不同设备的数据表示
采用标准补码表示,使不同厂家的设备的数据可以统一被处理。
但需要注意,二进制补码需要处理符号位扩展问题,左移时需要适当维护符号位。并且 debug 和显示需做转换。使用二进制补码可以提高传感器数据处理的效率与质量。
那说了这么多,自己模拟一个协议可能是最好的,这里就用51单片机来搞这个。

使用的引脚

遍历需要发送的数据字节数组,一位一位写入MOSI口。同时通过设置SCK为1和0来模拟SPI时钟的上升沿和下降沿。

在一个8位循环内,读取MOSI的每一位数据,在SCK上升沿时采样,并写入data变量。SCK下降沿准备采样下一位。

传感器具有能在SCK输入信号为有效高电平或低电平时工作的能力。当 CE 信号变成高电平时,检测到 SCK 的 无效状态,而时钟输入 (CP)的极性决定数据是在系统时钟的上升沿或下降沿移入或移出,

看眼引脚

这个图给出了用于传送数据到寄存器和从寄存器移出数据的相应时钟边沿。每个时钟脉冲传送一位数据,数据位以 8 位为一组传送。
A是地址,D是数据。先发送地址字节,随后为数据。

数据可以采用单字节或多字节包的方式进行传送,在 3 字节包中,数据序列包括温度数据的 MSb、温度数据的 LSb 和紧接着的控制寄存器数据。通过向寄存器写入所需数据包的最高地址来启动多字节读功能。
  • 串行输出: SCLK : SCK, CLK.

  • 主输出 –> 从输入: MOSI : SIMO, SDI(对于“从”设备), DI, DIN, SI, MTST.

  • 主输入 ←- 从输出: –> MISO : SOMI, SDO (对于“从”设备), DO, DOUT, SO, MRSR.

  • 从选择: SS : nCS, CS, CSB, CSN, EN, nSS, STE, SYNC.

多数从设备的输出是三态的,当该从设备没有被选中的时候它们的MISO信号就为高阻(逻辑上断开连接)。不具有三态输出的器件是不能同其它器件共享SPI总线部分的,只能是一个从设备跟主设备相连。
单片机GPIO引脚的三态(Tri-state)是指该引脚可以处于三种状态:
1.推挽输出: 引脚被配置为输出,可以被置高电平(1)或者低电平(0)。
2.开漏输出: 引脚被配置为开漏输出,可以被置低电平(0),或处于高阻抗状态(Z)。
3.高阻输入: 引脚被配置为输入,此时处于高阻抗状态(Z),可以检测外部信号的高低电平。
文章的最后解惑一下。
这里以最常见的SPI3模式说下时序图怎么看。

当数据未发送时以及发送完毕后,SCK都是高电平,因此CPOL=1。看最前面。

在SCK第一个沿(下降沿)的时候,MOSI和MISO会发生变化。同时SCK第二个沿(上升沿)的时候,数据是稳定的,此刻采样数据是合适的,也就是上升沿即一个时钟周期的后沿锁存读取数据,即CPHA=1。

当CPHA=0、CPOL=0时SPI总线工作在方式0,如下图。简化起见把MOSI和MISO合在一起了。

SPI0通信时序图
SPI1和SPI2
当CPHA=0、CPOL=1时SPI总线工作在SPI1
当CPHA=1、CPOL=0时SPI总线工作在SPI2。

SPI1和SPI2通信时序图
要点,看发送前的时钟,然后看两个边沿对应的数据线,判断什么时候是保持边沿的。适合采样的。

让我小小的臭美一下

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多