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