引用参考:
/*******************************************************************************
* 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
#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*/