目录

SPI协议简介

SPI接口介绍

SPI接口连接图

SPI数据传输方向

SPI传输模式

模拟SPI程序

SPI协议简介

SPI的通信原理很简单,一般主从方式工作,这种模式通常有一个主设备和一个或者多个从设备,通常采用的是4根线,它们是MISO(数据输入,针对主机来说)、MOSI(数据输出,针对主机来说)、SCLK(时钟,主机产生)、CS/SS(片选,一般由主机发送或者直接使能,通常为低电平有效)

  • SPI接口介绍

SCK:时钟信号,由主设备产生,所以主设备SCK信号为输出模式,从设备的SCK信号为输入模式

CS:使能信号,由主设备控制从设备,所以主设备CS信号为输出模式,从设备的CS信号为输入模式。

MOSI:主设备数据输出,从设备输入,所以主设备MOSI信号为输出模式,从设备的MOSI信号为输入模式

MISO:主设备数据输入,从设备数据输出,所以主设备MISO信号为输入模式,从设备的MISO信号为输出模式

  • SPI接口连接图

注意:MOSI和MISO不能交叉连接(可以把主从机理解为一个整体系统,MOSI为系统主机发送从机接收的数据线,MISO为主机接收从机发送的数据线)

  • SPI数据传输方向

SPI作为全双工的串行通信协议,数据传输时高位在前,低位在后。主机和从机公用由主机产生的SCK信号,所以在每个时钟周期内主机和从机有1bit的数据交换(因为MOSI和MISO数据线上的数据都是在时钟的边沿处被采样)。如下图

SPI协议规定数据采样是在SCK的上升沿或下降沿时刻(由SPI模式决定,下面会说到),观察上图,在SCK的边沿处(上升沿或下降沿),主机会在MISO数据线上采样(接收来从机的数据),从机会在MOSI数据线上采样(接受来自主机的数据),所以每个时钟周期中会有一bit的数据交换。

SPI传输模式

SPI总线传输一共有4种模式,这4种模式分别由时钟极性(CPOL)和时钟相位(CPHA)来定义。

CPOL:规定了SCK时钟信号空闲状态的电平

CPHA:规定了数据是在SCK时钟的奇数边沿还是偶数边沿被采样

模式0:CPOL=0,CPHA=0 SCK空闲为低电平,数据在SCK的上升沿被采样(提取数据)。

模式1:CPOL=0,CPHA=1 SCK空闲为低电平,数据在SCK的下降沿被采样(提取数据)

模式2:CPOL=1,CPHA=0 SCK空闲为高电平,数据在SCK的下降沿被采样(提取数据)

模式3:CPOL=1,CPHA=1 SCK空闲为高电平,数据在SCK的上升沿被采样(提取数据)

以模式0为例,SCK空闲为低电平,数据在SCK的上升沿被采样(提取数据),在SCK的下降沿奇幻数据线的数据。

  • 在时钟的第一个上升沿(游标1处)(采样点)

MOSI上数据为1,则在此边沿从机采样,数据为1,采样点在MOSI数据线的中间

MISO上数据为0,则在此边沿从机采样,数据为0,采样点在MISO数据线的中间

  • 在时钟的第一个下降沿(游标2处)(触发点)

MOSI上数据由1切换为0,数据在时钟的下降沿时切换数据

MISO上数据由0切换为1,数据在时钟的下降沿时切换数据

  • 在时钟的第2~8个上升沿(采样点),主机在MISO上采样数据,从机在MOSI上采样数据
  • 在时钟的第2~8个下降沿(触发点),主机在MISO上切换数据,从机在MOSI上切换数据

模拟SPI程序

初始化代码

#define    SPI_SCK_PIN            GPIO_PIN_5
#define    SPI_SCK_GPIO_PORT      GPIOA
#define    SPI_MOSI_PIN           GPIO_PIN_7
#define    SPI_MOSI_GPIO_PORT     GPIOA
#define    SPI_MISO_PIN           GPIO_PIN_6
#define    SPI_MISO_GPIO_PORT     GPIOA
#define    SPI_NSS_PIN            GPIO_PIN_14
#define    SPI_NSS_GPIO_PORT      GPIOOD#define    SPI_SCK_GPIO_CLK_ENABLE()     HAL_GPIO_WritePin(SPI_MOSI_GPIO_PORT,                                 SPI_MOSI_PIN, GPIO_PIN_SET)
#define MOSI_L  HAL_GPIO_WritePin(SPI_MOSI_GPIO_PORT, SPI_MOSI_PIN,                         GPIO_PIN_RESET)
#define SCK_H   HAL_GPIO_WritePin(SPI_SCK_GPIO_PORT, SPI_SCK_PIN, GPIO_PIN_SET)
#define SCK_L   HAL_GPIO_WritePin(SPI_SCK_GPIO_PORT, SPI_SCK_PIN,             GPIO_PIN_RESET)
#define MISO    HAL_GPIO_ReadPin(SPI_MISO_GPIO_PORT, SPI_MISO_PIN)
#define NSS_H   HAL_GPIO_WritePin(SPI_NSS_GPIO_PORT, SPI_NSS_PIN, GPIO_PIN_SET)
#define NSS_L   HAL_GPIO_WritePin(SPI_NSS_GPIO_PORT, SPI_NSS_PIN,     GPIO_PIN_RESET) void SPI_Init(void)
{  /*##-1- Enable peripherals and GPIO Clocks #########################*//* Enable GPIO TX/RX clock */SPI_SCK_GPIO_CLK_ENABLE();SPI_MISO_GPIO_CLK_ENABLE();SPI_MOSI_GPIO_CLK_ENABLE();SPI_NSS_GPIO_CLK_ENABLE();/*##-2- Configure peripheral GPIO #######################*//* SPI SCK GPIO pin configuration  */GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin       = SPI_SCK_PIN;GPIO_InitStruct.Mode      = GPIO_MODE_OUTPUT_PP;//GPIO_InitStruct.Pull      = GPIO_PULLDOWN;GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;HAL_GPIO_Init(SPI_SCK_GPIO_PORT, &GPIO_InitStruct);HAL_GPIO_WritePin(SPI_SCK_GPIO_PORT, SPI_SCK_PIN, GPIO_PIN_SET);/* SPI MISO GPIO pin configuration  */GPIO_InitStruct.Pin = SPI_MISO_PIN;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;HAL_GPIO_Init(SPI_MISO_GPIO_PORT, &GPIO_InitStruct);/* SPI MOSI GPIO pin configuration  */GPIO_InitStruct.Pin = SPI_MOSI_PIN;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;HAL_GPIO_Init(SPI_MOSI_GPIO_PORT, &GPIO_InitStruct);HAL_GPIO_WritePin(SPI_MOSI_GPIO_PORT, SPI_MOSI_PIN, GPIO_PIN_SET);GPIO_InitStruct.Pin = SPI_NSS_PIN;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;HAL_GPIO_Init(SPI_NSS_GPIO_PORT, &GPIO_InitStruct);HAL_GPIO_WritePin(SPI_NSS_GPIO_PORT, SPI_NSS_PIN, GPIO_PIN_SET);}

模拟SPI4种工作模式:

/*CPOL = 0 , CPHA = 0,MSB first*/
uint8_t SOFT_SPI_RW_MODE0(uint8_t write_data)
{uint8_t i, read_data;for(i=0;i<8;i++){if(write_data & 0x80)MOSI_H;elseMOSI_L;write_data <<= 1;delay_us(1);SCK_H;read_data <<= 1;if(MISO)read_data++;delay_us(1);SCK_L;__nop();    }return read_data;}/* CPOL=0,CPHA=1, MSB first */
uint8_t SOFT_SPI_RW_MODE1(uint8_t byte)
{uint8_t i,Temp=0;for(i=0;i<8;i++)     // 循环8次{SCK_H;     //拉高时钟if(byte&0x80){MOSI_H;  //若最到位为高,则输出高}else      {MOSI_L;   //若最到位为低,则输出低}byte <<= 1;     // 低一位移位到最高位delay_us(1);SCK_L;     //拉低时钟Temp <<= 1;     //数据左移if(MISO)Temp++;     //若从从机接收到高电平,数据自加一delay_us(1);}return (Temp);     //返回数据
}/* CPOL=1,CPHA=0, MSB first */
uint8_t SOFT_SPI_RW_MODE2(uint8_t byte)
{uint8_t i,Temp=0;for(i=0;i<8;i++)     // 循环8次{if(byte&0x80){MOSI_H;  //若最到位为高,则输出高}else      {MOSI_L;   //若最到位为低,则输出低}byte <<= 1;     // 低一位移位到最高位delay_us(1);SCK_L;     //拉低时钟Temp <<= 1;     //数据左移if(MISO)Temp++;     //若从从机接收到高电平,数据自加一delay_us(1);SCK_H;     //拉高时钟}return (Temp);     //返回数据
}/* CPOL = 1, CPHA = 1, MSB first */
uint8_t SOFT_SPI_RW_MODE3( uint8_t write_dat )
{uint8_t i, read_dat;for( i = 0; i < 8; i++ ){SCK_L; if( write_dat & 0x80 )MOSI_H;  else                    MOSI_L;  write_dat <<= 1;delay_us(1);  SCK_H; read_dat <<= 1;  if( MISO ) read_dat++; delay_us(1);__nop();}return read_dat;
}

软件模拟SPI接口程序代码相关推荐

  1. java如何编写spi接口_软件模拟SPI接口程序代码(4种模式)

    软件模拟SPI接口程序代码(4种模式) SPI协议简介 SPI的通信原理很简单,一般主从方式工作,这种模式通常有一个主设备和一个或多个从设备,通常采用的是4根线,它们是MISO(数据输入,针对主机来说 ...

  2. 软件模拟SPI接口程序代码(4种模式)

    软件模拟SPI接口程序代码(4种模式) SPI协议简介 SPI的通信原理很简单,一般主从方式工作,这种模式通常有一个主设备和一个或多个从设备,通常采用的是4根线,它们是MISO(数据输入,针对主机来说 ...

  3. STM32F103软件模拟SPI接口驱动ILI9486液晶屏

    STM32F103软件模拟SPI接口驱动ILI9486液晶屏 ILI9486的工作模式 ILI9486的SPI总线方式简介 ILI9486的3线SPI总线底层驱动配置步骤 ILI9486的工作模式 I ...

  4. 单片机软件模拟SPI接口—加深理解SPI总线协议

    单片机软件模拟SPI接口-加深理解SPI总线协议   SPI(Serial Peripheral Interfacer 串行外设接口)是摩托罗拉公司推出的一种同步串行通讯接口,用于微处理器臌控制器和外 ...

  5. 用GPIO模拟SPI接口读取传感器数据

    本文基于平头哥开发板RVB2601,简要介绍了用GPIO模拟SPI时序逻辑,实现SPI协议,按照特定温度传感器的时序,读取其数据,及示例程序 一.概述 SPI(Serial Peripheral In ...

  6. 【STM32】0.96寸OLED显示屏(7针SPI协议)软件模拟SPI

    Author:AXYZdong 自动化专业 工科男 有一点思考,有一点想法,有一点理性 [自制展示]2020鼠年大吉 文章目录 概述 3.1硬件设计 3.2软件设计 3.2.1编程要点 3.2.2代码 ...

  7. 嵌入式单片机基础篇(三十六)之STM32F1SPI标准接口程序以及模拟SPI标准接口程序讲解

    STM32F1SPI标准接口程序以及模拟SPI标准接口程序讲解 一.SPI标准接口初始化: 1.SPI 内部结构简明图 2.上一篇文章提到,spi标准协议包含4条信号线.时钟相位.时钟极性.数据单字节 ...

  8. 软件模拟SPI时序实现25Q64读写操作

    软件模拟SPI时序实现25Q64读写操作 单片机采用SPI/IIC通讯协议访问外围电子模块如:显示屏.EEPROM.FLASH.各种电子传感器等等越来越多,掌握SPI/IIC通讯协议访问外设非常必要. ...

  9. 一文搞懂——软件模拟SPI

    关于stm32通信协议:软件模拟SPI.软件模拟I2C的总结(fishing_8)_To_be_a_fisher的博客-CSDN博客_stm32 软件spi 发现一篇写的软件模拟SPI的比较容易理解的 ...

最新文章

  1. php性能分析工具 - xhprof的安装使用
  2. 从零开始编译自己的Linux发行版 LFS简介
  3. R语言实战应用精讲50篇(二)-多重线性回归系列之稳健回归
  4. Redis操作key相关API
  5. MVC是架构模式,而不是设计模式
  6. 红包封面发货平台卡密系统 全新红包封面平台可搭建分站独立后台的源码
  7. 浅谈前端面向对象oop思想
  8. 2017年 外牌转沪牌 攻略 (沪南路车管所)
  9. 从Oppo手机拍照无法展示谈图片压缩
  10. 浅谈Anchor free与Anchor based
  11. 光盘在服务器上装系统,如何通过DELL引导光盘在戴尔11G服务器上安装Win2003操作系统?.docx...
  12. 费解的开关解析 C++【递推+位运算】
  13. 一个DataFrame赋值的诡异报错 A value is trying to be set on a copy of a slice from a DataFrame. Try using .loc
  14. 微信小程序支付 tp5
  15. 【SCIR笔记】Transformer及其变种
  16. Skywalking极简入门
  17. 如何寻找数组中最大值与最小值(取双元素法)
  18. 《东周列国志》第五十七回 娶夏姬巫臣逃晋 围下宫程婴匿孤
  19. Windows 标准控件 ComboBox 的改造
  20. 假如我有一台新电脑, 我要做些什么?

热门文章

  1. Android-代码设置TextView字体加粗或者不加粗
  2. OpenCV4 快速入门 (学习笔记 全)
  3. Git commit (amend)
  4. git hub寻找资源
  5. PDF拆分与合并工具(DOS版)
  6. 诚之和:字节再迎裁员潮温州百人“大撤退”、ohayoo应届生“团灭”
  7. 身份管理的15个安全开发实践
  8. 如何使用阿里云虚拟主机搭建网站?
  9. AD生成顶层丝印、底层丝印
  10. 安防视频监控流媒体服务器系统对网络带宽的要求