STM32 HAL库常用功能封装

embedded/2024/10/9 7:58:13/

关中断

/*** @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); /* 关闭低功耗 */}

http://www.ppmy.cn/embedded/97952.html

相关文章

AXI DMA IP的DRE对性能产生的影响

AXI DMA IP的DRE(Data Re-Alignment,数据重对齐)对齐功能在提供数据传输灵活性的同时,确实可能对性能产生一定的影响。在编程时,是否启用此功能需要综合考虑多个因素。以下是对这一问题的详细分析: DRE对齐…

使用 AWS EKS 部署 Easysearch

随着企业对数据搜索和分析需求的增加,高效的搜索引擎解决方案变得越来越重要。Easysearch 作为一款强大的企业级搜索引擎,可以帮助企业快速构建高性能、可扩展的数据检索系统。在云计算的背景下,使用容器化技术来部署和管理这些解决方案已经成…

Linux系统安全加固:深入防火墙与SELinux策略

在当前复杂多变的网络环境中,Linux系统作为服务器和开发环境的首选操作系统之一,其安全性至关重要。从防火墙的精细配置到SELinux(Security-Enhanced Linux)的策略调整,本文将深入探讨Linux系统安全加固的高级技巧&…

基于LangChain手工测试用例转接口自动化测试生成工具!

接口自动化测试用例是一个老生常谈的问题,在未引入人工智能之前,也有非常多的生成方案,比如如下所示,通过har生成接口自动化测试用例: 但是以上的生成方式依然是有一些弊端,比如 har 本身虽然能表述一定的接…

vscode 阅读linux内核(vscode+clangd)

此插件曾在vim里用过,非常好用。 首先先在vscode 里下载clangd插件 这只是客户端,还需下载个服务器(这在coc插件里也有说明) sudo apt install clangd 下载完后可以 clangd --version 查看版本信息,如果能查看&#x…

使用VirtualBox【安装Ubuntu虚拟机】并【挂载宿主机器目录】

1.安装Ubuntu虚拟机 参考文章:https://blog.csdn.net/Amentos/article/details/127733864 2.虚拟机器与宿主机共享文件夹 共享文件夹 步骤: a. 在VirtualBox中,选择要添加共享文件夹的虚拟机,点击"设置"。 b. 在&q…

讲清前端开发(入门)

前端开发:创建用户在网页或应用程序中直接与之交互的部分。 简单来说,就是负责打造用户在使用网站、网页应用或者移动应用时直接看到和与之交互的部分。打个比方,前端开发就像是给房子做装修。房子的框架结构已经有了,但是需要有…

软考高级第四版备考---第四十六天(数据集成)

一、基础集成:基本原则 开放:要遵循工业开放标准结构化:复杂系统分解成相对独立和简单的子系统先进性;主流性 二、网络集成(互连),主要体系框架 传输子系统:传输是网络的核心&…