STM32H7的8个串口fifo收发(兼容232和485)
/* 串口1的GPIO PA9, PA10 RS323 DB9接口 */
#define USART1_CLK_ENABLE() __HAL_RCC_USART1_CLK_ENABLE()
#define USART1_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define USART1_TX_GPIO_PORT GPIOA
#define USART1_TX_PIN GPIO_PIN_9
#define USART1_TX_AF GPIO_AF7_USART1
#define USART1_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define USART1_RX_GPIO_PORT GPIOA
#define USART1_RX_PIN GPIO_PIN_10
#define USART1_RX_AF GPIO_AF7_USART1
/* 串口2的GPIO --- PA2 PA3 GPS (只用RX。 TX被以太网占用) */
#define USART2_CLK_ENABLE() __HAL_RCC_USART2_CLK_ENABLE()
#define USART2_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define USART2_TX_GPIO_PORT GPIOA
#define USART2_TX_PIN GPIO_PIN_2
#define USART2_TX_AF GPIO_AF7_USART2
#define USART2_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOA_CLK_ENABLE()
#define USART2_RX_GPIO_PORT GPIOA
#define USART2_RX_PIN GPIO_PIN_3
#define USART2_RX_AF GPIO_AF7_USART2
/* 串口3的GPIO --- PB10 PB11 RS485 */
#define USART3_CLK_ENABLE() __HAL_RCC_USART3_CLK_ENABLE()
#define USART3_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define USART3_TX_GPIO_PORT GPIOB
#define USART3_TX_PIN GPIO_PIN_10
#define USART3_TX_AF GPIO_AF7_USART3
#define USART3_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define USART3_RX_GPIO_PORT GPIOB
#define USART3_RX_PIN GPIO_PIN_11
#define USART3_RX_AF GPIO_AF7_USART3
/* 串口4的GPIO --- PC10 PC11 被SD卡占用 */
#define UART4_CLK_ENABLE() __HAL_RCC_UART4_CLK_ENABLE()
#define UART4_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
#define UART4_TX_GPIO_PORT GPIOC
#define UART4_TX_PIN GPIO_PIN_10
#define UART4_TX_AF GPIO_AF8_UART4
#define UART4_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
#define UART4_RX_GPIO_PORT GPIOC
#define UART4_RX_PIN GPIO_PIN_11
#define UART4_RX_AF GPIO_AF8_UART4
/* 串口5的GPIO --- PC12/UART5_TX PD2/UART5_RX (被SD卡占用) */
#define UART5_CLK_ENABLE() __HAL_RCC_UART5_CLK_ENABLE()
#define UART5_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
#define UART5_TX_GPIO_PORT GPIOC
#define UART5_TX_PIN GPIO_PIN_12
#define UART5_TX_AF GPIO_AF8_UART5
#define UART5_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOD_CLK_ENABLE()
#define UART5_RX_GPIO_PORT GPIOD
#define UART5_RX_PIN GPIO_PIN_2
#define UART5_RX_AF GPIO_AF8_UART5
/* 串口6的GPIO --- PG14 PC7 GPRS */
#define USART6_CLK_ENABLE() __HAL_RCC_USART6_CLK_ENABLE()
#define USART6_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOG_CLK_ENABLE()
#define USART6_TX_GPIO_PORT GPIOG
#define USART6_TX_PIN GPIO_PIN_14
#define USART6_TX_AF GPIO_AF7_USART6
#define USART6_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOC_CLK_ENABLE()
#define USART6_RX_GPIO_PORT GPIOC
#define USART6_RX_PIN GPIO_PIN_7
#define USART6_RX_AF GPIO_AF7_USART6
/* 串口7的GPIO --- PB4/UART7_TX, PB3/UART7_RX (被SPI3 占用) */
#define UART7_CLK_ENABLE() __HAL_RCC_UART7_CLK_ENABLE()
#define UART7_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define UART7_TX_GPIO_PORT GPIOB
#define UART7_TX_PIN GPIO_PIN_4
#define UART7_TX_AF GPIO_AF11_UART7
#define UART7_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define UART7_RX_GPIO_PORT GPIOB
#define UART7_RX_PIN GPIO_PIN_3
#define UART7_RX_AF GPIO_AF11_UART7
/* 串口8的GPIO --- PJ8/UART8_TX, PJ9/UART8_RX (RGB硬件接口占用) */
#define UART8_CLK_ENABLE() __HAL_RCC_UART8_CLK_ENABLE()
#define UART8_TX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE()
#define UART8_TX_GPIO_PORT GPIOJ
#define UART8_TX_PIN GPIO_PIN_8
#define UART8_TX_AF GPIO_AF8_UART8
#define UART8_RX_GPIO_CLK_ENABLE() __HAL_RCC_GPIOJ_CLK_ENABLE()
#define UART8_RX_GPIO_PORT GPIOJ
#define UART8_RX_PIN GPIO_PIN_9
#define UART8_RX_AF GPIO_AF8_UART8
/* 定义每个串口结构体变量 */
#if UART1_FIFO_EN == 1
static UART_T g_tUart1;
static uint8_t g_TxBuf1[UART1_TX_BUF_SIZE]; /* 发送缓冲区 */
static uint8_t g_RxBuf1[UART1_RX_BUF_SIZE]; /* 接收缓冲区 */
#endif
#if UART2_FIFO_EN == 1
static UART_T g_tUart2;
static uint8_t g_TxBuf2[UART2_TX_BUF_SIZE]; /* 发送缓冲区 */
static uint8_t g_RxBuf2[UART2_RX_BUF_SIZE]; /* 接收缓冲区 */
#endif
#if UART3_FIFO_EN == 1
static UART_T g_tUart3;
static uint8_t g_TxBuf3[UART3_TX_BUF_SIZE]; /* 发送缓冲区 */
static uint8_t g_RxBuf3[UART3_RX_BUF_SIZE]; /* 接收缓冲区 */
#endif
#if UART4_FIFO_EN == 1
static UART_T g_tUart4;
static uint8_t g_TxBuf4[UART4_TX_BUF_SIZE]; /* 发送缓冲区 */
static uint8_t g_RxBuf4[UART4_RX_BUF_SIZE]; /* 接收缓冲区 */
#endif
#if UART5_FIFO_EN == 1
static UART_T g_tUart5;
static uint8_t g_TxBuf5[UART5_TX_BUF_SIZE]; /* 发送缓冲区 */
static uint8_t g_RxBuf5[UART5_RX_BUF_SIZE]; /* 接收缓冲区 */
#endif
#if UART6_FIFO_EN == 1
static UART_T g_tUart6;
static uint8_t g_TxBuf6[UART6_TX_BUF_SIZE]; /* 发送缓冲区 */
static uint8_t g_RxBuf6[UART6_RX_BUF_SIZE]; /* 接收缓冲区 */
#endif
#if UART7_FIFO_EN == 1
static UART_T g_tUart7;
static uint8_t g_TxBuf7[UART7_TX_BUF_SIZE]; /* 发送缓冲区 */
static uint8_t g_RxBuf7[UART7_RX_BUF_SIZE]; /* 接收缓冲区 */
#endif
#if UART8_FIFO_EN == 1
static UART_T g_tUart8;
static uint8_t g_TxBuf8[UART8_TX_BUF_SIZE]; /* 发送缓冲区 */
static uint8_t g_RxBuf8[UART8_RX_BUF_SIZE]; /* 接收缓冲区 */
#endif
static void UartVarInit(void);
static void InitHardUart(void);
static void UartSend(UART_T *_pUart, uint8_t *_ucaBuf, uint16_t _usLen);
static uint8_t UartGetChar(UART_T *_pUart, uint8_t *_pByte);
static void UartIRQ(UART_T *_pUart);
void RS485_InitTXE(void);
/*
*********************************************************************************************************
* 函 数 名: bsp_InitUart
* 功能说明: 初始化串口硬件,并对全局变量赋初值.
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_InitUart(void)
{
UartVarInit(); /* 必须先初始化全局变量,再配置硬件 */
InitHardUart(); /* 配置串口的硬件参数(波特率等) */
RS485_InitTXE(); /* 配置RS485芯片的发送使能硬件,配置为推挽输出 */
}
/*
*********************************************************************************************************
* 函 数 名: ComToUart
* 功能说明: 将COM端口号转换为UART指针
* 形 参: _ucPort: 端口号(COM1 - COM8)
* 返 回 值: uart指针
*********************************************************************************************************
*/
UART_T *ComToUart(COM_PORT_E _ucPort)
{
if (_ucPort == COM1)
{
#if UART1_FIFO_EN == 1
return &g_tUart1;
#else
return 0;
#endif
}
else if (_ucPort == COM2)
{
#if UART2_FIFO_EN == 1
return &g_tUart2;
#else
return 0;
#endif
}
else if (_ucPort == COM3)
{
#if UART3_FIFO_EN == 1
return &g_tUart3;
#else
return 0;
#endif
}
else if (_ucPort == COM4)
{
#if UART4_FIFO_EN == 1
return &g_tUart4;
#else
return 0;
#endif
}
else if (_ucPort == COM5)
{
#if UART5_FIFO_EN == 1
return &g_tUart5;
#else
return 0;
#endif
}
else if (_ucPort == COM6)
{
#if UART6_FIFO_EN == 1
return &g_tUart6;
#else
return 0;
#endif
}
else if (_ucPort == COM7)
{
#if UART7_FIFO_EN == 1
return &g_tUart7;
#else
return 0;
#endif
}
else if (_ucPort == COM8)
{
#if UART8_FIFO_EN == 1
return &g_tUart8;
#else
return 0;
#endif
}
else
{
Error_Handler(__FILE__, __LINE__);
return 0;
}
}
/*
*********************************************************************************************************
* 函 数 名: ComToUart
* 功能说明: 将COM端口号转换为 USART_TypeDef* USARTx
* 形 参: _ucPort: 端口号(COM1 - COM8)
* 返 回 值: USART_TypeDef*, USART1, USART2, USART3, UART4, UART5,USART6,UART7,UART8。
*********************************************************************************************************
*/
USART_TypeDef *ComToUSARTx(COM_PORT_E _ucPort)
{
if (_ucPort == COM1)
{
#if UART1_FIFO_EN == 1
return USART1;
#else
return 0;
#endif
}
else if (_ucPort == COM2)
{
#if UART2_FIFO_EN == 1
return USART2;
#else
return 0;
#endif
}
else if (_ucPort == COM3)
{
#if UART3_FIFO_EN == 1
return USART3;
#else
return 0;
#endif
}
else if (_ucPort == COM4)
{
#if UART4_FIFO_EN == 1
return UART4;
#else
return 0;
#endif
}
else if (_ucPort == COM5)
{
#if UART5_FIFO_EN == 1
return UART5;
#else
return 0;
#endif
}
else if (_ucPort == COM6)
{
#if UART6_FIFO_EN == 1
return USART6;
#else
return 0;
#endif
}
else if (_ucPort == COM7)
{
#if UART7_FIFO_EN == 1
return UART7;
#else
return 0;
#endif
}
else if (_ucPort == COM8)
{
#if UART8_FIFO_EN == 1
return UART8;
#else
return 0;
#endif
}
else
{
/* 不做任何处理 */
return 0;
}
}
/*
*********************************************************************************************************
* 函 数 名: comSendBuf
* 功能说明: 向串口发送一组数据。数据放到发送缓冲区后立即返回,由中断服务程序在后台完成发送
* 形 参: _ucPort: 端口号(COM1 - COM8)
* _ucaBuf: 待发送的数据缓冲区
* _usLen : 数据长度
* 返 回 值: 无
*********************************************************************************************************
*/
void comSendBuf(COM_PORT_E _ucPort, uint8_t *_ucaBuf, uint16_t _usLen)
{
UART_T *pUart;
pUart = ComToUart(_ucPort);
if (pUart == 0)
{
return;
}
if (pUart->SendBefor != 0)
{
pUart->SendBefor(); /* 如果是RS485通信,可以在这个函数中将RS485设置为发送模式 */
}
UartSend(pUart, _ucaBuf, _usLen);
}
/*
*********************************************************************************************************
* 函 数 名: comSendChar
* 功能说明: 向串口发送1个字节。数据放到发送缓冲区后立即返回,由中断服务程序在后台完成发送
* 形 参: _ucPort: 端口号(COM1 - COM8)
* _ucByte: 待发送的数据
* 返 回 值: 无
*********************************************************************************************************
*/
void comSendChar(COM_PORT_E _ucPort, uint8_t _ucByte)
{
comSendBuf(_ucPort, &_ucByte, 1);
}
/*
*********************************************************************************************************
* 函 数 名: comGetChar
* 功能说明: 从接收缓冲区读取1字节,非阻塞。无论有无数据均立即返回。
* 形 参: _ucPort: 端口号(COM1 - COM8)
* _pByte: 接收到的数据存放在这个地址
* 返 回 值: 0 表示无数据, 1 表示读取到有效字节
*********************************************************************************************************
*/
uint8_t comGetChar(COM_PORT_E _ucPort, uint8_t *_pByte)
{
UART_T *pUart;
pUart = ComToUart(_ucPort);
if (pUart == 0)
{
return 0;
}
return UartGetChar(pUart, _pByte);
}
/*
*********************************************************************************************************
* 函 数 名: comClearTxFifo
* 功能说明: 清零串口发送缓冲区
* 形 参: _ucPort: 端口号(COM1 - COM8)
* 返 回 值: 无
*********************************************************************************************************
*/
void comClearTxFifo(COM_PORT_E _ucPort)
{
UART_T *pUart;
pUart = ComToUart(_ucPort);
if (pUart == 0)
{
return;
}
pUart->usTxWrite = 0;
pUart->usTxRead = 0;
pUart->usTxCount = 0;
}
/*
*********************************************************************************************************
* 函 数 名: comClearRxFifo
* 功能说明: 清零串口接收缓冲区
* 形 参: _ucPort: 端口号(COM1 - COM8)
* 返 回 值: 无
*********************************************************************************************************
*/
void comClearRxFifo(COM_PORT_E _ucPort)
{
UART_T *pUart;
pUart = ComToUart(_ucPort);
if (pUart == 0)
{
return;
}
pUart->usRxWrite = 0;
pUart->usRxRead =