工程文件参考——CubeMX+LL库+SPI主机 阻塞式通用库

文章目录

  • 前言
  • CubeMX配置
  • SPI驱动实现
    • spi_driver.h
    • spi_driver.c
  • 额外的接口补充


前言

SPI,想了很久没想明白其DMA或者IT比较好用的方法,可能之后也会写一个
我个人使用场景大数据流不多,如果是大批量数据交互自然是DMA更好用,但考虑到多从机通讯,感觉还是阻塞式更灵活一些,毕竟大部分通讯片选延时1us,但一个数据传进去也就不到1us。
以后有时间改个DMA或者IT升级版

spix = new_SPI_Driver(SPIx_Port, CS_GPIOx, CS_Pin);//完成初始化
RxData = spix->tr16(spix, TxData);//数据传递
spix->cs_l(spix);;//CS拉低
spix->cs_h(spix);;//CS拉搞

SPI的多从机任务可以自己挂CS,并在上层实现数据流读取
上层实现可以参考工程文件参考——ADS1118多从机驱动(base on spi_driver)
需要8位传输的可以自己改


CubeMX配置

开了就能用,注意匹配下,数据长度,8bit还是16bit。MSB是先高位还是先低位,以及CPOL与CPHA的设置。NSS硬件片选没什么用,包括从机的NSS,感觉不如外部触发中断。
在这里插入图片描述
CS直接开GPIO,根据自己从机数量需求设计
在这里插入图片描述

SPI驱动实现

spi_driver.h

/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __SPI_DRIVER_H
#define __SPI_DRIVER_H
/* =================================================================================
File name:       __SPI_DRIVER_H
Author: Mr.NoFish
===================================================================================*/#ifdef __cplusplus
extern "C" {
#endif/* Includes ------------------------------------------------------------------*/#include "main.h"#include "spi.h"typedef struct SPI_Driver_ SPI_Driver;typedef void (*SPIfptrCS_H)(SPI_Driver*);
typedef void (*SPIfptrCS_L)(SPI_Driver*);
typedef uint16_t (*SPIfptrTranRecv16)(SPI_Driver*, uint16_t);
typedef void (*SPIfptrTran16)(SPI_Driver*, uint16_t);struct SPI_Driver_
{SPI_TypeDef* SPIx;GPIO_TypeDef* CS_GPIOx;uint32_t CS_Pin;uint16_t TxData;uint16_t RxData;SPIfptrCS_H cs_h;SPIfptrCS_L cs_l;SPIfptrTranRecv16 tr16;SPIfptrTran16 tran16;
};SPI_Driver* new_SPI_Driver(SPI_TypeDef* SPIx_Port, GPIO_TypeDef* CS_GPIOx, uint32_t CS_Pin);void spi_chip_select_set(SPI_Driver* const pSPIObj);
void spi_chip_select_reset(SPI_Driver* const pSPIObj);
void spi_transmit_16(SPI_Driver* const pSPIObj, uint16_t TxData);
uint16_t spi_transmit_receive_16(SPI_Driver* const pSPIObj, uint16_t TxData);
#endif

spi_driver.c

/* =================================================================================
File name:       __SPI_DRIVER_C
Author: Mr.NoFish
===================================================================================*/
#include "spi_driver.h"SPI_Driver* new_SPI_Driver(SPI_TypeDef* SPIx_Port, GPIO_TypeDef* CS_GPIOx, uint32_t CS_Pin)
{SPI_Driver* pObj = NULL;uint8_t i = 0;pObj = (SPI_Driver*)malloc(sizeof(SPI_Driver));if (pObj == NULL){printf("WARN: SPI_Driver initialization failed.\r\n");return NULL;}pObj->SPIx = SPIx_Port;pObj->CS_GPIOx = CS_GPIOx;pObj->CS_Pin = CS_Pin;pObj->cs_h = spi_chip_select_set;pObj->cs_l = spi_chip_select_reset;pObj->tran16 = spi_transmit_16;pObj->tr16 = spi_transmit_receive_16;pObj->cs_h(pObj);//LL_SPI_Enable(pObj->SPIx);printf("INFO: SPI_Driver initialization succeeded.\r\n");return pObj;			
}void spi_chip_select_set(SPI_Driver* const pSPIObj)
{LL_GPIO_SetOutputPin(pSPIObj->CS_GPIOx, pSPIObj->CS_Pin);
}void spi_chip_select_reset(SPI_Driver* const pSPIObj)
{LL_GPIO_ResetOutputPin(pSPIObj->CS_GPIOx, pSPIObj->CS_Pin);
}void spi_transmit_16(SPI_Driver* const pSPIObj, uint16_t TxData)
{	pSPIObj->TxData = TxData;while(!LL_SPI_IsActiveFlag_TXE(pSPIObj->SPIx));LL_SPI_TransmitData16(pSPIObj->SPIx, pSPIObj->TxData);
}uint16_t spi_transmit_receive_16(SPI_Driver* const pSPIObj, uint16_t TxData)
{	pSPIObj->TxData = TxData;while(!LL_SPI_IsActiveFlag_TXE(pSPIObj->SPIx));LL_SPI_TransmitData16(pSPIObj->SPIx, pSPIObj->TxData);while(LL_SPI_IsActiveFlag_BSY(pSPIObj->SPIx));while(!LL_SPI_IsActiveFlag_RXNE(pSPIObj->SPIx));pSPIObj->RxData =  LL_SPI_ReceiveData16(pSPIObj->SPIx);return pSPIObj->RxData;
}

额外的接口补充

LL_SPI_Enable(SPIx);别忘记自己加一下,但留意别在初始化之前Enable。
SPI每个设备的实现方式都不同,所以需要根据数据手册进一步实现上层设计。
这个库设计用来提供给多从机控制,一些范例的应用可以参考如下文章。
工程文件参考——ADS1118多从机驱动(base on spi_driver)

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

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

相关文章

reggie外卖优化

文章目录 一、redis缓存1.1 缓存验证码1.2 缓存菜品数据 二、spring-cache 一、redis缓存 1.1 缓存验证码 不用sesiion,而使用redis来存放验证码。 首先在用户请求验证码,将验证码保存在sesion中,当登录成功之后,将redis中的验证…

Tekla Structures钢结构详图设计软件下载;Tekla Structures高效、准确的合作平台

Tekla Structures,它不仅集成了先进的三维建模技术,还融入了丰富的工程实践经验,为设计师、工程师和建筑商提供了一个高效、准确的合作平台。 在建筑项目的整个生命周期中,Tekla Structures都发挥着举足轻重的作用。从规划阶段开始…

Java Map转泛型对象

Springboot Map转泛型对象 import org.springframework.beans.PropertyAccessorFactory;public abstract class AbstractGoodsProcessor<T>{/*** 封装对象**/Overridepublic T assembleOfBeforeCheck(Map<String, Object> map){return this.mapToParam(map,0);};O…

录音转文字软件免费版哪个好?6个转文字工具让你轻松记录

随着小暑的到来&#xff0c;炎热的天气容易让人心浮气躁&#xff0c;影响工作效率。 在这个季节里&#xff0c;掌握一些办公技巧尤为关键。尤其是当我们需要整理会议记录或讲座内容时&#xff0c;如果能有一种方法&#xff0c;可以迅速将那些冗长的录音转换成清晰的文字&#…

使用Retrofit2+OkHttp监听上传或者下载进度会执行两次的问题

使用Retrofit2OkHttp监听上传或者下载进度RequestBody#writeTo/ResponseBody#source 会执行两次的问题 example&#xff1a; 问题原因&#xff1a; 使用了HttpLoggingInterceptor拦截器&#xff0c;并且日志等级为HttpLoggingInterceptor.Level.BODY 问题解决&#xff1a;

day08. 02 Python中的位运算符案例与解析

理解并掌握Python中的位运算符&#xff1a;异或&#xff08;^&#xff09;、与&#xff08;&&#xff09;、或&#xff08;|&#xff09;、反&#xff08;~&#xff09;、右移&#xff08;>>&#xff09;、无符号右移&#xff08;>>>&#xff0c;注意Python…

艾滋病隐球菌病的病原学诊断方法包括?

艾滋病隐球菌病的病原学诊断方法包括()查看答案 A.培养B.隐球菌抗原C.墨汁染色D.PCR 在感染性疾病研究中&#xff0c;单细胞转录组学的应用包括哪些()? A.细胞异质性研究B.基因组突变检测C.感染过程单细胞分析D.代谢通路分析 开展病原微生物网络实验室体系建设&#xff0c;应通…

Linux--平台设备、平台驱动的注册源码分析

一、设备和驱动的注册 设备注册两种方式&#xff1a; 1、从设备树解析动态注册。设备树dts文件中定义了设备节点&#xff0c;描述了硬件信息&#xff0c;比如寄存器信息&#xff0c;引脚信息等&#xff0c;内核将从设备树中解析得到的platform_device注册到平台总线中。具体设…

一个opencv实现检测程序

引言 图像处理是计算机视觉中的一个重要领域&#xff0c;它在许多应用中扮演着关键角色&#xff0c;如自动驾驶、医疗图像分析和人脸识别等。边缘检测是图像处理中的基本任务之一&#xff0c;它用于识别图像中的显著边界。本文将通过一个基于 Python 和 OpenCV 的示例程序&…

UniApp 中 Web/H5 正确使用反向代理解决跨域问题

因为 Vue3 的构建工具是 Vite&#xff0c;所以配置 vue.config.js 是没用的&#xff08;Vue2 因为使用 webpack 所以才用这个文件&#xff09; 这里提供一份 vue.config.js 的示例&#xff1a; module.exports {devServer: {proxy: {/api: {target: http://example.com,chan…

Python学习速成必备知识,(20道练习题)!

基础题练习 1、打印出1-100之间的所有偶数&#xff1a; for num in range(1, 101):if num % 2 0:print(num) 2、打印出用户输入的字符串的长度&#xff1a; string input("请输入一个字符串&#xff1a;")print("字符串的长度为&#xff1a;", len(str…

使用Python进行文件合并和分割

哈喽,大家好,我是木头左! 引言 在数据处理过程中,经常需要将多个文件合并为一个文件,或者将一个大文件分割成多个小文件。Python作为一种功能强大的编程语言,提供了多种方法来实现这一目标。本文将介绍如何使用Python进行文件合并和分割。 文件合并 1. 逐行合并 最简…

Git不想跟踪某个文件

如果你不想跟踪某个文件&#xff0c;可以将该文件路径添加到 .gitignore 文件中。.gitignore 文件用于告诉 Git 哪些文件或目录应该被忽略&#xff0c;不进行版本控制。以下是具体步骤&#xff1a; 编辑 .gitignore 文件&#xff1a;在项目的根目录下找到或创建一个 .gitignore…

More Effective C++ 35个改善编程与设计的有效方法笔记与心得 5

五. 技术 条款25&#xff1a; 将 constructor 和 non-member functions虚化 请记住&#xff1a; 1. 利用重载技术&#xff08;overload&#xff09;避免隐式类型转换&#xff08;implicit type conversions&#xff09; ‌‌‌‌  重载技术是指在同一个作用域中声明多个同…

差分进化算法(Differential Evolution)及其python实现

### 背景&#xff1a; 差分进化算法&#xff08;Differential Evolution&#xff0c;DE&#xff09;是一种基于种群的优化算法&#xff0c;旨在解决连续优化问题。DE 最初由 Price 和 Storn 提出&#xff0c;是一种简单但有效的全局优化算法&#xff0c;适用于具有非线性、非光…

rillflow运行时,跳转子应用时,页面循环自动刷新

rill-flow-ui执行运行完毕&#xff0c;生成如下运行url&#xff0c;http://110.108.190.18:8080/选中执行&#xff0c;跳转子应用循环自动刷新&#xff0c;debugger发现主应用在和微应用的默认地址建立链接失败&#xff0c; 改为运行 http://localhost:8080/&#xff0c;即可和…

excel表格如何换行,这几个操作方法要收藏好

Excel表格作为一款强大的数据处理工具&#xff0c;在日常工作和生活中被广泛应用。当需要在单元格内显示较长的文本内容或使数据更加清晰易读时&#xff0c;我们需要掌握一些换行技巧。下面将介绍几种常用的Excel换行方法&#xff1a; 一、使用快捷键换行 1、首先&#xff0c;…

iSDF改进优化笔记

《iSDF: Real-Time Neural Signed Distance Fields for Robot Perception》论文提出了一种实时神经签名距离场&#xff08;SDF&#xff09;重建的方法&#xff0c;该方法在多个方面表现优异。然而&#xff0c;仍有一些潜在的改进空间&#xff1a; 1. 扩展实验范围 更多数据集和…

openresty lua用Redis的Stream解决消息订阅问题

使用 Redis Streams 解决消息订阅和消费的问题&#xff0c;可以避免在订阅模式下的连接管理问题。下面是如何使用 OpenResty 和 Redis Streams 实现类似的功能。 配置 nginx.conf 确保你的 nginx.conf 文件中配置了 Lua 模块和 Redis 集群的连接信息&#xff1a; http {lua_…

暑假学习DevEco Studio第一天

学习目标&#xff1a; 掌握构建第一个ArkTS应用 学习内容&#xff1a; 容器的应用 创建流程 点击file&#xff0c;new-> create project 点击empty ->next 进入配置界面 点击finsh&#xff0c;生成下面图片 这里需要注意记住index.ets &#xff0c;这是显示页面 –…