STM32 HAL库常用功能封装

关中断

c 复制代码
/**
 * @brief       关闭所有中断(但是不包括fault和NMI中断)
 * @param       无
 * @retval      无
 */
void sys_intx_disable(void)
{
    __ASM volatile("cpsid i");
}

开中断

c 复制代码
/**
 * @brief       开启所有中断
 * @param       无
 * @retval      无
 */
void sys_intx_enable(void)
{
    __ASM volatile("cpsie i");
}

进入待机模式

c 复制代码
/**
 * @brief       进入待机模式
 * @param       无
 * @retval      无
 */
void sys_standby(void)
{
    __HAL_RCC_PWR_CLK_ENABLE();    /* 使能电源时钟 */
    SET_BIT(PWR->CR, PWR_CR_PDDS); /* 进入待机模式 */
}

设置栈顶指针

c 复制代码
/**
 * @brief       设置栈顶地址
 * @note        左侧若出现红X, 属于MDK误报, 实际是没问题的
 * @param       addr: 栈顶地址
 * @retval      无
 */
void sys_msr_msp(uint32_t addr)
{
    __set_MSP(addr);    /* 设置栈顶地址 */
}

进入低功耗模式

c 复制代码
/**
 * @brief       执行: WFI指令(执行完该指令进入低功耗状态, 等待中断唤醒)
 * @param       无
 * @retval      无
 */
void sys_wfi_set(void)
{
    __ASM volatile("wfi");
}

系统软复位 (第一种)

c 复制代码
/**
 * @brief       系统软复位
 * @param       无
 * @retval      无
 */
void sys_soft_reset(void)
{
    NVIC_SystemReset();
}

系统软复位 (第二种)

c 复制代码
/*!
* @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初始化封装

c 复制代码
/**
  * @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_Pin
	GPIO_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相应时钟

c 复制代码
/**
  * @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

c 复制代码
#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_MODE
	uint16_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

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 sp330
	
	u4_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); /* 关闭低功耗 */
	
}
相关推荐
国科安芯1 天前
ASP4644芯片低功耗设计思路解析
网络·单片机·嵌入式硬件·安全
充哥单片机设计1 天前
【STM32项目开源】基于STM32的智能厨房火灾燃气监控
stm32·单片机·嵌入式硬件
CiLerLinux1 天前
第四十九章 ESP32S3 WiFi 路由实验
网络·人工智能·单片机·嵌入式硬件
时光の尘1 天前
【PCB电路设计】常见元器件简介(电阻、电容、电感、二极管、三极管以及场效应管)
单片机·嵌入式硬件·pcb·二极管·电感·三极管·场效应管
Lu Zelin1 天前
单片机为什么不能跑Linux
linux·单片机·嵌入式硬件
宁静致远20211 天前
stm32 freertos下基于hal库的模拟I2C驱动实现
stm32·嵌入式硬件·freertos
Wave8452 天前
STM32--智能小车
stm32·单片机·嵌入式硬件
wdfk_prog2 天前
[Linux]学习笔记系列 -- lib/timerqueue.c Timer Queue Management 高精度定时器的有序数据结构
linux·c语言·数据结构·笔记·单片机·学习·安全
helesheng2 天前
用低成本FPGA实现FSMC接口的多串口(UART)控制器
stm32·fsmc·fpga·uart控制器
充哥单片机设计2 天前
【STM32项目开源】基于STM32的智能家居环境(空气质量)检测系统
stm32·单片机·嵌入式硬件