STM32作为SPI slave与主机异步通信

背景

最近被测试提了个BUG,说某款产品在用户按下前面板的按键后,对应的按键灯没有亮起来。前面板跟主机是通过SPI口通信,前面板是从机,从机想要主动发送消息,需要通过GPIO中断来通知主机
前面板到主机的SPI和GPIO信号
上图前面板是STM32(没有RTOS),主机是RK3588平台,INT是GPIO管脚,CS、MISO、MOSI是SPI标准信号。

整个通信过程是异步的:

前面板 主机 检测到用户按下了hold键 发送SPI请求:用户按下了hold键 主机App要求点亮hold键和numeric键的按键灯 接收SPI命令:点亮hold键和numeric键的按键灯 点亮hold键和numeric键的按键灯 前面板 主机

hold键示例的视频:

按键按下到按键灯亮起

思路

因为前面板是从机,它不知道主机什么时候会发消息,因此需要一直监听SPI总线,等待主机的command。另一方面,它也不知道用户什么时候会按下按键,因此需要一直扫描按键接口,并在检测到按键活动后尽快向SPI总线发送消息,即request,这两种事件对于STM32来说,都是异步的。

SPI总线虽然是双向通信的,但是仅限同步收发(UART是异步收发)。换句话说,尽管STM32发送request的同时可以接收command,但这两种消息的信源(用户和app)却不是同步的,因此不能调用HAL_SPI_TransmitReceive_DMA等双向API来通信,只能分别调用HAL_SPI_Transmit_DMAHAL_SPI_Receive_DMA来模拟异步通信。

解决方法

为了清晰,用流程图来描述:

SPI发送完成中断
SPI接收完成中断
主循环
全局初始化
进入中断
退出中断
进入中断
退出中断
扫描按键
用户按下某个按键
调用HAL_SPI_Abort中止当前的SPI接收
调用HAL_SPI_Transmit_DMA发送request
处理收到的各种SPI command
HAL库、时钟、GPIO、DMA、SPI、TIM初始化
调用HAL_SPI_Receive_DMA接收command

注意事项:

  1. 进入主循环前先启动SPI接收,然后在接收完成中断里再次启动接收,即恢复到监听下一个command的状态。
  2. STM32绝大部分时间都在监听并执行主机发来的command,仅在用户按下按键时才发送request
  3. 发送request前,必须先abort掉当前的SPI接收流程(SPI同步通信模式的限制)
  4. 最好给command和request分别开辟一个队列,接收中断将command入队,主循环将command出队;主循环发送request前将其入队,发送完成中断将其出队。这样做的好处是可以容纳不同类型、不同时间点的request(按键、旋钮、command的response等),以及不同类型、不同时间点的command(LED点亮命令、蜂鸣器开关命令、固件版本查询命令等)。

可能存在的问题

按照上述思路写完代码后,发现只要用户有按键行为,按键灯就仍然点不亮,从串口打印来看,是接收到的command出现了掐头或去尾的现象。

分析是SPI内部的FIFO没有正确清空,网上搜了下,这篇文章分析得比较到位,我在评论区找到了解决办法,贴出来:

void reset_spi1(void)
{__HAL_RCC_SPI1_FORCE_RESET();__HAL_RCC_SPI1_RELEASE_RESET();MX_SPI1_Init();
}

在每次启动接收前都调一下上面的代码,就可能清空FIFO。经测试,SPI没有再出现掐头去尾的现象。

总结

如果应用场景是双向异步通信,且是系统拓扑是点到点,就别选SPI了,UART更好。

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

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

相关文章

阿里云不杀熟,云服务器优惠价格99元一年,新老用户均可购买

2024阿里云服务器优惠活动政策整理,阿里云99计划ECS云服务器2核2G3M带宽99元一年、2核4G5M优惠价格199元一年,轻量应用服务器2核2G3M服务器61元一年、2核4G4M带宽165元1年,云服务器4核16G10M带宽26元1个月、149元半年,云服务器8核…

14 程序地址空间

背景 kernel 2.6.32 32位平台 空间布局图 如何理解地址划分 地址划分,本质是调整地址空间的定义start和end,内存中定义了管理每个区域范围的结构体,叫mm_struct,每个进程都有一个这个结构体指针变量 验证上面划分的结构&#…

十四经脉最全总结(什么是经脉、十二经脉动态图、经脉走向、人体和手足哪面为阳,哪面为阴?)

目录 一.什么是经脉二.人体和手足哪面为阳?哪面为阴?三.任督二脉3.1 任脉3.2 督脉 四.十二经脉4.1 什么是 厥阴,少阴,太阴;少阳,阳明,太阳?4.2 十二经脉总分布4.3 手三阴经1.手厥阴心…

4、pod运维replicationCtroller、replicaSet、DeamonSet、Job、Cronjob

1、kubenetes 会自动重新运行失败的pod应用 pod运行失败,会自动重启,但是节点失败,pod会被移除, 除非配置了relicationController来管理资源 2、保持pod的健康存活 配置探针,发送http请求 3、查看前一个pod的运行日…

mysql-视图,创建表,存储过程,循环,判断实操命令

数据库操作命令在IDEA工具database的console命令 数据库表结构与视图 -- 查询隔离级别 select transaction_isolation;-- 设置隔离级别 set session transaction isolation level read committed ; set session transaction isolation level REPEATABLE READ ;start transacti…

蚂蚁感冒c++

题目 思路 “两蚂蚁碰面会掉头,若其中一只蚂蚁感冒了,会把感冒传染给碰到的蚂蚁”,这句话看作是“两蚂蚁碰面会互相穿过,只是把感冒的状态传给了另一只蚂蚁”,因为哪只蚂蚁感冒了并不是题目的重点,重点是有…

如何在Word里一次性给全部汉字加拼音?

word是大家日常使用频率较高的工作软件,功能性很强,有上乘的文档格式设置工具,利用它可更轻松、高效地组织和编写文档,熟练运用word,在职场上很重要。那么word如何添加拼音呢?下面给大家介绍一下吧。 方法一&#xf…

线性dp P4310-绝世好题/P4933 大师【日记】

1.绝世好题(P4310) 绝世好题https://www.luogu.com.cn/problem/P4310 比较考验思维的一道题目,码量和理解难度都不大,重在思维。 一开始看错题,以为是求子串(还在想为啥考的纯位运算枚举,whe…

vue iis 配置

下载安装两个IIS模块 1). 传送门:URL Rewrite 2). 传送门:Application Request Routing 注 : 只有在 服务器的主页 有Application Request Routing 部署VUE网站 生成网站 在VUE项目打包生成出发布文件,即文件夹 dist,此处忽略 复制到你需要存放网站的…

Skywalking官方的实战模拟项目Live-Demo

Skywalking 官方的实战模拟项目Live-Demo Live-Demo 是 Skywalking 官方的实战模拟项目,其中包含4个子模块项目 projectA访问projectB、projectC两个SpringBoot项目 projectB访问本地的H2数据库 projectC访问www.baidu.com并同时向一台Kafka消息队列写入数据 proje…

入门指南:使用uni-app构建跨平台应用

入门指南:使用uni-app构建跨平台应用 🌟 前言 欢迎来到我的小天地,这里是我记录技术点滴、分享学习心得的地方。📚 🛠️ 技能清单 编程语言:Java、C、C、Python、Go前端技术:Jquery、Vue.js、R…

六、软考-系统架构设计师笔记-软件工程基础知识

1、软件工程 软件工程是将系统化的、严格约束的、可量化的方法应用于软件的开发、运行和维护,即将工程化应用于软件并对上述方法的研究。 软件要经历从需求分析、软件设计、软件开发、运行维护,直至被淘汰这样的全过程,这个过程称为软件的生…

Android使用OpenGL和FreeType绘制文字

Open GL主要是渲染图形的,有时候需要绘制文字,网上搜了一下,基本思路都是把文字转成位图,再使用Open GL纹理进行渲染。加载纹理在特定阶段才能成功(在onSurfaceCreated中加载),这样就无法动态的…

部署LVS负载均衡架构

目录 一、ipvsadm 工具 二、NAT模式下部署LVS负载均衡 1、部署NFS共享存储服务器 1.1 安装NFS软件 1.2 新建共享目录和站点文件 1.3 设置共享策略 2、部署节点服务器1 2.1 安装并启动nginx软件 2.2 挂载共享目录到网页站点目录 2.3 修改网关 3、部署节点服务器2 3.…

在ABAP中创建一个简单的守护进程

原文地址:Create a simple Daemon in ABAP 目录 一、ABAP语言中的守护进程是什么?二、ABAP 守护进程框架 (ADF)三、ABAP 守护进程类四、创建一个简单的ABAP守护进程步骤1:创建一个新的ABAP Daemon类步骤2:实现ON_ACCEPT方法第三步…

「滚雪球学Java」:GUI编程(章节汇总)

咦咦咦,各位小可爱,我是你们的好伙伴——bug菌,今天又来给大家普及Java SE相关知识点了,别躲起来啊,听我讲干货还不快点赞,赞多了我就有动力讲得更嗨啦!所以呀,养成先点赞后阅读的好…

Kosmos-1: 通用接口架构下的多模态大语言模型

Kosmos-1: 通用接口架构下的多模态大语言模型 FesianXu 20230513 at Baidu Search Team 前言 在大规模语言模型(Large Language Model, LLM)看似要带来新一番人工智能变革浪潮之际,越来越多尝试以LLM作为通用接口去融入各种任务的工作&#…

【vue】ant-design弹出框无法关闭和runtimecore提示isFucntion is not function的问题修复

【vue】ant-design弹出框无法关闭和runtimecore提示isFucntion is not function的问题修复,初步分析是vue发布3.4版本以后引起的兼容性问题。 问题截图: 1.isFucntion is not function,是由于vue升级后众多插件版本不匹配造成的问题 2.弹框…

计算机中msvcp140.dll,丢失怎么修复与解决

一、msvcp140.dll20个软件环境 msvcp140.dll文件是许多软件运行环境的组成部分,通常与Microsoft Visual C Redistributable关联。以下是可能使用该文件的软件环境: 微软办公软件:如Microsoft Office套件,包括Word、Excel、Power…

Python给图片加水印

受到“手动给证件加文字太麻烦”的感触,想用Python来实现给图片加水印,这不方便多了。 这里使用PIL模块: from PIL import Image from PIL import ImageFont from PIL import ImageDrawimg_t Image.open(cat.jpg) img_size_t img_t.size…