STM32 HAL库函数HAL_SPI_Receive_IT和HAL_SPI_Receive的区别

背景

前段时间开发一个按键板驱动,该板用的STM32F103系列单片机,前任工程师用STM32CubeMX生成的工程,里面全是HAL库调用,我接手后,学习了下HAL库的用法,踩坑不少,特别是带IT后缀的函数,初学者对其的理解很容易出错,特此记录一下。
按键板

项目中的按键板通过SPI总线与主板连接,按键板是Slave设备,因此无法确定什么时候收到主板的读写请求,要么轮询SPI控制器的rx fifo是否非空,要么依赖SPI控制器提供的中断机制,在中断里将rx fifo内容读出来。
带IT的receive

两种Receive流程

说明一下,SPI的BPW(bits per word)设置为8,因此文中一个word的size就是一个字节。

轮询:HAL_SPI_Receive流程

先看函数签名

HAL_StatusTypeDef HAL_SPI_Receive(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size, uint32_t Timeout);

hspi是SPI控制器句柄,pData是接收buf地址,Size是接收buf长度,Timeout是接收超时时间,如果期间一直没收到数据,则返回。

根据HAL源码,梳理流程概要:

获取控制器的锁
记录起始时间
填充控制器的各个字段:
控制器状态=BUSY_RX
接收buf地址=pData
接收buf长度=Size
RxISR = NULL
待接收字节数> 0?
rx fifo为空?
超时?
读取一个字节
待接收字节数-1
释放控制器的锁
返回错误码

注意,RxISR表示接收中断的回调函数,因为我们是轮询模式,所以该字段填0。

中断:HAL_SPI_Receive_IT流程

先看函数签名

HAL_StatusTypeDef HAL_SPI_Receive_IT(SPI_HandleTypeDef *hspi, uint8_t *pData, uint16_t Size);
void HAL_SPI_ErrorCallback(SPI_HandleTypeDef *hspi);
void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi);

参数含义跟HAL_SPI_Receive一样,少了个超时参数,因为中断方式并不轮询rx fifo是否非空,而是收到rx fifo非空中断后才去读取,不会让CPU无谓等待。

根据HAL源码,梳理流程概要:

HAL_SPI_Receive_IT
填充控制器的各个字段:
控制器状态=BUSY_RX
接收buf地址=pData
接收buf长度=Size
RxISR = SPI_RxISR_8BIT
获取控制器的锁
开启rx_fifo非空和rx_error中断
释放控制器的锁
HAL_SPI_IRQHandler
溢出中断置位?
获取中断使能和中断状态
禁用所有中断
HAL_SPI_ErrorCallback
rx fifo非空中断置位?
SPI_RxISR_8BIT
退出中断
SPI_RxISR_8BIT
待接收字节数-1
将FIFO的第一个字节拷贝到pData
待接收字节数== 0?
SPI_CloseRx_ISR
退出函数
SPI_CloseRx_ISR
控制器的错误码为NONE?
禁用rx_fifo非空和rx_error中断
用户定义的HAL_SPI_RxCpltCallback
用户定义的HAL_SPI_ErrorCallback
退出函数

注意:

  1. 每个字节的接收都会触发一次中断,因为所谓的rx fifo并不存在,其实就是直接读取控制器的DR寄存器(暂存当前收到的word),如果想提高效率,可以使用DMA版本。
  2. HAL_SPI_Receive_IT运行在后台(主循环),HAL_SPI_IRQHandler以及它调用的其他函数都运行在前台(中断),因此后者代码里一定不能有printf之类的打印语句,否则会影响SPI接收时序!

对比

可以看出,带IT后缀的receive函数,只填充控制器的上下文结构体并开启中断,剩下的都交给中断回调。这种策略将接收分成前后台两部分,后台开启中断,前台响应中断并读取数据,检测数据收够了就关闭中断,因此带IT后缀并不是传言的只能在中断态下运行。

后记

  1. HAL库其他总线,像UART、I2C等,它们的带IT后缀的receive函数,应该也是这种设计模式,大家可以验证一下。
  2. rx_fifo非空中断到底是片选信号触发的,还是SCK信号触发的,不太确定,看过芯片TRM手册,好像是SCK触发的,知道的帮忙确认下。

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

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

相关文章

R语言实现多变量孟德尔随机化分析(1)

多变量孟德尔随机化分析调整了潜在混杂因素的影响。 1、调整哪些因素?参考以往文献。可以分别调整,也可以一起调整。 2、解决了什么问题?某个暴露相关的SNP,往往与某个或者某几个混杂因素相关。可以控制混杂偏倚。 3、如何解释…

AI从入门到精通,什么是LLMs大型语言模型?

大型语言模型是指由大量文本数据训练而成的自然语言处理模型,它可以生成高质量的文本内容,并能够理解和回答人类提出的问题。 这种模型通常基于深度学习技术,如循环神经网络(RNN)或变换器(Transformer&…

【左程云算法全讲11】贪心算法 并查集

系列综述: 💞目的:本系列是个人整理为了秋招面试的,整理期间苛求每个知识点,平衡理解简易度与深入程度。 🥰来源:材料主要源于左程云算法课程进行的,每个知识点的修正和深入主要参考…

电子电器架构 —— 车载网关边缘节点总线转换

电子电器架构 —— 车载网关边缘节点路由转发策略 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 PS:小细节,本文字数3000+,详细描述了网关在车载框架中的具体性能设置。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 没有人关注你。也无…

Java枚举

在Java中,枚举(Enumeration)是一种特殊的数据类型,用于表示一组常量。Java 5及以上版本引入了枚举类型(Enum Type),通过关键字 enum 来定义。 以下是关于Java枚举的一些基本概念和用法&#xf…

Django(八、如何开启事务、介绍长见的字段类型和参数)

文章目录 ORM事务操作开启事务 常见的字段类型和参数ORM还支持用户自定义字段类型ORM常用字段参数外键相关参数 ORM事务操作 引入事务 1.事务的四大特性原子性、一致性、隔离性、持久性 2.相关SQL关键字start transaction;rollback;commit;savapoint; 3.相关重要概念脏读、幻…

系列十、你说你做过JVM调优和参数配置,请问如何盘点JVM系统的默认值?

一、JVM的参数类型 1.1、标配参数 java -versionjava -help 1.2、XX参数 1.2.1、Boolean类型 公式:-XX:或者- 某个属性值 表示开启、-表示关闭 # 是否打印GC收集细节 -XX:PrintGCDetails -XX:-PrintGCDetails# 是否使用串行垃圾收集器 -XX:UseSerialGC -XX:-UseS…

使用FFmpeg合并多个ts视频文件转为mp4格式

前言 爬取完视频发现都是ts文件,而且都是几百KB的视频片段,.ts 全名叫:MPEG Transport Stream,它是一个万能的多媒体容器,可以装下音频、视频、字幕。有时我们需要将.ts文件转换为其他更加广泛被支持的格式&#xff0…

springboot项目中没有识别到yml文件解决办法

springboot项目中没有识别到yml文件解决办法 ![外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传] 1、这个意思就是没有配置数据库的数据源路径。所以需要配置数据源,比如mysql的驱动和路径。检查是否在properties或者yml文件中是否已经配置好。…

简单的用Python实现一下,采集某牙视频,多个视频翻页下载

前言 表弟自从学会了Python,每天一回家就搁那爬视频,不知道的以为是在学习,结果我昨天好奇看了一眼,好家伙,在那爬某牙舞蹈区,太过分了! 为了防止表弟做坏事,我连忙找了个凳子坐下&…

图像分类(四) 全面解读复现GoogleNet_InceptionV1-V4

论文解读 InceptionV1 前言 论文题目: Going Deeper with Convolutions Googlenet论文原文地址:https://arxiv.org/pdf/1409.4842.pdf 之前看过VGG的论文(VGG精读直达)。当时VGG获得了 2014 ILSVRC 图像分类的第二名,今天来看一下第一名…

Yolov5

Yolov5 Anchor 1.Anchor是啥? anchor字面意思是锚,是个把船固定的东东(上图),anchor在计算机视觉中有锚点或锚框,目标检测中常出现的anchor box是锚框,表示固定的参考框…

Mysql 三种不使用索引的情况

目录 1. 查询语句中使用LIKE关键字 例 1 2. 查询语句中使用多列索引 例 2 3. 查询语句中使用OR关键字 例 3 总结 索引可以提高查询的速度,但并不是使用带有索引的字段查询时,索引都会起作用。使用索引有几种特殊情况,在这些情况下&…

CSS-表格属性(1)

边框相关属性(其他元素也能用): 属性名:border-style功能:边框风格可选值: 1.none 默认值(无边框) 2.solid 实线 3.dashed 虚线 4.dotted 点线 5.double 双实线 border-style: dashed; 属性名&#xff1a…

基于金鹰算法优化概率神经网络PNN的分类预测 - 附代码

基于金鹰算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于金鹰算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于金鹰优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要:针对PNN神经网络的光滑…

使用Qt实现多人聊天工作室

目录 1、项目背景 2、技术分析 3、架构设计 3、1 服务器架构 3.1.1 模块划分 3.1.2 模块之间的交互 3、2 客户端架构 3.2.1 模块划分 3.2.2 模块之间交互 4、实现过程 4、1 功能实现 4.1.1 用户登录注册功能​编辑 4.1.2 用户主界面功能 4、2 设计实现 4.2.1 登录…

关于Flume-Kafka-Flume的模式进行数据采集操作

测试是否连接成功: 在主节点flume目录下输入命令: bin/flume-ng agent -n a1 -c conf/ -f job/file_to_kafka.conf -Dflume.root.loggerinfo,console # 这个file_to_kafka.conf文件就是我们的配置文件 然后在另一台节点输入命令进行消费数据: kafka-cons…

核—幂零分解

若向量空间 V \mathcal V V存在子空间 X \mathcal X X与 Y \mathcal Y Y,当 X Y V X ∩ Y 0 \mathcal {X\text{}Y\text{}V}\\ \mathcal {X}\cap \mathcal {Y}0 XYVX∩Y0 时称子空间 X \mathcal X X与 Y \mathcal Y Y是完备的,其中记为 X ⊕ Y V \ma…

SQL INSERT INTO 语句详解:插入新记录、多行插入和自增字段

SQL INSERT INTO 语句用于在表中插入新记录。 INSERT INTO 语法 可以以两种方式编写INSERT INTO语句: 指定要插入的列名和值: INSERT INTO 表名 (列1, 列2, 列3, ...) VALUES (值1, 值2, 值3, ...);如果要为表的所有列添加值,则无需在SQL…

每日OJ题_算法_双指针_力扣283. 移动零+力扣1089. 复写零

力扣283. 移动零 283. 移动零 - 力扣(LeetCode) 难度 简单 给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。 请注意 ,必须在不复制数组的情况下原地对数组进行操作。 示例…