SPI总线是我们常用的串行设备接口,一般情况下我们都会适应硬件SPI接口,但有些时候当硬件端口不足时,我们也希望可以使用软件来模拟SPI硬件接口,特别是要求不是很高的时候。在这一篇中我们将来讨论如何使用GPIO和软件来模拟SPI通讯接口。
1、功能概述
SPI即串行外设接口,是一种同步串行通讯接口,用于微处理器及控制器和外围扩展芯片之间的串行连接,现已发展成为一种工业标准。
1.1、物理层
SPI总线在物理层通常使用3条总线及1条片选线,3条总线分别为 SCK、 MOSI、 MISO,片选线为NSS,它们的作用介绍如下:
NSS( Slave Select),从设备选择信号线,常称为片选信号线。在SPI协议中没有设备地址,所以需要使用NSS信号线来寻址,当主机要选择从设备时,把该从设备的NSS信号线设置为低电平,该从设备即被选中,即片选有效,接着主机开始与被选中的从设备进行SPI通讯。所以SPI通讯以NSS线置低电平为开始信号,以NSS线被拉高作为结束信号。
SCK (Serial Clock),时钟信号线,用于通讯数据同步。它由通讯主机产生,决定了通讯的速率,不同的设备支持的最高时钟频率不一样,如 STM32 的 SPI 时钟频率最大为fpclk/2,两个设备之间通讯时,通讯速率受限于低速设备。
MOSI (Master Output, Slave Input),主设备输出/从设备输入引脚。主机的数据从这条信号线输出,从机由这条信号线读入主机发送的数据,即这条线上数据的方向为主机到从机。
MISO(Master Input,, Slave Output),主设备输入/从设备输出引脚。主机从这条信号线读入数据,从机的数据由这条信号线输出到主机,即在这条线上数据的方向为从机到主机。
对于使用SPI总线来进行通讯的设备,一台主机可以与多台从机进行通讯,时钟与数据总线为公用,片选线每台从机都是独立的,具体连接方式如下图所示:

也就是说,有多个SPI从设备与SPI主机通讯时,设备的时钟线和总线数据线 SCK、MOSI及MISO同时并联到相同的SPI总线上,即无论有多少个从设备,都共同只使用这 3 条总线。而每个从设备都拥有独立的一条NSS信号线,即有多少个从设备,就有多少条片选信号线。
1.2、协议层
我们已经简述了SPI总线的物理连接方式,接下来我们再来了解一下具体的通讯协议。在了解协议前,我们需要清楚两个概念,即时钟的极性和时钟的相位。
所谓时钟极性,通常称作CPOL,即是指在空闲状态下,时钟所处的电平状态。如果SCLK在数据发送之前和之后的空闲状态是高电平,那么就是CPOL=1;如果空闲状态SCLK是低电平,那么就是 CPOL=0。
而时钟的相位,通常称作CPHA,就是指数据采样是在时钟脉冲的第1个跳变沿还是在第2个跳变沿。如果在SCK的第1个跳变沿进行数据采样,则CPHA=0;如果在SCK的第2个跳变沿采样,则CPHA=1。
在通讯协议中,根据CPOL和CPHA的取值不同存在4种不同的配置方式,不同的配置方式对应不同的通讯模式。
(1)当CPOL=0,CPHA=0时,空闲状态时钟SCK的电平要保持在低电平,而数据的采样时刻在时钟脉冲的奇数跳变边沿,其时序图如下:

(2)当CPOL=0,CPHA=1时,空闲状态时钟SCK的电平要保持在低电平,而数据的采样时刻在时钟脉冲的偶数跳变边沿,其时序图如下:

(3)当CPOL=1,CPHA=0时,空闲状态时钟SCK的电平要保持在高电平,而数据的采样时刻在时钟脉冲的奇数跳变边沿,其时序图如下:

(4)当CPOL=1,CPHA=1时,空闲状态时钟SCK的电平要保持在高电平,而数据的采样时刻在时钟脉冲的偶数跳变边沿,其时序图如下:

根据这时钟情况,将SPI总线的工作模式分为4种,如下图所示:

而只有主机与从机拥有相同的工作模式时,主从机之间才可以正常通讯。在实际应用中,“模式 0”与“模式 3”是比较常见的工作模式,但在我们的驱动设计中应该兼顾这4种模式,以具备更广泛的适应性。
2、驱动设计与实现
我们已经简要的描述了SPI通讯总线的物理连接和通讯协议,接下来我们将根据其协议的特性设计并实现基于GPIO模拟的SPI总线驱动。
2.1、对象定义
我们依然使用基于对象的思想来实现基于GPIO模拟的SPI总线驱动。既然是基于对象,那么在使用一个对象之前我们需要先获得这个对象。所以我们必须先定义一个基于GPIO模拟的SPI总线的对象。
2.1.1、对象的抽象
我们要得到基于GPIO模拟的SPI总线的对象,需要先分析其基本特性。一般来说,一个对象至少包含属性与操作两方面的特性。接下来我们就来从这两个方面思考一下基于GPIO模拟的SPI总线的对象。
我们首先来考虑对象的属性,作为属性肯定是用于标识或记录对象特征的东西。我们在前面已经了解到SPI总线的一些特点和独特设定,那么这些特点和设定是否能成为对象的属性呢?
我们考虑到作为同步总线,SPI总线的控制需要时钟,这关系到SPI总线的通讯速率,这一通讯速率不仅配置SPI总线的工作方式也标识当前的工作状态,所以我们将工作速率作为模拟SPI总线对象的一个属性。在前面我们讨论过SPI总线的工作模式,工作模式由CPOL和CPHA决定,所以在初始化总线时就会确定工作模式,所以我们需要记录CPOL和CPHA,我们将CPOL和CPHA也作为对象的属性。
接下来我们考虑GPIO模拟SPI总线的操作问题。我们将那些对象要实现的,并且依赖于具体的平台的行为实现定义为对象的操作。对

本文介绍了一种使用GPIO模拟SPI接口的方法,包括SPI总线的基本原理、驱动设计与实现过程,并提供了一个简单的应用案例。
最低0.47元/天 解锁文章
1202

被折叠的 条评论
为什么被折叠?



