STM32之七:SPI通信

news2024/9/21 4:21:56

目录

1.SPI通信简介

1.1 主从模式

1.2 4根通信线

        1.3 数据传输

2. SPI总线时序及其4种工作模式

2.1 SPI数据移位示意

2.2 SPI四种工作模式

2.2.1  mode 0 :CPOL = 0,CPHA=0

2.2.2 mode 1: CPOL = 0,CPHA = 1

2.2.3 mode 2: CPOL = 1,CPHA = 0

2.2.4 mode 3: CPOL = 1,CPHA = 1

3.  SPI 模式0 代码编写


1.SPI通信简介

SPI(Serial Peripheral Interface)通信是一个全双工、同步,可以一主多从的一种串行通信协议,该通信模式需要4根线,分别是MISO\MOSI\CLK\CS,广泛用于微控制器与各种外围设备(如传感器、存储器、显示器等)之间的数据交换。

1.1 主从模式

        SPI采用主从模式(Master-Slave)。在通信过程中,通常有一个主设备(Master)和一个或多个从设备(Slave)。主设备控制整个通信过程。

1.2 4根通信线

        MISO(Master input Slave Output):主设备接收数据,从设备发送数据。一般主设备的MISO引脚连接到从设备的MOSI引脚。

        MOSI(Master output Slave Input):主设备发送数据,从设备接收数据。主设备的MOSI引脚连接到从设备的MISO引脚

        SCK(Serial Clock):同步时钟线,由主设备生成,用于同步数据传输。主设备的SCK引脚连接到从设备的SCK引脚。

        CS/SS(Chip Select/ Slave Select):从设备选择信号,由主设备控制,低电平有效。在单主多从的模式下,主设备通过控制相应从机的CS引脚来选择和哪个从设备进行通信。只有被主设备选择的从设备才能相应从设备的指令。

一主多从的接线图如下所示:

        

        在和STM32 进行接线的时候,输出引脚需要配置为推挽输出模式,输入引脚需要配置为浮空或者上拉输入。

        1.3 数据传输

        SPI总线在传输设备时,先传送高位,后传送低位;数据线为高电平表示逻辑1,低电平表示逻辑0,主设备/从设备在时钟线的上升沿或者下降沿往数据线上发送数据,or读取数据。

        SPI为全双工通信,全双工通信即可以同时发送和接收数据。

2. SPI总线时序及其4种工作模式

2.1 SPI数据移位示意

SPI数据是如何在主机和从机之间传输的?下图展示了前两位数据移动的过程,主机波特率发生器生成时钟信号,通过SCK将时钟信号同步给从机。SPI是先传送高位,后传送低位,因此会将数据左移,每来一个时钟信号,完成一位数据传输。

对于SPI时序和数据发送不太清楚的,强烈推荐观看B站UP主江协科技的STM32SPI章节。传送门:江协科技-SPI讲解

2.2 SPI四种工作模式

主设备会通过波特率发生器来产生相应的时钟脉冲,时钟脉冲组成了时钟信号,时钟信号通过时钟极性(CPOL)和时钟相位(CPHA)控制着两个SPI设备间何时数据交换以及何时对接收到的数据进行采样,来保证数据在两个设备之间是同步传输的。

  1. CPOL = 1:表示空闲时是高电平
  2. CPOL = 0:表示空闲时是低电平
  3. CPHA = 1:表示从第一个跳变沿开始采样
  4. CPHA = 0:表示从第二个跳变沿开始采样

SPI通过时钟极性(CPOL)和时钟相位(CPHA)的搭配来得到四种工作模式。

2.2.1  mode 0 :CPOL = 0,CPHA=0

模式0的特性为:

CPOL = 0:空闲时是SCK低电平,第1个跳变沿是上升沿,第2个跳变沿是下降沿
CPHA = 0:数据在第1个跳变沿(上升沿)采样(SCK第一个边沿移入数据,第二个边沿移出数据)

mode 0模式下SCK低电平表示空闲,可以看到SS从高电平拉达到低电平,表示主机选择该从机,MISO也从高阻状态变换到高电平(或者低电平,由具体数据决定)。

模式0表示SCK第一个跳变沿进行采样,第二个边沿即表示一个时钟周期,完成数据移位。

2.2.2 mode 1: CPOL = 0,CPHA = 1

模式1的特性为

CPOL = 0:空闲时是SCK低电平,第1个跳变沿是上升沿,第2个跳变沿是下降沿
CPHA = 1:数据在第2个跳变沿(上升沿)采样(SCK第一个边沿移出数据,第二个边沿移入数据)

mode 1 模式下,SCK低电平国表示空闲,在第一个时钟跳变沿沿到来时,主从两机已经做好准备,并在第二个跳变沿进行数据传输。

2.2.3 mode 2: CPOL = 1,CPHA = 0

模式2的特性为:

CPOL = 1:空闲时SCK为高电平

CPHA = 0:第一个时钟跳变沿进行采样

模式2状态下,SCK高电平为空闲,第一个跳变沿进行数据传输。

2.2.4 mode 3: CPOL = 1,CPHA = 1

模式3的特性为:

CPOL = 1:空闲时SCK高电平

CPHA = 1:第二个时钟跳变沿进行采样

模式3状态下,SCK高电平为空闲,第二个跳变沿进行数据传输。

3.  SPI 模式0 代码编写

代码来自B站up主:江协科技

//spi_.c
#include "stm32f10x.h"                  // Device header

/*引脚配置层*/

/**
  * 函    数:SPI写SS引脚电平
  * 参    数:BitValue 协议层传入的当前需要写入SS的电平,范围0~1
  * 返 回 值:无
  * 注意事项:此函数需要用户实现内容,当BitValue为0时,需要置SS为低电平,当BitValue为1时,需要置SS为高电平
  */
void MySPI_W_SS(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)BitValue);		//根据BitValue,设置SS引脚的电平
}

/**
  * 函    数:SPI写SCK引脚电平
  * 参    数:BitValue 协议层传入的当前需要写入SCK的电平,范围0~1
  * 返 回 值:无
  * 注意事项:此函数需要用户实现内容,当BitValue为0时,需要置SCK为低电平,当BitValue为1时,需要置SCK为高电平
  */
void MySPI_W_SCK(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_5, (BitAction)BitValue);		//根据BitValue,设置SCK引脚的电平
}

/**
  * 函    数:SPI写MOSI引脚电平
  * 参    数:BitValue 协议层传入的当前需要写入MOSI的电平,范围0~0xFF
  * 返 回 值:无
  * 注意事项:此函数需要用户实现内容,当BitValue为0时,需要置MOSI为低电平,当BitValue非0时,需要置MOSI为高电平
  */
void MySPI_W_MOSI(uint8_t BitValue)
{
	GPIO_WriteBit(GPIOA, GPIO_Pin_7, (BitAction)BitValue);		//根据BitValue,设置MOSI引脚的电平,BitValue要实现非0即1的特性
}

/**
  * 函    数:I2C读MISO引脚电平
  * 参    数:无
  * 返 回 值:协议层需要得到的当前MISO的电平,范围0~1
  * 注意事项:此函数需要用户实现内容,当前MISO为低电平时,返回0,当前MISO为高电平时,返回1
  */
uint8_t MySPI_R_MISO(void)
{
	return GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6);			//读取MISO电平并返回
}

/**
  * 函    数:SPI初始化
  * 参    数:无
  * 返 回 值:无
  * 注意事项:此函数需要用户实现内容,实现SS、SCK、MOSI和MISO引脚的初始化
  * CS——PA4
  * DO——PA6 从机输出
  * CLK—PA5 
  * DI——PA7 从机输入
  */
void MySPI_Init(void)
{
	/*开启时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);	//开启GPIOA的时钟
	
	/*GPIO初始化*/
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA4、PA5和PA7引脚初始化为推挽输出
	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA6引脚初始化为上拉输入
	
	/*设置默认电平*/
	MySPI_W_SS(1);											//SS默认高电平
	MySPI_W_SCK(0);											//SCK默认低电平
}

/*协议层*/

/**
  * 函    数:SPI起始
  * 参    数:无
  * 返 回 值:无
  */
void MySPI_Start(void)
{
	MySPI_W_SS(0);				//拉低SS,开始时序
}

/**
  * 函    数:SPI终止
  * 参    数:无
  * 返 回 值:无
  */
void MySPI_Stop(void)
{
	MySPI_W_SS(1);				//拉高SS,终止时序
}

/**
  * 函    数:SPI交换传输一个字节,使用SPI模式0
  * 参    数:ByteSend 要发送的一个字节
  * 返 回 值:接收的一个字节
  */

uint8_t MySPI_SwapByte(uint8_t ByteSend)
{
	uint8_t i, ByteReceive = 0x00;					//定义接收的数据,并赋初值0x00,此处必须赋初值0x00,后面会用到
	
	for (i = 0; i < 8; i ++)						//循环8次,依次交换每一位数据
	{
		MySPI_W_MOSI(ByteSend & (0x80 >> i));		//使用掩码的方式取出ByteSend的指定一位数据并写入到MOSI线
		MySPI_W_SCK(1);								//拉高SCK,上升沿移出数据
		if (MySPI_R_MISO() == 1){ByteReceive |= (0x80 >> i);}	//读取MISO数据,并存储到Byte变量
																//当MISO为1时,置变量指定位为1,当MISO为0时,不做处理,指定位为默认的初值0
		MySPI_W_SCK(0);								//拉低SCK,下降沿移入数据
	}
	
	return ByteReceive;								//返回接收到的一个字节数据
}

如果对最后一段位操作有些迷糊的,可以看另一篇博文:嵌入式移位赋值操作详解。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1925726.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024-07-14 Unity插件 Odin Inspector1 —— 插件介绍

文章目录 1 介绍2 模块3 学习目的 1 介绍 ​ Odin Inspector 是 Unity 的一个插件&#xff0c;拥有强大、自定义和用户友好的编辑器&#xff0c;而无需编写任何自定义编辑器代码&#xff0c;使得编程过程中的数据可视化更容易实现。 ​ 具体功能包括&#xff1a; 更舒适美观…

新一代大语言模型 GPT-5 对工作与生活的影响及应对策略

文章目录 &#x1f4d2;一、引言 &#x1f4d2;二、GPT-5 的发展背景 &#x1f680;&#xff08;一&#xff09;GPT-4 的表现与特点 &#x1f680;&#xff08;二&#xff09;GPT-5 的预期进步 &#x1f4d2;三、GPT-5 对工作的影响 &#x1f680;&#xff08;一&#xf…

FreeRTOS学习(1)STM32单片机移植FreeRTOS

一、FreeRTOS源码的下载 1、官网下载 FreeRTOS官方链接 官方下载速度慢&#xff0c;需要翻墙&#xff0c;一般选择第一个 2、直接通过仓库下载 仓库地址链接 同样很慢&#xff0c;甚至打不开网页&#xff0c;也不建议使用这种方法。 3、百度网盘 链接&#xff1a;https:…

ArrayList模拟实现

ArrayList模拟实现 ArrayList 的初步介绍常见操作 ArrayList 的简单模拟实现 ArrayList 的初步介绍 ArrayList也叫做顺序表&#xff0c;底层是一个数组。 在创建顺序表 时就应该规定 里面元素的数据类型&#xff0c;其中不能直接传基本数据类型&#xff0c;例如int、char。需要…

超简易高效的 AI绘图工具—与sd-webui一致界面,6G显存最高提升75%出图速率!(附安装包)

大家好&#xff0c;我是灵魂画师向阳 今天给大家分享一个基于Stable Diffusion WebUI 构建的AI绘图工具—sd-webui-forge&#xff0c;该工具的目标在于简化插件开发&#xff0c;优化资源管理&#xff0c;加速推理。 Forge承诺永远不会对Stable Diffusion WebUI用户界面添加不…

链接追踪系列-09.spring cloud项目整合elk显示业务日志

准备工作&#xff1a; 参看本系列之前篇&#xff1a;服务器安装elastic search 本机docker启动的kibana-tencent 使用本机安装的logstash。。。 本微服务实现的logstash配置如下&#xff1a; 使用腾讯云redis 启动本机mysql 启动本机docker 启动nacos,微服务依赖它作为…

rollup打包工具

rollup打包工具 在学习vite和vue3源码的时候&#xff0c;接触到了rollup&#xff0c;所以过来学习一下 什么是rollup rollup是一个模块化的打包工具&#xff0c;会将javascript文件进行合并。比起webpack&#xff0c;webpack在打包的时候会进行代码注入(保障兼容性)&#xf…

fortran简单排序算法,对一维、二维矩阵进行正序或倒序排序

fortran简单排序算法&#xff0c;对一维、二维矩阵进行正序或倒序排序 0. 引言1. 算法实现1.1 一维数组排序1.2 二维数组排序1.2 module文件 2. 结语 0. 引言 排序算法是计算机科学中的一项重要技术&#xff0c;它将一组数据按照特定的顺序排列起来。排序算法有很多种&#xff…

【云原生】Prometheus整合Alertmanager告警规则使用详解

目录 一、前言 二、Altermanager概述 2.1 什么是Altermanager 2.2 Altermanager使用场景 三、Altermanager架构与原理 3.1 Altermanager使用步骤 3.2 Altermanager工作机制 3.3 Altermanager在Prometheus中的位置 四、Altermanager部署与接入Prometheus 4.1 Altermana…

Codeforces Round 797 (Div. 3) F. Shifting String

感觉这种题写多了&#xff0c;第一眼就感觉是个图论&#xff0c;很经典的排列置换问题&#xff0c;首先连边&#xff0c;然后观察样例可以知道&#xff0c;大概是多个环的大小取lcm&#xff0c;但容易发现&#xff0c;环内部的循环节也对答案有影响&#xff0c;比如一个长度为4…

threadx 线程以及优先级调整案例

以正点原子stm32 f407板子为例子&#xff0c;如何创建工程 CubeMXCubeIDE在我之前的文章里提到了&#xff0c;这里我就不多重复。 有关线程优先级的两个参数 priority和preemption&#xff0c;我们来看看在官网是如何定义的 在main.c里面添加一个printf转串口的代码&#xff0…

Binder解析精炼

Binder原理解析精炼 1 注册服务 Server进程向binder驱动向Binder驱动发起服务注册请求 向Binder驱动申请创建一个XXXService的Binder的实体&#xff0c;Binder驱动为这个XXXService创建位于内核中的Binder实体节点以及Binder的引用 Binder驱动将注册请求转发给ServiceManager进…

Manim学习笔记05:实现向量的加法动画

以同一点 O&#x1d442; 为起点的两个已知向量 →a&#x1d44e;→&#xff0c; →b&#x1d44f;→&#xff0c;以 OA&#x1d442;&#x1d434;&#xff0c;OB&#x1d442;&#x1d435; 为邻边作 □OACB◻&#x1d442;&#x1d434;&#x1d436;&#x1d435;&#xff…

Yolov8 姿态估计

原文:Yolov8 姿态估计 - 知乎 (zhihu.com) YOLOv8论文还没有,官方默默又加了新模型:姿态估计。 现在你可以用YOLOv8做目标检测、实例分割、图像分类、目标跟踪、姿态估计,未完待续。。。。。。 一、Yolov8姿态估计 Yolov8的姿态估计模型是在COCO数据集训练的,目前支持…

python+Selenium自动化之免登录(cookie及token)

目录 cookie免登录 通过接口获取cookie 启用浏览器绕过登录 添加token 使用登录可以减去每次登录的重复操作&#xff0c;直接操作系统登录后的菜单页面&#xff0c;也可以减少安全验证登录&#xff0c;如图像验证登录的操作。注意&#xff1a;cookie和token都有有效期。 c…

前端Vue组件化实践:打造自定义等宽tabs标签组件

在前端开发的世界里&#xff0c;随着业务复杂度的提升和需求的多样化&#xff0c;传统的整体式开发方式已经难以满足快速迭代和高效维护的需求。组件化开发作为一种重要的解决方案&#xff0c;正逐渐受到广大开发者的青睐。本文将结合Vue框架&#xff0c;探讨如何通过组件化开发…

如何在Linux上如何配置虚拟主机

在Linux上配置虚拟主机可以通过使用Apache HTTP服务器来实现。Apache是一个开源的跨平台的Web服务器软件&#xff0c;可以在多种操作系统上运行并支持虚拟主机的配置。 以下是在Linux上配置虚拟主机的步骤&#xff1a; 安装Apache HTTP服务器 在终端中运行以下命令来安装Apache…

CANoe:为什么两个VLAN接口不能设置同一个网络的IP地址呢?

经常玩CANoe的人应该配置过TCP/IP Stack中网络节点的网卡信息&#xff0c;基本的信息包含&#xff1a;MAC地址、IP地址、子网掩码、默认网关、MTU值、IPv6地址。 如果你想让发送出去的报文携带VLAN tag&#xff0c;可以在网卡上添加VLAN tag信息。 此时你就能得到两个新的网卡V…

加速数字化转型,信创自主可控:TapData 为银行业数据管理能力建设提供新思路

使用 TapData&#xff0c;化繁为简&#xff0c;摆脱手动搭建、维护数据管道的诸多烦扰&#xff0c;轻量代替 OGG、DSG 等同步工具&#xff0c;「CDC 流处理 数据集成」组合拳&#xff0c;加速仓内数据流转&#xff0c;帮助企业将真正具有业务价值的数据作用到实处&#xff0c;…

防火墙nat与智能选路

这里写目录标题 此实验是基于上个实验的基础上添加功能拓扑1办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP不能用来转换)首先在fw1防火墙创建电信和移动两个安全区域&#xff0c;并且将对应的接口划分进去配置nat测试 分公司设备可…