当前位置: 首页 > news >正文

STM32的串行外设接口SPI

一、SPI简介

1.SPI总线特点

        (1)四条通信线

        SPI需要SCK、MISO、MOSI、NSS四条通信线来完成数据传输 ,每增加一个从机,多一条NSS通信线。

        (2)多主多从

        SPI总线允许有多个主机和多个从机。

        (3)传输速率

        比常见的I2C协议要快,通常为Mbit级别。

        (4)通信方式 

         是同步全双工串行通信,每次交换一个字节(8bit)或者两个字节(16bit),可选择高位先行或者低位先行。

2.SPI总线术语

  • SCK:串行时钟线,作为主设备的输出、从设备的输入。

  • MISO:主机输入/从机输出数据线,该引脚在主模式下接收数据,在从模式下发送数据。

  • MOSI:主机输出/从机输入数据线,该引脚在主模式下发送数据,在从模式下接收数据。

  • NSS:低电平有效的从机选择线。NSS引脚是可选的,一般选择用软件管理。

3.SPI硬件构成

        所有SPI设备的SCKMOSIMISO分别连在一起,主机另外引出多条NSS控制线,分别接到各从机的NSS引脚,输出引脚配置为推挽输出,输入引脚配置为浮空或上拉输入。

 4.位传输

        (1)起始信号 

                SS引脚从高电平切换到低电平 。

        (2)终止信号 

                SS引脚从低电平切换到高电平 。

5.数据传输模式 

        在使用STM32的SPI外设时,需要设置时钟相位(CPHA)和时钟极性(CPOL)。 

 (1)模式0
  • CPOL=0:空闲状态时,SCK为低电平 
  • CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据

(2)模式1
  • CPOL=0:空闲状态时,SCK为低电平 
  • CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据

(3)模式2
  • CPOL=1:空闲状态时,SCK为高电平 
  • CPHA=0:SCK第一个边沿移入数据,第二个边沿移出数据

 (4)模式3
  • CPOL=1:空闲状态时,SCK为高电平 
  • CPHA=1:SCK第一个边沿移出数据,第二个边沿移入数据

 二、STM32的SPI外设

1.STM32的SPI外设的特性:

  • 8位或16位传输帧格式
  • 可选的时钟频率、高/低位先行
  • 支持多主模式
  • 可触发中断的专用发送和接收标志、主模式故障、过载以及CRC错误标志
  • SPI总线忙状态标志
  • 支持DMA功能的1字节发送和接收缓冲器,产生发送和接收请求
  • 兼容I2S协议

2.STM32 SPI外设的基本结构:

 3.状态标志

        应用程序可以通过TXE、RXNE和BUSY三个状态标志来完全监控SPI总线的状态。

        (1)发送缓冲器空闲标志(TXE) 

        此标志为1时表示发送缓冲器为空,可以写下一个待发送的数据进入缓冲器中。 

         (2)接收缓冲器非空标志(RXNE)

        此标志为1时表示接收缓冲器中包含有效的接收数据。 

        (3)忙标志(BUSY)

        此标志为1时表示SPI正忙于通信,但有一个例外:在主模式下的双向接收模式下,在接收期间BUSY标志保持为低。

三、STM32 SPI外设的通信方式 

 1.主模式

        在SPI主模式下,MOSI引脚是数据输出,而MISO是数据输入,SCK引脚产生串行时钟。 

 2.从模式

        在 SPI从模式下,MOSI引脚是数据输入,而MISO是数据输出,SCK引脚用于接收来自主机的串行时钟。

四、STM32 SPI外设使用流程 

        虽然不同器件实现的功能不同,但是只要遵循SPI协议,其通信方式都是一样的,配置流程也基本相同。对于STM32,首先要对SPI进行配置,使其能够正常工作,再结合不同器件的驱动程序,完成STM32与不同器件的数据传输。这里只介绍STM32作为主机的使用流程,使用流程和参考代码如下:

  1. 配置GPIO
  2. 配置SPI
  3. 写一个产生起始条件的函数
  4. 写一个产生终止条件的函数
  5. 写一个交换数据的函数
void SPI_W_SS(uint8_t Bit)          //根据Bit设置SS引脚的电平
{GPIO_WriteBit(GPIOA, GPIO_Pin_4, (BitAction)Bit);		
}void SPI_Init(void)                 //配置GPIO和SPI
{RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_SPI1, ENABLE);GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA4引脚初始化为推挽输出,作为NSS片选引脚GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5 | GPIO_Pin_7;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);					//将PA5和PA7引脚初始化为复用推挽输出,即配置SCK和MOSIGPIO_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引脚初始化为上拉输入,即配置为MISOSPI_InitTypeDef SPI_InitStructure;						SPI_InitStructure.SPI_Mode = SPI_Mode_Master;			//模式,选择为SPI主模式SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;//方向,选择2线全双工SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;		//数据宽度,选择为8位SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;		//先行位,选择高位先行SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_128;	//波特率分频,选择128分频SPI_InitStructure.SPI_CPOL = SPI_CPOL_Low;				//SPI极性,选择低极性SPI_InitStructure.SPI_CPHA = SPI_CPHA_1Edge;			//SPI相位,选择第一个时钟边沿采样,极性和相位决定选择SPI模式0SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;				//NSS,选择由软件控制SPI_InitStructure.SPI_CRCPolynomial = 7;				//CRC多项式,暂不用,给默认值7SPI_Init(SPI1, &SPI_InitStructure);						SPI_Cmd(SPI1, ENABLE);									//使能SPI1,开始运行MySPI_W_SS(1);											//NSS默认高电平
}void MySPI_Start(void)                          //产生起始信号
{MySPI_W_SS(0);	//拉低SS
}void MySPI_Stop(void)                           //产生终止信号
{MySPI_W_SS(1);	//拉高SS
}uint8_t MySPI_SwapByte(uint8_t ByteSend)        //交换一个字节数据
{while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_TXE) != SET);	//等待发送数据寄存器空SPI_I2S_SendData(SPI1, ByteSend);								//写入数据到发送数据寄存器,开始产生时序while (SPI_I2S_GetFlagStatus(SPI1, SPI_I2S_FLAG_RXNE) != SET);	//等待接收数据寄存器非空return SPI_I2S_ReceiveData(SPI1);								//读取接收到的数据并返回
}

 代码仅供参考,具体使用需要结合相关从机器件的开发文档。

相关文章:

STM32的串行外设接口SPI

一、SPI简介 1.SPI总线特点 (1)四条通信线 SPI需要SCK、MISO、MOSI、NSS四条通信线来完成数据传输 ,每增加一个从机,多一条NSS通信线。 (2)多主多从 SPI总线允许有多个主机和多个从机。 (3&…...

函数重载

一、概念 C 允许在同一作用域中存在几个功能类似的同名函数,但这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同 int Add(int left, int right) {return leftright; }double Add(double left, double right) {return leftright; }long Add(long left, l…...

单例模式:Python中的“独一无二”模式

引言 单例模式是一种常用的设计模式,它确保一个类只有一个实例,并提供一个全局访问点。这种模式在需要控制资源消耗、管理共享资源或者协调系统组件时非常有用。例如,数据库连接、配置文件管理、日志记录等场景。 基础语法介绍 单例模式的…...

C++和OpenGL实现3D游戏编程【连载12】——游戏中音效的使用

🔥C++和OpenGL实现3D游戏编程【目录】 1、游戏中音效的使用 前面我们实现了图片纹理的显示功能,是不是感觉到非常的简单。那么今天我们就继续说下游戏声音的实现。音效也是游戏的灵魂,只有搭配了美妙动听的音效以后,游戏才能令人耳目一新,与玩家产生良好的效果。 音效文…...

Hive数仓操作(八)

一、Hive中的分桶表 1. 分桶表的概念 分桶表是Hive中一种用于提升查询效率的表类型。分桶指的是根据指定列的哈希值将数据划分到不同的文件(桶)中。 2. 分桶表的原理 哈希分桶:根据分桶列计算哈希值,对哈希值取模,将…...

【C++打怪之路Lv6】-- 内存管理

🌈 个人主页:白子寰 🔥 分类专栏:C打怪之路,python从入门到精通,数据结构,C语言,C语言题集👈 希望得到您的订阅和支持~ 💡 坚持创作博文(平均质量分82)&#…...

408知识点自检(二)

一、细节题 边界对齐长度是由什么决定的?64位计算机边界按几字节对齐?单周期cpu、多周期cpu、基本流水线cpu、超标量cpu的cpi分别是多少?中断的处理优先级和响应优先级分别由谁决定?动态分区管理需要用什么重定位方式&#xff1f…...

C语言复习概要(二)

本文目录 C语言中的数组与函数详解1. 引言2. 数组2.1. 什么是数组?语法:示例: 2.2. 数组的初始化示例 1:在声明时初始化示例 2:部分初始化示例 3:运行时赋值 2.3. 数组的访问与修改示例: 2.4. 多…...

小程序原生-利用setData()对不同类型的数据进行增删改

1. 声明和绑定数据 wxml文件 <view> {{school}} </view> <view>{{obj.name}}</view> <view id"{{id}}" > 绑定属性值 </view> <checkbox checked"{{isChecked}}"/> <!--算数运算--> <view>{{ id …...

.NET Core 集成 MiniProfiler性能分析工具

前言&#xff1a; 在日常开发中&#xff0c;应用程序的性能是我们需要关注的一个重点问题。当然我们有很多工具来分析程序性能&#xff1a;如&#xff1a;Zipkin等&#xff1b;但这些过于复杂&#xff0c;需要单独搭建。 MiniProfiler就是一款简单&#xff0c;但功能强大的应用…...

【JAVA开源】基于Vue和SpringBoot的旅游管理系统

本文项目编号 T 063 &#xff0c;文末自助获取源码 \color{red}{T063&#xff0c;文末自助获取源码} T063&#xff0c;文末自助获取源码 目录 一、系统介绍二、演示录屏三、启动教程四、功能截图五、文案资料5.1 选题背景5.2 国内外研究现状5.3 可行性分析5.4 用例设计 六、核…...

信息学奥赛一本通 1885:【14NOIP提高组】寻找道路 | 洛谷 P2296 [NOIP2014 提高组] 寻找道路

【题目链接】 洛谷 P2296 [NOIP2014 提高组] 寻找道路 ybt 1885&#xff1a;【14NOIP提高组】寻找道路 【题目考点】 1. 图论&#xff1a;广搜 2. 图论&#xff1a;反图 【解题思路】 设path数组&#xff0c;path[i]表示顶点i出发到终点t是否有路径。 先求path数组&#…...

JVM 基础、GC 算法与 JProfiler 监控工具详解

目录 1、引言 1.1 JVM内存与本地内存 1.2 JVM与JDK的关系 2、JVM基础 2.1 JVM&#xff08;Java Virtual Machine&#xff09; 2.2 Java与JVM的关系 2.3 JVM的内存结构 2.3.1 堆内存 2.3.2 栈内存 2.3.3 方法区 2.3.4 本地方法栈 2.3.5 程序计数器&#xff08;PC寄存…...

nodejs安装及环境配置

一、下载 进入官网https://nodejs.org/en/download/prebuilt-installer下载node.js安装包&#xff0c;选择对应版本的node&#xff0c;这里我选择的是14.21.3版本 二、安装 1、下载完成后&#xff0c;双击“node-v14.21.3-x64.msi”&#xff0c;开始安装Node.js 2、勾选复…...

无人机电力巡检:点亮电力巡检新视野!

一、无人机电力巡查的优势 提高巡检效率&#xff1a;无人机可以搭载高清摄像头、红外热像仪等先进设备&#xff0c;实时拍摄和传输图像&#xff0c;帮助巡检人员快速发现潜在问题&#xff0c;如电线破损、绝缘子污损、设备过热等&#xff0c;从而大大缩短了巡检周期。 降低人…...

详细介绍:API 和 SPI 的区别

文章目录 Java SPI (Service Provider Interface) 和 API (Application Programming Interface) 的区别详解目录1. 定义和目的1.1 API (Application Programming Interface)1.2 SPI (Service Provider Interface) 2. 使用场景2.1 API 的应用场景2.2 SPI 的应用场景 3. 加载和调…...

【面向对象】设计模式概念和分类

零.前提提要 本文章是我考中级软件设计师时的笔记&#xff0c;基本都是一些自己的思路和见解&#xff0c;现记录一下&#xff0c;希望可以帮助到即将考证的同学。 一.面向对象设计模式的概念 二.面向对象的设计模式分类 设计模式确定了所包含的类和实例、他们的角色和写作方式以…...

APK安装包arm64-v8a、armeabi-v7a、x86、x86_64如何区别?(2024年10月1日)

其实就是安卓CPU的进步史 安卓CPU类型: arm64-v8a: 第8代、64位ARM处理器&#xff0c;目前手机大多数是此架构(新手机&#xff0c;可以无脑选择)armeabiv-v7a: 第七代及以上的 ARM 处理器。2011年5月以后生产的大部分安卓设备都使用它armeabi: 第5代、第6代的ARM处理器&#…...

【DataLoom】智能问数 - 自然语言与数据库交互

探索DataLoom的智能问数功能&#xff1a;简化数据库查询 在数据驱动的决策制定中&#xff0c;数据库查询是获取洞察的关键步骤。但是&#xff0c;传统的数据库查询方法往往复杂且技术性强&#xff0c;这限制了非技术用户的使用。DataLoom的智能问数功能正是为了解决这一问题而…...

【Linux】进程地址空间(初步了解)

文章目录 1. 奇怪的现象2. 虚拟地址空间3. 关于页表4. 为什么要有虚拟地址 1. 奇怪的现象 我们先看一个现象&#xff1a; 为什么父子进程从“同一块地址中”读取到的值不一样呢&#xff1f; 因为这个地址不是物理内存的地址 &#xff0c;如果是物理内存的地址是绝对不可能出…...

从WWDC看苹果产品发展的规律

WWDC 是苹果公司一年一度面向全球开发者的盛会&#xff0c;其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具&#xff0c;对过去十年 WWDC 主题演讲内容进行了系统化分析&#xff0c;形成了这份…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

自然语言处理——Transformer

自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效&#xff0c;它能挖掘数据中的时序信息以及语义信息&#xff0c;但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN&#xff0c;但是…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

LeetCode - 199. 二叉树的右视图

题目 199. 二叉树的右视图 - 力扣&#xff08;LeetCode&#xff09; 思路 右视图是指从树的右侧看&#xff0c;对于每一层&#xff0c;只能看到该层最右边的节点。实现思路是&#xff1a; 使用深度优先搜索(DFS)按照"根-右-左"的顺序遍历树记录每个节点的深度对于…...

Selenium常用函数介绍

目录 一&#xff0c;元素定位 1.1 cssSeector 1.2 xpath 二&#xff0c;操作测试对象 三&#xff0c;窗口 3.1 案例 3.2 窗口切换 3.3 窗口大小 3.4 屏幕截图 3.5 关闭窗口 四&#xff0c;弹窗 五&#xff0c;等待 六&#xff0c;导航 七&#xff0c;文件上传 …...

Chrome 浏览器前端与客户端双向通信实战

Chrome 前端&#xff08;即页面 JS / Web UI&#xff09;与客户端&#xff08;C 后端&#xff09;的交互机制&#xff0c;是 Chromium 架构中非常核心的一环。下面我将按常见场景&#xff0c;从通道、流程、技术栈几个角度做一套完整的分析&#xff0c;特别适合你这种在分析和改…...

实战三:开发网页端界面完成黑白视频转为彩色视频

​一、需求描述 设计一个简单的视频上色应用&#xff0c;用户可以通过网页界面上传黑白视频&#xff0c;系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观&#xff0c;不需要了解技术细节。 效果图 ​二、实现思路 总体思路&#xff1a; 用户通过Gradio界面上…...

Linux中《基础IO》详细介绍

目录 理解"文件"狭义理解广义理解文件操作的归类认知系统角度文件类别 回顾C文件接口打开文件写文件读文件稍作修改&#xff0c;实现简单cat命令 输出信息到显示器&#xff0c;你有哪些方法stdin & stdout & stderr打开文件的方式 系统⽂件I/O⼀种传递标志位…...

ubuntu系统文件误删(/lib/x86_64-linux-gnu/libc.so.6)修复方案 [成功解决]

报错信息&#xff1a;libc.so.6: cannot open shared object file: No such file or directory&#xff1a; #ls, ln, sudo...命令都不能用 error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory重启后报错信息&…...