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_Receive_DMA接收command
扫描按键
处理SPI command,点亮LED
用户按下某个按键
调用HAL_SPI_Abort中止当前的SPI接收
调用HAL_SPI_Transmit_DMA发送request

注意事项:

  1. STM32绝大部分时间都在监听并执行主机发来的command,仅在用户按下按键时才发送request
  2. 发送request前,必须先abort掉当前的SPI接收流程(SPI同步通信模式的限制)
  3. STM没有Linux那种用户态和内核态的说法,因此在中断里也可以再次启动SPI接收流程,即恢复到监听下一个command的状态。
  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.hqwc.cn/news/505634.html

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

相关文章

小程序图形:echarts-weixin 入门使用

去官网下载整个项目: https://github.com/ecomfe/echarts-for-weixin 拷贝ec-canvs文件夹到小程序里面 index.js里面的写法 import * as echarts from "../../components/ec-canvas/echarts" const app getApp(); function initChart(canvas, width, h…

WEB漏洞 SSRF简单入门实践

一、漏洞原理 SSRF 服务端请求伪造 原理:在某些网站中提供了从其他服务器获取数据的功能,攻击者能通过构造恶意的URL参数,恶意利用后可作为代理攻击远程或本地的服务器。 二、SSRF的利用 1.对目标外网、内网进行端口扫描。 2.攻击内网或本地的…

复试PAT乙级day34

1111~1115 1113 很难,看了题解 人类习惯用 10 进制,可能因为大多数人类有 10 根手指头,可以用于计数。这个世界上有一种叫“钱串子”(学名“蚰蜒”)的生物,有 30 只细长的手/脚,在它们的世界里…

实践航拍小目标检测,基于YOLOv8全系列【n/s/m/l/x】参数模型开发构建无人机航拍场景下的小目标检测识别分析系统

关于无人机相关的场景在我们之前的博文也有一些比较早期的实践,感兴趣的话可以自行移步阅读即可: 《deepLabV3Plus实现无人机航拍目标分割识别系统》 《基于目标检测的无人机航拍场景下小目标检测实践》 《助力环保河道水质监测,基于yolov…

在网页上踢球:打造我自己的python(Django)足球网站

足球不仅仅是球场上的90分钟。它是一个不断发展的故事,一个全球球迷社群的粘合剂,一个数据和热情交织的世界。作为一名开发者和球迷,我决定将这两大爱好结合起来,用 Django 打造一个足球网站,让球迷们能够追踪他们最爱…

电脑数据丢失是什么原因 易我数据恢复软件下载 easyrecovery数据恢复软件下载 电脑数据删除了怎么恢复 电脑数据库损坏了怎么找回

目录 一、电脑数据丢失是什么原因 二、电脑数据丢失如何恢复 三、EasyRecovery恢复电脑数据的方法介绍 电脑是我们大家熟悉并且常用的数据存储设备,也是综合性非常强的数据处理设备。对于电脑设备来讲,最主要的数据存储介质是硬盘,电脑硬…

学习:吴恩达:什么是神经元?神经网络如何工作?

学习-吴恩达《AI for everyone》2019 深度学习非技术解释 第2部分 可选.zh_哔哩哔哩_bilibili 深度学习Deep learning 人工神经网络Artificial Neural network 什么是神经网络? 只有一个神经元 4个神经元的神经网络 神经网路的绝妙之处 神经网路的绝妙之处就在…

vscode如何远程到linux python venv虚拟环境开发?(python虚拟环境、vscode远程开发、vscode远程连接)

文章目录 1. 安装VSCode2. 安装扩展插件3. 配置SSH连接4. 输入用户名和密码5. 打开远程文件夹6. 创建/选择Python虚拟环境7. 安装Python插件 Visual Studio Code (VSCode) 提供了一种称为 Remote Development 的功能,允许用户在远程系统、容器或甚至 Windows 子系统…

【k8s管理--集群日志管理elk】

1、ELKF日志部署框架 使用docker部署的k8s集群所有的容器日志统一都在目录:/var/log/containers/1、filebeat是一个轻量级的日志手机工具,主要功能是收集日志2、logstash通可以收集日志,也可以进行数据清洗,但是一般不用logstash来…

YOLOv5论文作图教程(3)— 关于论文作图教程系列采用线上培训的通知(终结篇)

前言:Hello大家好,我是小哥谈。YOLOv5论文作图教程系列其实是我特别擅长的一个模块(本人产品经理出身),自从本系列发表了两篇文章之后,一直没有再继续更新,主要原因是通过文字无法比较好的表达软件的功能及使用,并且也无法达到比较好的培训效果。为了确保大家可以彻底掌…

StarRocks实战——首汽约车实时数仓实践

目录 前言 一、引入背景 二、OLAP引擎选型 三、架构演进 四、实时数仓构建 五、业务实践价值未来规划 原文大佬的这篇首汽约车实时数仓实践有借鉴意义,这里摘抄下来用作学习和知识沉淀。 前言 首汽约车(以下简称“首约”)是首汽集团打造…

javaWebssh在线授课辅导系统myeclipse开发mysql数据库MVC模式java编程计算机网页设计

一、源码特点 java ssh在线授课辅导系统是一套完善的web设计系统(系统采用ssh框架进行设计开发),对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用 B/S模式开发。开发环境为TOMCAT7.…