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_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相应时钟

/**
  * @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_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

/**
  * @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
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值