Clion开发STM32之HAL库USART封装(基础库)

前言

引用参考:

  1. Clion开发STM32之HAL库GPIO宏定义封装(最新版)

头文件

c 复制代码
/*******************************************************************************
 * Copyright (c) [scl]。保留所有权利。
 *      本文仅供个人学习和研究使用,禁止用于商业用途。
 ******************************************************************************/
#ifndef STM32_F1XX_PROJECT_BSP_SERIAL_H
#define STM32_F1XX_PROJECT_BSP_SERIAL_H

#include "bsp_include.h"


#ifndef STM32_LIB_SYS_CORE_KERNEL_H /*为了保证驱动的独立性*/
#define sys_force_static_inline      __attribute__((always_inline)) static inline
#define error_handle()
#endif
#define COM_DEFAULT_CNF {\
                .BaudRate = 115200, /*波特率*/\
                .WordLength = UART_WORDLENGTH_8B,/*数据宽度*/\
                .StopBits = UART_STOPBITS_1,/*停止位*/\
                .Parity = UART_PARITY_NONE,/*校验位*/\
                .Mode = UART_MODE_TX_RX,/*读写模式*/\
                .HwFlowCtl = UART_HWCONTROL_NONE,/*硬件控制*/\
                .OverSampling = UART_OVERSAMPLING_16,/*采样率*/\
        }

/** @brief  检查是否设置了指定的 UART 标志。
  * @param  __UART__ 具体串口实例.
  * @param  __FLAG__ 具体标志位
  *        此参数可以是以下值之一:
  *            @arg UART_FLAG_CTS:  CTS 更改标志(不适用于 UART4 和 UART5)
  *            @arg UART_FLAG_LBD:  LIN 中断检测标志
  *            @arg UART_FLAG_TXE:  传输数据寄存器空标志
  *            @arg UART_FLAG_TC:   传输完成标志
  *            @arg UART_FLAG_RXNE: 接收数据寄存器不为空标志
  *            @arg UART_FLAG_IDLE: 空闲线路检测标志
  *            @arg UART_FLAG_ORE:  溢出错误标志
  *            @arg UART_FLAG_NE:   噪声错误标志
  *            @arg UART_FLAG_FE:   帧错误标志
  *            @arg UART_FLAG_PE:   奇偶校验错误标志
  * @retval 状态(true或false).
  */
#define UART_GET_FLAG(__UART__, __FLAG__) (((__UART__)->SR & (__FLAG__)) == (__FLAG__))
#define UART_CLEAR_FLAG(__UART__, __FLAG__) ((__UART__)->SR = ~(__FLAG__))
#define UART_CLEAR_PEFLAG(__UART__)     \
  do{                                           \
    __IO uint32_t tmpreg = 0x00U;               \
    tmpreg = (__UART__)->SR;        \
    tmpreg = (__UART__)->DR;        \
    UNUSED(tmpreg);                             \
  } while(0U)

/** @brief  使能具体的中断源标志位
  * @param  __UART__ 具体串口实例
  * @param  __INTERRUPT__  中断源
  *          此参数可以是以下值之一:
  *            @arg UART_IT_CTS:  CTS 中断
  *            @arg UART_IT_LBD:  LIN中断检测中断
  *            @arg UART_IT_TXE:  发送数据寄存器空中断
  *            @arg UART_IT_TC:   传输完成中断
  *            @arg UART_IT_RXNE: 接收数据寄存器不为空中断
  *            @arg UART_IT_IDLE: 空闲线路检测中断
  *            @arg UART_IT_PE:   奇偶校验错误中断
  *            @arg UART_IT_ERR:  错误中断(帧错误, 噪声错误, 溢出错误)
  * @retval None
  */
#define UART_ENABLE_IT(__UART__, __INTERRUPT__)   ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__UART__)->CR1 |= ((__INTERRUPT__) & UART_IT_MASK)): \
                                                   (((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__UART__)->CR2 |= ((__INTERRUPT__) & UART_IT_MASK)): \
                                                    ((__UART__)->CR3 |= ((__INTERRUPT__) & UART_IT_MASK)))

/** @brief  Disable 具体的中断源标志位.
  * @param  __UART__ 具体串口实例.
  * @param  __INTERRUPT__ 指定要禁用的 UART 中断源.
  *          此参数可以是以下值之一:
  *            @arg UART_IT_CTS:  CTS 中断
  *            @arg UART_IT_LBD:  LIN中断检测中断
  *            @arg UART_IT_TXE:  发送数据寄存器空中断
  *            @arg UART_IT_TC:   传输完成中断
  *            @arg UART_IT_RXNE: 接收数据寄存器不为空中断
  *            @arg UART_IT_IDLE: 空闲线路检测中断
  *            @arg UART_IT_PE:   奇偶校验错误中断
  *            @arg UART_IT_ERR:  错误中断(帧错误, 噪声错误, 溢出错误)
  * @retval None
  */
#define UART_DISABLE_IT(__UART__, __INTERRUPT__)  ((((__INTERRUPT__) >> 28U) == UART_CR1_REG_INDEX)? ((__UART__)->CR1 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
                                                           (((__INTERRUPT__) >> 28U) == UART_CR2_REG_INDEX)? ((__UART__)->CR2 &= ~((__INTERRUPT__) & UART_IT_MASK)): \
                                                           ((__UART__)->CR3 &= ~ ((__INTERRUPT__) & UART_IT_MASK)))

/**
 * @brief 串口错误标志位判断 并清除
 */
#define UART_FAILED_FLAG_CLEAR(__UART__)     do { \
if (UART_GET_FLAG(__UART__, UART_FLAG_ORE) != RESET   || UART_GET_FLAG(__UART__, UART_FLAG_FE) != RESET \
    || UART_GET_FLAG(__UART__, UART_FLAG_PE) != RESET || UART_GET_FLAG(__UART__, UART_FLAG_NE) != RESET) { \
            UART_CLEAR_PEFLAG(__UART__); \
    } \
if (UART_GET_FLAG(__UART__, UART_FLAG_CTS) != RESET) {\
            UART_CLEAR_FLAG(__UART__, UART_FLAG_CTS);\
}\
if (UART_GET_FLAG(__UART__, UART_FLAG_TXE) != RESET) {\
            UART_CLEAR_FLAG(__UART__, UART_FLAG_TXE);\
}\
if (UART_GET_FLAG(__UART__, UART_FLAG_TC) != RESET) {\
            UART_CLEAR_FLAG(__UART__, UART_FLAG_TC);\
}\
if (UART_GET_FLAG(__UART__, UART_FLAG_RXNE) != RESET) {\
            UART_CLEAR_FLAG(__UART__, UART_FLAG_RXNE);\
    }\
} while (0)


sys_force_static_inline int com_read_data(USART_TypeDef *uart) {
    int ch = -1;

    if (UART_GET_FLAG(uart, UART_FLAG_RXNE) != RESET) {
        ch = uart->DR & 0xff;
    }
    return ch;
}

sys_force_static_inline int com_write_data(USART_TypeDef *uart, uint8_t dat) {
    UART_CLEAR_FLAG(uart, UART_FLAG_TC);
    uart->DR = dat;
    while (UART_GET_FLAG(uart, UART_FLAG_TC) == RESET);
    return 1;
}

/********************************串口1 (需要重写)**********************************************/
#define COM1_TX PA9
#define COM1_RX PA10

void com1_gpio_msp_init();

void com1_gpio_msp_de_init();

void com1_dma_tx_msp_init();/**串口DMA TX硬件初始化 @see HAL_UART_MspInit*/
void com1_dma_tx_msp_de_init();/**串口DMA TX硬件重置 @see HAL_UART_MspDeInit*/
void com1_dma_rx_msp_init();/**串口DMA RX硬件初始化 @see HAL_UART_MspInit*/
void com1_dma_rx_msp_de_init();/**串口DMA RX硬件重置 @see HAL_UART_MspDeInit*/
void com1_it_msp_init(void);/**串口中断硬件初始化 @see HAL_UART_MspInit*/
void com1_it_msp_de_init(void);/**串口中断硬件重置 @see HAL_UART_MspDeInit*/
/*-------------------------------------串口1回调-------------------------------------------------*/
extern void com1_ErrorCallback();/** @see HAL_UART_ErrorCallback*/
extern void com1_RxHalfCpltCallback();/**@see HAL_UART_RxHalfCpltCallback*/
extern void com1_RxCpltCallback();/**@see HAL_UART_RxCpltCallback*/
extern void com1_RxEventCallback(uint16_t Size);/** @see HAL_UARTEx_RxEventCallback*/
/********************************串口2 (需要重写)**********************************************/
//PA2------> USART2_TX   PA3------> USART2_RX
#define COM2_TX PA2
#define COM2_RX PA3

void com2_gpio_msp_init();

void com2_gpio_msp_de_init();

void com2_dma_tx_msp_init();/**串口DMA TX硬件初始化 @see HAL_UART_MspInit*/
void com2_dma_tx_msp_de_init();/**串口DMA TX硬件重置 @see HAL_UART_MspDeInit*/
void com2_dma_rx_msp_init();/**串口DMA RX硬件初始化 @see HAL_UART_MspInit*/
void com2_dma_rx_msp_de_init();/**串口DMA RX硬件重置 @see HAL_UART_MspDeInit*/
void com2_it_msp_init(void);/**串口中断硬件初始化 @see HAL_UART_MspInit*/
void com2_it_msp_de_init(void);/**串口中断硬件重置 @see HAL_UART_MspDeInit*/
/*-------------------------------------串口2回调-------------------------------------------------*/
extern void com2_ErrorCallback();/** @see HAL_UART_ErrorCallback*/
extern void com2_RxHalfCpltCallback();/**@see HAL_UART_RxHalfCpltCallback*/
extern void com2_RxCpltCallback();/**@see HAL_UART_RxCpltCallback*/
extern void com2_RxEventCallback(uint16_t Size);/** @see HAL_UARTEx_RxEventCallback*/
/********************************串口3 (需要重写)**********************************************/
#define COM3_TX PB10
#define COM3_RX PB11

void com3_gpio_msp_init();

void com3_gpio_msp_de_init();

void com3_dma_tx_msp_init();/**串口DMA TX硬件初始化 @see HAL_UART_MspInit*/
void com3_dma_tx_msp_de_init();/**串口DMA TX硬件重置 @see HAL_UART_MspDeInit*/
void com3_dma_rx_msp_init();/**串口DMA RX硬件初始化 @see HAL_UART_MspInit*/
void com3_dma_rx_msp_de_init();/**串口DMA RX硬件重置 @see HAL_UART_MspDeInit*/
void com3_it_msp_init(void);/**串口中断硬件初始化 @see HAL_UART_MspInit*/
void com3_it_msp_de_init(void);/**串口中断硬件重置 @see HAL_UART_MspDeInit*/
/*-------------------------------------串口3回调-------------------------------------------------*/
extern void com3_ErrorCallback();/** @see HAL_UART_ErrorCallback*/
extern void com3_RxHalfCpltCallback();/**@see HAL_UART_RxHalfCpltCallback*/
extern void com3_RxCpltCallback();/**@see HAL_UART_RxCpltCallback*/
extern void com3_RxEventCallback(uint16_t Size);/** @see HAL_UARTEx_RxEventCallback*/
/********************************串口4 中断**********************************************/
void bsp_SerialHandleInit(UART_HandleTypeDef *handle, uint32_t baud);


#endif //STM32_F1XX_PROJECT_BSP_SERIAL_H

源文件

c 复制代码
#include "bsp_serial.h"

void HAL_UART_MspInit(UART_HandleTypeDef *uartHandle) {
    USART_TypeDef *uart = uartHandle->Instance;
    if (uart == USART1) {
        /* USART1 clock enable */
        __HAL_RCC_USART1_CLK_ENABLE();
        /* io init */
        com1_gpio_msp_init();
        /*com1 dma rx 初始化*/
        com1_dma_rx_msp_init();
        /*com1 dma tx 初始化*/
        com1_dma_tx_msp_init();
        /*com1 it 初始化*/
        com1_it_msp_init();
    } else if (uart == USART2) {
        /*  clock enable */
        __HAL_RCC_USART2_CLK_ENABLE();
        /* io init */
        com2_gpio_msp_init();

        /*com2 dma rx 初始化*/
        com2_dma_rx_msp_init();
        /*com2 dma tx 初始化*/
        com2_dma_tx_msp_init();
        /*com2 it 初始化*/
        com2_it_msp_init();
    } else if (uart == USART3) {
        /* USART3 clock enable */
        __HAL_RCC_USART3_CLK_ENABLE();
        /* io init */
        com3_gpio_msp_init();

        /*com3 dma rx 初始化*/
        com3_dma_rx_msp_init();
        /*com3 dma tx 初始化*/
        com3_dma_tx_msp_init();
        /*com3 it 初始化*/
        com3_it_msp_init();
    } else if (uart == UART4) {
    } else {
        error_handle();
    }
}

void HAL_UART_MspDeInit(UART_HandleTypeDef *uartHandle) {
    USART_TypeDef *uart = uartHandle->Instance;
    if (uart == USART1) {
        /* clock disable */
        __HAL_RCC_USART1_CLK_DISABLE();
        /* io deinit */
        com1_gpio_msp_de_init();

        com1_dma_rx_msp_de_init();
        com1_dma_tx_msp_de_init();
        com1_it_msp_de_init();
    } else if (uart == USART2) {
        /* clock disable */
        __HAL_RCC_USART2_CLK_DISABLE();

        com2_gpio_msp_de_init();
        com2_dma_rx_msp_de_init();
        com2_dma_tx_msp_de_init();
        com2_it_msp_de_init();
    } else if (uart == USART3) {
        /* Peripheral clock disable */
        __HAL_RCC_USART3_CLK_DISABLE();
        /* io init */
        com3_gpio_msp_de_init();

        com3_dma_rx_msp_de_init();
        com3_dma_tx_msp_de_init();
        com3_it_msp_de_init();
    } else if (uart == UART4) {
    } else {
        error_handle();
    }

}


void bsp_SerialInit(device_id_type com, uint32_t baud) {
    UART_HandleTypeDef *ptr = conv_uart_handle_ptr(handle_get_by_id(com));
    if (ptr == NULL) {
        error_handle();
    } else {
        ptr->Init.BaudRate = baud;
        if (HAL_UART_Init(ptr) != HAL_OK) {
            error_handle();
        }
    }

}

void bsp_SerialHandleInit(UART_HandleTypeDef *handle, uint32_t baud) {
    if (handle == NULL) {
        error_handle();
    } else {
        handle->Init.BaudRate = baud;
        if (HAL_UART_Init(handle) != HAL_OK) {
            error_handle();
        }
    }
}




void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *handle, uint16_t Size) {
    USART_TypeDef *uart = handle->Instance;
    if (uart == USART1) {
        com1_RxEventCallback(Size);
    } else if (uart == USART2) {
        com2_RxEventCallback(Size);
    } else if (uart == USART3) {
        com3_RxEventCallback(Size);

    } else if (uart == UART4) {
    } else {
        error_handle();
    }
}


void HAL_UART_ErrorCallback(UART_HandleTypeDef *handle) {
    switch (handle->ErrorCode) {
        case HAL_UART_ERROR_PE:
            __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_PE);
            break;
        case HAL_UART_ERROR_NE:
            __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_NE);
            break;
        case HAL_UART_ERROR_FE:
            __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_FE);
            break;
        case HAL_UART_ERROR_ORE:
            __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_ORE);
            break;
        case HAL_UART_ERROR_DMA:
            __HAL_UART_CLEAR_FLAG(handle, UART_FLAG_IDLE);
            break;
        default:
            __HAL_UART_CLEAR_FEFLAG(handle);
            break;
    }
    USART_TypeDef *uart = handle->Instance;
    if (uart == USART1) {
        com1_ErrorCallback();
    } else if (uart == USART2) {
        com2_ErrorCallback();
    } else if (uart == USART3) {
        com3_ErrorCallback();

    } else if (uart == UART4) {
    } else {
        error_handle();
    }
}

void HAL_UART_RxHalfCpltCallback(UART_HandleTypeDef *handle) {
    USART_TypeDef *uart = handle->Instance;
    if (uart == USART1) {
        com1_RxHalfCpltCallback();
    } else if (uart == USART2) {
        com2_RxHalfCpltCallback();
    } else if (uart == USART3) {
        com3_RxHalfCpltCallback();

    } else if (uart == UART4) {
    } else {
        error_handle();
    }
}

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *handle) {
    USART_TypeDef *uart = handle->Instance;
    if (uart == USART1) {
        com1_RxCpltCallback();
    } else if (uart == USART2) {
        com2_RxCpltCallback();
    } else if (uart == USART3) {
        com3_RxCpltCallback();
    } else if (uart == UART4) {
    } else {
        error_handle();
    }

}
/*-*****************************************串口1弱引用**********************************************-*/
__weak void com1_gpio_msp_init() {

    stm32_pin_define_mode_set(stm_get_pin(COM1_TX), pin_mode_af_pp);
    stm32_pin_define_mode_set(stm_get_pin(COM1_RX), pin_mode_input);
}

__weak void com1_gpio_msp_de_init() {
    //PA9------> USART1_TX   PA10------> USART1_RX
    stm32_pin_define_reset(stm_get_pin(COM1_TX));
    stm32_pin_define_reset(stm_get_pin(COM1_RX));
}

__weak void com1_it_msp_init(void) {
    //  @note 框架不实现,需要重新定义此方法
    //    HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
    //    HAL_NVIC_EnableIRQ(USART1_IRQn);
}

__weak void com1_it_msp_de_init(void) {
    /* USART1 interrupt Deinit */
    //  @note 框架不实现,需要重新定义此方法
    //    HAL_NVIC_DisableIRQ(USART1_IRQn);
}/*com1*/
__weak void com1_dma_tx_msp_init(void) {}

__weak void com1_dma_tx_msp_de_init(void) {}/*com1*/
__weak void com1_dma_rx_msp_init(void) {}/*com1*/
__weak void com1_dma_rx_msp_de_init(void) {}/*com1*/
__weak void com1_ErrorCallback() {}/*com1*/
__weak void com1_RxHalfCpltCallback() {}/*com1*/
__weak void com1_RxCpltCallback() {}/*com1*/
__weak void com1_RxEventCallback(uint16_t Size) {}/*com1*/
/*-*****************************************串口2弱引用**********************************************-*/
__weak void com2_gpio_msp_init() {
    /* io init */
    stm32_pin_define_mode_set(stm_get_pin(COM2_TX), pin_mode_af_pp);
    stm32_pin_define_mode_set(stm_get_pin(COM2_RX), pin_mode_input);

}

__weak void com2_gpio_msp_de_init() {
    stm32_pin_define_reset(stm_get_pin(COM2_TX));
    stm32_pin_define_reset(stm_get_pin(COM2_RX));
}

__weak void com2_it_msp_init(void) {
    //  @note 框架不实现,需要重新定义此方法
    //    HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
    //    HAL_NVIC_EnableIRQ(USART2_IRQn);
} /*com*/
__weak void com2_it_msp_de_init(void) {}/*com*/
__weak void com2_dma_tx_msp_init(void) {}/*com*/
__weak void com2_dma_tx_msp_de_init(void) {}/*com*/
__weak void com2_dma_rx_msp_init(void) {}/*com*/
__weak void com2_dma_rx_msp_de_init(void) {}/*com*/
__weak void com2_ErrorCallback() {}/*com*/
__weak void com2_RxHalfCpltCallback() {}/*com*/
__weak void com2_RxCpltCallback() {}/*com*/
__weak void com2_RxEventCallback(uint16_t Size) {}/*com*/

/*-*****************************************串口3弱引用**********************************************-*/
__weak void com3_it_msp_init(void) {
    //  @note 框架不实现,需要重新定义此方法
    //    HAL_NVIC_SetPriority(USART3_IRQn, 0, 0);
    //    HAL_NVIC_EnableIRQ(USART3_IRQn);
} /*com*/
__weak void com3_gpio_msp_init() {
    /* io init */
    stm32_pin_define_mode_set(stm_get_pin(COM3_TX), pin_mode_af_pp);
    stm32_pin_define_mode_set(stm_get_pin(COM3_RX), pin_mode_input);
}

__weak void com3_gpio_msp_de_init() {
    stm32_pin_define_reset(stm_get_pin(COM3_TX));
    stm32_pin_define_reset(stm_get_pin(COM3_RX));
}

__weak void com3_it_msp_de_init(void) {}/*com*/
__weak void com3_dma_tx_msp_init(void) {}/*com*/
__weak void com3_dma_tx_msp_de_init(void) {}/*com*/
__weak void com3_dma_rx_msp_init(void) {}/*com*/
__weak void com3_dma_rx_msp_de_init(void) {}/*com*/
__weak void com3_ErrorCallback() {}/*com*/
__weak void com3_RxHalfCpltCallback() {}/*com*/
__weak void com3_RxCpltCallback() {}/*com*/
__weak void com3_RxEventCallback(uint16_t Size) {}/*com*/
相关推荐
scan13 小时前
单片机串口接收状态机STM32
stm32·单片机·串口·51·串口接收
Qingniu014 小时前
【青牛科技】应用方案 | RTC实时时钟芯片D8563和D1302
科技·单片机·嵌入式硬件·实时音视频·安防·工控·储能
Mortal_hhh5 小时前
VScode的C/C++点击转到定义,不是跳转定义而是跳转声明怎么办?(内附详细做法)
ide·vscode·stm32·编辑器
深圳市青牛科技实业有限公司5 小时前
【青牛科技】应用方案|D2587A高压大电流DC-DC
人工智能·科技·单片机·嵌入式硬件·机器人·安防监控
Mr.谢尔比6 小时前
电赛入门之软件stm32keil+cubemx
stm32·单片机·嵌入式硬件·mcu·信息与通信·信号处理
LightningJie6 小时前
STM32中ARR(自动重装寄存器)为什么要减1
stm32·单片机·嵌入式硬件
鹿屿二向箔6 小时前
STM32外设之SPI的介绍
stm32
西瓜籽@7 小时前
STM32——毕设基于单片机的多功能节能窗控制系统
stm32·单片机·课程设计
远翔调光芯片^138287988729 小时前
远翔升压恒流芯片FP7209X与FP7209M什么区别?做以下应用市场摄影补光灯、便携灯、智能家居(调光)市场、太阳能、车灯、洗墙灯、舞台灯必看!
科技·单片机·智能家居·能源
极客小张10 小时前
基于STM32的智能充电桩:集成RTOS、MQTT与SQLite的先进管理系统设计思路
stm32·单片机·嵌入式硬件·mqtt·sqlite·毕业设计·智能充电桩