STM32 HAL库常用功能封装
关中断
/*** @brief 关闭所有中断(但是不包括fault和NMI中断)* @param 无* @retval 无*/
void sys_intx_disable(void)
{__ASM volatile("cpsid i");
}
开中断
/*** @brief 开启所有中断* @param 无* @retval 无*/
void sys_intx_enable(void)
{__ASM volatile("cpsie i");
}
进入待机模式
/*** @brief 进入待机模式* @param 无* @retval 无*/
void sys_standby(void)
{__HAL_RCC_PWR_CLK_ENABLE(); /* 使能电源时钟 */SET_BIT(PWR->CR, PWR_CR_PDDS); /* 进入待机模式 */
}
设置栈顶指针
/*** @brief 设置栈顶地址* @note 左侧若出现红X, 属于MDK误报, 实际是没问题的* @param addr: 栈顶地址* @retval 无*/
void sys_msr_msp(uint32_t addr)
{__set_MSP(addr); /* 设置栈顶地址 */
}
进入低功耗模式
/*** @brief 执行: WFI指令(执行完该指令进入低功耗状态, 等待中断唤醒)* @param 无* @retval 无*/
void sys_wfi_set(void)
{__ASM volatile("wfi");
}
系统软复位 (第一种)
/*** @brief 系统软复位* @param 无* @retval 无*/
void sys_soft_reset(void)
{NVIC_SystemReset();
}
系统软复位 (第二种)
/*!
* @brief ARM 软重启
* @retval: 无
*/
#define SCB_AIRCR (*(unsigned long *)0xE000ED0C) //Reset control Address Register
#define SCB_RESET_VALUE 0x05FA0004 //reset value ,write to SCB_AIRCR can reset cpu
void Reset_System(void)
{SCB_AIRCR=SCB_RESET_VALUE;
}
GPIO初始化封装
/*** @brief 初始化GPIO* @note * @retval */
void MX_GPIOX_PIN_Init(GPIO_TypeDef *GPIOx,uint32_t GPIO_PIN_x,uint32_t GPIO_MODE_x,uint32_t Speed_x)
{GPIO_InitTypeDef GPIO_InitStruct = {0}; /* gpio初始化 */GPIO_InitStruct.Pin = GPIO_PIN_x; // 设置GPIO_PinGPIO_InitStruct.Mode = GPIO_MODE_x; // 设置模式为输入GPIO_InitStruct.Pull = GPIO_NOPULL; // 不使用上拉或下拉GPIO_InitStruct.Speed = Speed_x;HAL_GPIO_Init(GPIOx, &GPIO_InitStruct); // 初始化GPIOX的GPIO_Pin
}
开启GPIOx相应时钟
/*** @brief 开启对应GPIO Port时钟* @note * @retval */
void MX_GPIOX_Clock_Enable(GPIO_TypeDef *GPIOx) {/* 确保GPIOx是有效的GPIO口 */if (GPIOx == GPIOA) {__HAL_RCC_GPIOA_CLK_ENABLE();} else if (GPIOx == GPIOB) {__HAL_RCC_GPIOB_CLK_ENABLE();} else if (GPIOx == GPIOC) {__HAL_RCC_GPIOC_CLK_ENABLE();} else if (GPIOx == GPIOD) {__HAL_RCC_GPIOD_CLK_ENABLE();} else if (GPIOx == GPIOE) {__HAL_RCC_GPIOE_CLK_ENABLE();} else if (GPIOx == GPIOF) {__HAL_RCC_GPIOF_CLK_ENABLE();} else if (GPIOx == GPIOG) {__HAL_RCC_GPIOG_CLK_ENABLE();} else if (GPIOx == GPIOH) {__HAL_RCC_GPIOH_CLK_ENABLE();} else if (GPIOx == GPIOI) {__HAL_RCC_GPIOI_CLK_ENABLE();}
}
SP330协议转换芯片配置接口封装
sp330.h
#define USE_SP330 1 //使用sp330
/* sp330 configure begin */
#if USE_SP330
#define U1_SP330_SLEW_Pin GPIO_PIN_15
#define U1_SP330_SLEW_GPIO_Port GPIOA
#define U1_SP330_SHDN_Pin GPIO_PIN_12
#define U1_SP330_SHDN_GPIO_Port GPIOC
#define U1_SP330_DE_Pin GPIO_PIN_0
#define U1_SP330_DE_GPIO_Port GPIOD
#define U1_SP330_RE_Pin GPIO_PIN_1
#define U1_SP330_RE_GPIO_Port GPIOD
#define U1_SP330_HALE_FULL_Pin GPIO_PIN_2
#define U1_SP330_HALE_FULL_GPIO_Port GPIOD
#define U1_SP330_MODE_Pin GPIO_PIN_5
#define U1_SP330_MODE_GPIO_Port GPIOD#define U4_SP330_DE_Pin GPIO_PIN_6
#define U4_SP330_DE_GPIO_Port GPIOD
#define U4_SP330_RE_Pin GPIO_PIN_7
#define U4_SP330_RE_GPIO_Port GPIOB
#define U4_SP330_HALE_FULL_Pin GPIO_PIN_8
#define U4_SP330_HALE_FULL_GPIO_Port GPIOB
#define U4_SP330_MODE_Pin GPIO_PIN_9
#define U4_SP330_MODE_GPIO_Port GPIOB
#define U4_SP330_SLEW_Pin GPIO_PIN_0
#define U4_SP330_SLEW_GPIO_Port GPIOE
#define U4_SP330_SHDN_Pin GPIO_PIN_1
#define U4_SP330_SHDN_GPIO_Port GPIOE/* sp330模式 */
typedef enum
{RS232_MODE = 232,RS422_MODE = 422,RS485_MODE = 485
}SP330_MODE;/* sp330通信方式 */
typedef enum
{HALF_DUPLEX = 11,FULL_DUPLEX = 22 //全双工
}SP330_COMM_MODE;/* 配置结构体 */
typedef struct
{uint16_t SP330_Work_Mode; //取值范围为SP330_MODE枚举uint16_t SP330_Comm_Mode; //SP330_COMM_MODEuint16_t SP330_DE_GPIO_Pin; //发送脚uint16_t SP330_RE_GPIO_Pin; //接收脚uint16_t SP330_MODE_GPIO_Pin; //模式配置uint16_t SP330_SLEW_GPIO_Pin; //限摆率设置uint16_t SP330_SHDN_GPIO_Pin; //功耗模式设置:uint16_t SP330_HALE_FULL_GPIO_Pin; //双工模式GPIO_TypeDef *SP330_RE_GPIOx;GPIO_TypeDef *SP330_DE_GPIOx;GPIO_TypeDef *SP330_SLEW_GPIOx;GPIO_TypeDef *SP330_SHDN_GPIOx;GPIO_TypeDef *SP330_MODE_GPIOx;GPIO_TypeDef *SP330_HALE_FULL_GPIOx;
}Sp330_Configure;void Sp330_Init(Sp330_Configure *sp330); //sp330初始化
void Uart_Sp330_Configure(void); //sp330配置
/* sp330 configure end */
#endif
sp330.c
/*** @brief sp330配置函数* @note * @retval */
void Uart_Sp330_Configure(void)
{/* 配置结构体定义 */Sp330_Configure u1_sp330; Sp330_Configure u4_sp330; u1_sp330.SP330_DE_GPIOx = U1_SP330_DE_GPIO_Port;u1_sp330.SP330_DE_GPIO_Pin = U1_SP330_DE_Pin;u1_sp330.SP330_RE_GPIOx = U1_SP330_RE_GPIO_Port;u1_sp330.SP330_RE_GPIO_Pin = U1_SP330_RE_Pin;u1_sp330.SP330_SHDN_GPIOx = U1_SP330_SHDN_GPIO_Port;u1_sp330.SP330_SHDN_GPIO_Pin = U1_SP330_SHDN_Pin;u1_sp330.SP330_SLEW_GPIOx = U1_SP330_SLEW_GPIO_Port;u1_sp330.SP330_SLEW_GPIO_Pin = U1_SP330_SLEW_Pin;u1_sp330.SP330_MODE_GPIOx = U1_SP330_MODE_GPIO_Port;u1_sp330.SP330_MODE_GPIO_Pin = U1_SP330_MODE_Pin;u1_sp330.SP330_Work_Mode = RS422_MODE; //422模式u1_sp330.SP330_Comm_Mode = FULL_DUPLEX; //全双工Sp330_Init(&u1_sp330); //初始化uart1 sp330u4_sp330.SP330_DE_GPIOx = U4_SP330_DE_GPIO_Port;u4_sp330.SP330_DE_GPIO_Pin = U4_SP330_DE_Pin;u4_sp330.SP330_RE_GPIOx = U4_SP330_RE_GPIO_Port;u4_sp330.SP330_RE_GPIO_Pin = U4_SP330_RE_Pin;u4_sp330.SP330_SHDN_GPIOx = U4_SP330_SHDN_GPIO_Port;u4_sp330.SP330_SHDN_GPIO_Pin = U4_SP330_SHDN_Pin;u4_sp330.SP330_SLEW_GPIOx = U4_SP330_SLEW_GPIO_Port;u4_sp330.SP330_SLEW_GPIO_Pin = U4_SP330_SLEW_Pin;u4_sp330.SP330_MODE_GPIOx = U4_SP330_MODE_GPIO_Port;u4_sp330.SP330_MODE_GPIO_Pin = U4_SP330_MODE_Pin;u4_sp330.SP330_Work_Mode = RS422_MODE; //422模式u4_sp330.SP330_Comm_Mode = FULL_DUPLEX; //全双工Sp330_Init(&u4_sp330); //初始化uart4 sp330
}void Sp330_Init(Sp330_Configure *sp330)
{
#if 0 //mx生成时已初始化引脚,不在这里再次初始化了/* 开启GPIO时钟 */MX_GPIOX_Clock_Enable(sp330->SP330_DE_GPIOx);MX_GPIOX_Clock_Enable(sp330->SP330_RE_GPIOx);MX_GPIOX_Clock_Enable(sp330->SP330_SLEW_GPIOx);MX_GPIOX_Clock_Enable(sp330->SP330_SHDN_GPIOx);MX_GPIOX_Clock_Enable(sp330->SP330_HALE_FULL_GPIOx);MX_GPIOX_Clock_Enable(sp330->SP330_MODE_GPIOx);/* 初始化GPIO */MX_GPIOX_PIN_Init(sp330->SP330_DE_GPIOx,sp330->SP330_DE_GPIO_Pin,GPIO_MODE_OUTPUT_PP,GPIO_SPEED_LOW);MX_GPIOX_PIN_Init(sp330->SP330_RE_GPIOx,sp330->SP330_RE_GPIO_Pin,GPIO_MODE_OUTPUT_PP,GPIO_SPEED_LOW);MX_GPIOX_PIN_Init(sp330->SP330_SLEW_GPIOx,sp330->SP330_SLEW_GPIO_Pin,GPIO_MODE_OUTPUT_PP,GPIO_SPEED_LOW);MX_GPIOX_PIN_Init(sp330->SP330_SHDN_GPIOx,sp330->SP330_SHDN_GPIO_Pin,GPIO_MODE_OUTPUT_PP,GPIO_SPEED_LOW);MX_GPIOX_PIN_Init(sp330->SP330_HALE_FULL_GPIOx,sp330->SP330_HALE_FULL_GPIO_Pin,GPIO_MODE_OUTPUT_PP,GPIO_SPEED_LOW);MX_GPIOX_PIN_Init(sp330->SP330_MODE_GPIOx,sp330->SP330_MODE_GPIO_Pin,GPIO_MODE_OUTPUT_PP,GPIO_SPEED_LOW);
#endif /* 模式配置 RS485 \RS422 \RS232设置*/if(sp330->SP330_Work_Mode == RS232_MODE)HAL_GPIO_WritePin(sp330->SP330_MODE_GPIOx,sp330->SP330_MODE_GPIO_Pin,GPIO_PIN_RESET);else if(sp330->SP330_Work_Mode == RS422_MODE || sp330->SP330_Work_Mode == RS485_MODE) {HAL_GPIO_WritePin(sp330->SP330_MODE_GPIOx,sp330->SP330_MODE_GPIO_Pin,GPIO_PIN_SET);HAL_GPIO_WritePin(sp330->SP330_DE_GPIOx,sp330->SP330_DE_GPIO_Pin,GPIO_PIN_SET);//使能发送HAL_GPIO_WritePin(sp330->SP330_RE_GPIOx,sp330->SP330_RE_GPIO_Pin,GPIO_PIN_RESET); //使能接收}/* 通信方式设置 全双工、半双工设置*/if(sp330->SP330_Comm_Mode == HALF_DUPLEX) HAL_GPIO_WritePin(sp330->SP330_HALE_FULL_GPIOx,sp330->SP330_HALE_FULL_GPIO_Pin,GPIO_PIN_SET);else if(sp330->SP330_Comm_Mode == FULL_DUPLEX) HAL_GPIO_WritePin(sp330->SP330_HALE_FULL_GPIOx,sp330->SP330_HALE_FULL_GPIO_Pin,GPIO_PIN_RESET);/* 限摆率设置 */HAL_GPIO_WritePin(sp330->SP330_SLEW_GPIOx,sp330->SP330_SLEW_GPIO_Pin,GPIO_PIN_SET); /*无限制*//* 低功耗设置 */HAL_GPIO_WritePin(sp330->SP330_SHDN_GPIOx,sp330->SP330_SHDN_GPIO_Pin,GPIO_PIN_SET); /* 关闭低功耗 */}
相关文章:
STM32 HAL库常用功能封装
关中断 /*** brief 关闭所有中断(但是不包括fault和NMI中断)* param 无* retval 无*/ void sys_intx_disable(void) {__ASM volatile("cpsid i"); }开中断 /*** brief 开启所有中断* param 无* retval 无*/ void sys_intx_enabl…...

golang zap日志库 打印日志时显示的源文件始终是同一个问题解决方法 zap.Option函数可选项 zap.AddCallerSkip(1) 使用示例
这种情况一般出现在我们对zap日志库进行二次封装的情况下, 在打印日志的时候的源文件非我们期望的文件,如下 原因分析 出现这个问题的原因是zap函数内部在调用 runtime.Caller 时的skip层级不对了,因为我们进行了二次封装,所以za…...

BL196MQTT远程IO模块助力智能楼宇自动化升级
在智能楼宇自动化领域,每一个细节的优化都能带来整体效率与舒适度的显著提升。钡铼技术的BL196MQTT远程IO模块,以其卓越的灵活性和强大的性能,正在成为这一领域中推动楼宇自动化升级的关键力量。 钡铼技术IOy系列:创新与灵活性的…...
【面试宝典】Java面向对象面试题总结(上)
一、重写和重载 在Java中,重写(Override)和重载(Overload)是面向对象编程中两个非常重要的概念,它们都与方法的定义和调用有关,但两者有着本质的区别。 1、重写(Overrideÿ…...

如何运用独特的产业运营体系打造一流的数字媒体产业园
如何运用独特的产业运营体系打造一流的数字媒体产业园 2024-08-15 17:37树莓集团 在数字经济蓬勃发展的今天,数字媒体产业作为其中的重要一环,正展现出巨大的潜力和活力。而如何运用独特的产业运营体系,打造一流的数字媒体产业园࿰…...
安全基础学习-SHA-256
SHA-256 是一种密码学哈希函数,是 SHA-2(Secure Hash Algorithm 2)家族的一部分。它被广泛用于数据完整性验证、数字签名以及密码存储等领域。 1、SHA-256的原理 SHA-256 生成一个固定长度为 256 位(32 字节)的哈希值。无论输入数据的大小或类型,输出的哈希值始终是 25…...
Redis中Big Key该如何解决?
目录 1、Big Key的产生 2、BigKey场景分析 3、Big Key的危害 4、检测 BigKey 5、解决 BigKey 问题 Big Key拆分 (1)按时间/业务拆分 (2)按哈希(Hash)拆分 (3)按前缀树拆分…...

基于springboot的实习管理系统
TOC springboot207基于springboot的实习管理系统 绪论 1.1研究背景与意义 信息化管理模式是将行业中的工作流程由人工服务,逐渐转换为使用计算机技术的信息化管理服务。这种管理模式发展迅速,使用起来非常简单容易,用户甚至不用掌握相关的…...

土地利用/土地覆盖遥感解译与基于CLUE模型未来变化情景预测
土地利用/土地覆盖数据是生态、环境和气象等领域众多模型的重要输入参数之一。基于遥感影像解译,可获取历史或当前任何一个区域的土地利用/土地覆盖数据,用于评估区域的生态环境变化、评价重大生态工程建设成效等。借助CLUE模型,实现对未来土…...
Rust 之环境搭建
前言 Rust 是一种现代的系统级编程语言,以其内存安全性、高性能和简洁的语法而著称。本文将介绍如何在不同操作系统上搭建 Rust 开发环境,并配置好基础工具,使您能够快速开始 Rust 编程。 1. 安装 Rust Rust 官方推荐使用 rustup 工具来管…...

基于微信小程序地图实现点位标注、覆盖物、地图聊天
目录 小程序部分map标签的使用获取用户经纬度并转换地址地图点击事件覆盖物标注点击并实现弹窗交互数据库及接口部分数据库表结构设计API搭建小程序接口使用注意事项wx.getLocation深入控制地图小程序部分 map标签的使用 创建小程序的步骤这里不再重复赘述,在wxml页面中放一个…...

xxl-job的分片广播+单播
1 介绍一下xxl-job XXL-JOB 是一个分布式任务调度平台,旨在为分布式应用系统提供开箱即用的调度解决方案。它非常易于使用,并具有很高的可扩展性。以下是 XXL-JOB 的详细介绍,包括其核心功能、架构设计、主要组件及其应用场景。 核心功能 简…...
情感分类代码
在进行自然语言处理中的情感分类时,通常需要准备以下几方面的内容: 1. **数据集**:高质量的标注数据集是关键,包括正面、负面和中性情感标记的文本。 2. **情感词典**:可用的情感词典,如SentiWordNet&…...
WPF—常用控件、属性、事件、详细介绍
WPF—常用控件、属性、事件、详细介绍 WPF(Windows Presentation Foundation)是微软推出的基于Windows 的用户界面框架,属于.NET Framework 3.0的一部分。它提供了统一的编程模型、语言和框架,真正做到了分离界面设计人员与开发人…...

Oracle遭遇bug导致共享内存无法分配报ORA-04031错误
1.故障描述 在7月17日上午11时左右,收到告警短信,提示集群节点2宕机,当即登陆该节点进行查看,发现数据库状态正常。但日志里出现大量的ORA-04031报错,提示无法分配shared_pool,当时手动执行shared pool刷新…...

SAP BRIM用于应收账款AR收入中台
SAP BRIM(Billing and Revenue Innovation Management)是SAP提供的一个综合性解决方案,旨在帮助企业高效管理计费和收入流程。它与SAP ERP系统集成,提供端到端的功能,简化计费流程,自动化收入确认ÿ…...

LVS原理简介
LVS是Linux virtual server的缩写,为linux虚拟服务器,是一个虚拟的服务器集群系统。LVS简单工作原理为用户请求LVS VIP,LVS根据转发方式和算法,将请求转发给后端服务器,后端服务器接收到请求,返回给用户。对…...
Qt五大核心特性之元对象系统
前言 Qt 的元对象系统(Meta-Object System)是 Qt 框架的核心之一,提供了一些 C 原生不具备的功能(因为在C它们是静态的),如反射、信号槽机制、属性系统等。通过这个系统,Qt 实现了许多强大的功能,这使得它…...

开放式耳机伤耳朵吗?开放式耳机在一定程度上保护我们的耳朵
开放式耳机通常被认为对耳朵的伤害较小,因为它们不需要插入耳道,从而减少了耳道内的压力和潜在的感染风险。与传统入耳式耳机相比,开放式耳机允许耳朵自然通风,减少耳道内的湿气和热量积聚,这有助于保持耳朵的健康。 然…...

JAVA打车小程序APP打车顺风车滴滴车跑腿源码微信小程序打车系统源码
🚗💨打车、顺风车、滴滴车&跑腿系统,一键解决出行生活难题! 一、出行新选择,打车从此不再难 忙碌的生活节奏,让我们常常需要快速、便捷的出行方式。打车、顺风车、滴滴车系统,正是为了满足…...

NFT模式:数字资产确权与链游经济系统构建
NFT模式:数字资产确权与链游经济系统构建 ——从技术架构到可持续生态的范式革命 一、确权技术革新:构建可信数字资产基石 1. 区块链底层架构的进化 跨链互操作协议:基于LayerZero协议实现以太坊、Solana等公链资产互通,通过零知…...

深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...

基于TurtleBot3在Gazebo地图实现机器人远程控制
1. TurtleBot3环境配置 # 下载TurtleBot3核心包 mkdir -p ~/catkin_ws/src cd ~/catkin_ws/src git clone -b noetic-devel https://github.com/ROBOTIS-GIT/turtlebot3.git git clone -b noetic https://github.com/ROBOTIS-GIT/turtlebot3_msgs.git git clone -b noetic-dev…...
return this;返回的是谁
一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请,不同级别的经理有不同的审批权限: // 抽象处理者:审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...
uniapp 字符包含的相关方法
在uniapp中,如果你想检查一个字符串是否包含另一个子字符串,你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的,但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...
MinIO Docker 部署:仅开放一个端口
MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...
苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会
在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

Python环境安装与虚拟环境配置详解
本文档旨在为Python开发者提供一站式的环境安装与虚拟环境配置指南,适用于Windows、macOS和Linux系统。无论你是初学者还是有经验的开发者,都能在此找到适合自己的环境搭建方法和常见问题的解决方案。 快速开始 一分钟快速安装与虚拟环境配置 # macOS/…...
【java】【服务器】线程上下文丢失 是指什么
目录 ■前言 ■正文开始 线程上下文的核心组成部分 为什么会出现上下文丢失? 直观示例说明 为什么上下文如此重要? 解决上下文丢失的关键 总结 ■如果我想在servlet中使用线程,代码应该如何实现 推荐方案:使用 ManagedE…...

Java中HashMap底层原理深度解析:从数据结构到红黑树优化
一、HashMap概述与核心特性 HashMap作为Java集合框架中最常用的数据结构之一,是基于哈希表的Map接口非同步实现。它允许使用null键和null值(但只能有一个null键),并且不保证映射顺序的恒久不变。与Hashtable相比,Hash…...