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); /* 关闭低功耗 */
	
}
相关推荐
安科瑞刘鸿鹏2 小时前
校园建筑用电安全监测装置 电气火灾监测预防设备功能介绍
运维·服务器·网络·嵌入式硬件·安全·能源
Wx120不知道取啥名2 小时前
C语言之长整型有符号数与短整型有符号数转换
c语言·开发语言·单片机·mcu·算法·1024程序员节
Cici_ovo5 小时前
摄像头点击器常见问题——摄像头视窗打开慢
人工智能·单片机·嵌入式硬件·物联网·计算机视觉·硬件工程
无际单片机项目实战5 小时前
为什么STM32的HAL库那么难用,ST还是要硬推HAL库?
c语言·stm32·单片机·嵌入式硬件·物联网
正在努力的小立8 小时前
STM32 HAL 点灯
stm32·单片机·嵌入式硬件
TeYiToKu9 小时前
笔记整理—linux驱动开发部分(1)驱动梗概
linux·c语言·arm开发·驱动开发·嵌入式硬件
Whappy00110 小时前
3. STM32之TIM实验--输出比较(PWM输出,电机,四轴飞行器,智能车,机器人)--(实验1:PWM驱动LED呼吸灯)
stm32·嵌入式硬件·机器人
想拿 0day 的脚步小子10 小时前
6.stm32 OLED显示屏
stm32
Java Fans12 小时前
嵌入式软件在电子烟开发中的应用
嵌入式硬件
环能jvav大师14 小时前
使用Ubuntu系统+VS Code开发STC51单片机
linux·c语言·开发语言·单片机·嵌入式硬件·ubuntu