外设驱动库开发笔记43:GPIO模拟SPI驱动

      最后更新:2022-07-04 02:46:29 手机定位技术交流文章

      SPI总线是我们常见的串行设备接口,一般而言,我们将适应硬件SPI接口,但是有时候,当硬件端口不够时,我们还希望使用软件模拟SPI硬件接口,尤其是在需求不够高的时候。本文将讨论如何使用GPIO和软件模拟SPI通信接口。

      1、功能概述

      SPI是一个同步序列通信接口,用于微处理器和控制器之间的序列连接和外部扩展芯片,并发展成为工业标准。

      1.1、物理层

      物理层的SPI总线通常使用三个总线和一个芯片选择线,三个总线是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总线通信的设备,一个主机可以与多个服务器通信。钟和数据总线是常见的,每个服务器是独立于芯片选择的。下图所示的特定连接方法:

      也就是说,当多个SPIs从设备发送到SPI主机时,该设备的时钟和总线数据线SCK、MOSI和MISO同时连接到同一SPI总线,也就是说,不管设备有多少,所有三条线都被联合使用。每个设备都有独立的NSS信号线,即有多少个从设备,有多少条选择信号线.

      1.2、协议层

      我们已经总结了SPI巴士的物理连接方式,然后我们将研究具体的通信协议。 在理解协议之前,我们需要明确两个概念,即时钟的极性和时钟的阶段。
      所谓时钟极性,通常称为CPOL,是指时钟处于空状态的电平衡。 如果数据前后空状态为高压,则CPOL=1;如果空状态为低压,则CPOL=0。
      时钟的阶段,通常称为CPHA,表示数据样本是在时钟脉冲的第一个或第二个步骤。 如果SCK的第一个跳动被数据样本跟踪,CPHA=0;如果SCK的第二个跳动被数据样本跟踪,CPHA=1。
      在通信协议中,根据CPOL和CPHA值,有四个不同的配置模式,不同的配置模式与不同的通信模式相符。
      (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总线分为四个工作模式,如图所示:

      只有当主机和接收机具有相同的工作模式时,接收机才能正常通信。 在实际应用中,0和3是比较常见的工作模式,但我们的驱动设计应该考虑到这些四个模式,以便更广泛的适应性。

      2、驱动设计与实现

      简要描述了SPI通信总线的物理连接和通信协议,然后将基于协议的特性设计和实现基于GPIO的SPI总线驱动器。

      2.1、对象定义

      我们仍然使用基于对象的概念来实现基于GPIO的SPI总线驱动器。 因为它是基于对象的,我们需要在使用对象之前取得这个对象,所以我们必须首先定义基于GPIO模拟的SPI总线对象。

      2.1.目标抽象

      要得到基于GPIO模拟的SPI总线的对象,首先需要分析其基本特性。 一般来说,一个对象至少包含两个属性和操作的方面。
      我们首先考虑对象的属性,这些属性必须作为属性来识别或记录对象的属性。 我们已经学会了SPI总线的一些特性和独特的设置,所以这些特性和设置是否可以成为对象的属性?
      我们认为它是同步的公共汽车,控制SPI总线需要一个钟,这与SPI总线的通信速度有关,这种通信速度不仅配置了SPI总线的工作模式,而且识别了当前的工作状态。所以我们将使用工作速度作为属性模拟SPI总线对象。过去我们讨论了SPI总线的工作模式,工作模式由警务处和卫生署决定, bus的初始化将决定工作模式,所以我们需要记录CPOL和CPHA,我们还将使用CPOL和CPHA作为对象属性。
      其次,我们考虑了GPIO仿真SPI总线的运行.我们将实现我们想要的对象,根据特定平台的行为实现,该操作被定义为对象。对于GPIO模拟的SPI总线,我们需要通过公共汽车发送数据和接收数据,接收和发送的实现取决于具体的硬件平台,所以我们将发送数据并接收定义为对象操作的数据。SPI总线需要时钟作为同步总线,而且时钟操作也取决于具体的硬件平台实现,因此,我们总是作为对象操作控制。
      基于GPIO模拟SPI总线的上述分析,我们可以定义GPIO模拟SPI总线的对象类型如下:

      2.1.对象初始化

      我们知道,你需要在使用它之前初始化一个对象。因此,我们考虑了GPIO模拟SPI对象的初始化函数。一般来说,初始化函数需要处理问题的几个方面.第一个是检查输入参数是否合理;第二个是将初始值分配给对象属性;第三是为对象进行必要的初始化配置。因此,我们设计了GPIO模拟SPI对象的初始化函数如下:

      2.2、对象操作

      我们已经定义了对象类型,并实现了对象的初始化函数,但我们还没有实现对象的特定操作,所以现在让我们实现对象的特定操作。

      2.2.1.数据传输

      当我们使用SPI来实现数据通信时,免不了要发送数据,因此,我们需要解决使用GPIO模拟SPI端口发送数据的问题。这里我们考虑了使用模拟的SPI来发送一个字符串的问题,因为发送多个字节是重复几个次。根据上面在不同的模式中分析的时序图,我们可以编译GPIO模拟SPI的功能,以发送一个字节如下:

      2.2.2.数据接收

      对SPI端口来说,不仅必须发送数据,而且必须从另一方接收数据,正如我们重新考虑接收字符串的情况一样。 同样,我们可以根据接收字符串的时序要求在不同的前后模式下编译接收字符串的功能如下:

      3、驱动的使用

      我们设计并实现了一种仿真GPIOSPI总线的驱动程序,然后我们将使用一个简单的例子来根据这个驱动程序的设计验证驱动程序的正确性。

      3.1.声明和初始化对象

      我们是基于对象的实现GPIO模拟SPI驱动器,所以在我们开始之前,我们需要声明一个模拟SPI对象如下:

      这个对象被声明后,我们需要在它可用之前初始化变量。 以前我们已经实现了对象变量初始化函数。 使用这个函数可以方便地初始化对象变量,该函数有多个输入:

      在这些参数中, simulaSPIInstance是我们想要初始化对象变量的指针。钟极度、钟相和数据长度是计数量,我们可以根据实际使用要求选择输入.时钟频率是我们想要的时钟速度,最大500K。其他参数是调制函数的指针。这些功能是我们需要在我们的应用程序中实现的,它们的原型如下:

      这些功能的实现与特定的应用程序平台有关,基于STM32F407的HAL库实现下列功能:

      延迟操作函数使用了我们系统中常见的“延迟”(Delayus)函数,我们用这些参数调用初始化函数来初始化对象变量如下:

      3.基于对象的操作

      在初始化该对象变量后,我们可以基于此操作对象。 基于驱动程序的简单读写操作如下:

      我们测试了阅读数据,发送数据,同时写字和阅读数据,写字后阅读数据等等。

      4、应用总结

      在这一篇中,我们设计并实现了基于GPIO仿真的SPI接口驱动程序.在此基础上设计了一个简单的测试应用.我们没有问题通过GPIO模拟的SPI接口到SPI接口Flash来写数据、读数据、同时读和预写和后读测试。
      注意,在使用驱动器时,SPI端口的速度是有限的,因为它使用GPIO模拟,并且它目前可以支持500K的速度比它能够支持的其他速度快。

      欢迎关注:

      本文由 在线网速测试 整理编辑,转载请注明出处,原文链接:https://www.wangsu123.cn/news/29152.html

          热门文章

          文章分类