Files
Leakage-Control/leakage_system/usr/bsp/bsp_uart.c
T
2026-04-23 17:20:51 +08:00

665 lines
17 KiB
C

#include "bsp_uart.h"
#include "string.h"
/* RS485控制宏定义 */
#define RS485_1_RX HAL_GPIO_WritePin(RS485_1_EN_GPIO_Port, RS485_1_EN_Pin, GPIO_PIN_RESET)
#define RS485_1_TX HAL_GPIO_WritePin(RS485_1_EN_GPIO_Port, RS485_1_EN_Pin, GPIO_PIN_SET)
#define RS485_2_RX HAL_GPIO_WritePin(RS485_2_EN_GPIO_Port, RS485_2_EN_Pin, GPIO_PIN_RESET)
#define RS485_2_TX HAL_GPIO_WritePin(RS485_2_EN_GPIO_Port, RS485_2_EN_Pin, GPIO_PIN_SET)
#define RS485_3_RX HAL_GPIO_WritePin(RS485_3_EN_GPIO_Port, RS485_3_EN_Pin, GPIO_PIN_RESET)
#define RS485_3_TX HAL_GPIO_WritePin(RS485_3_EN_GPIO_Port, RS485_3_EN_Pin, GPIO_PIN_SET)
#define RS485_4_RX HAL_GPIO_WritePin(RS485_4_EN_GPIO_Port, RS485_4_EN_Pin, GPIO_PIN_RESET)
#define RS485_4_TX HAL_GPIO_WritePin(RS485_4_EN_GPIO_Port, RS485_4_EN_Pin, GPIO_PIN_SET)
/* 缓冲收发区大小 */
#define RX_TEMP_BUFF_NUM (128U)
/* UART缓冲区大小定义 */
#define UART1_TX_LEN (128U)
#define UART1_RX_LEN (128U)
#define UART2_TX_LEN (128U)
#define UART2_RX_LEN (128U)
#define UART3_TX_LEN (128U)
#define UART3_RX_LEN (128U)
#define UART4_TX_LEN (128U)
#define UART4_RX_LEN (128U)
#define UART6_TX_LEN (128U)
#define UART6_RX_LEN (128U)
/* 全局缓冲区变量 */
u8 uart1_tx_buff[UART1_TX_LEN];
u8 uart1_rx_buff[UART1_RX_LEN];
u8 uart2_tx_buff[UART2_TX_LEN];
u8 uart2_rx_buff[UART2_RX_LEN];
u8 uart3_tx_buff[UART3_TX_LEN];
u8 uart3_rx_buff[UART3_RX_LEN];
u8 uart4_tx_buff[UART4_TX_LEN];
u8 uart4_rx_buff[UART4_RX_LEN];
u8 uart6_tx_buff[UART6_TX_LEN];
u8 uart6_rx_buff[UART6_RX_LEN];
u8 rx_temp_buff[RX_TEMP_BUFF_NUM];
/* 函数声明 */
static void bsp_uart_init(bsp_uart_t *p_uart);
static void bsp_uart_send(bsp_uart_t *p_uart, u8 *p_data, u16 len);
static void bsp_uart_rx_idle_int(bsp_uart_t *p_uart);
static void bsp_uart_rx_time_increment(bsp_uart_t *p_uart, u16 time);
static void bsp_uart_rx_task(bsp_uart_t *p_uart);
static void bsp_uart_rx_time_start(bsp_uart_t *p_uart);
static void bsp_uart_tx_dma_tc_int(bsp_uart_t *p_uart);
static void bsp_uart_dma_send(bsp_uart_t *p_uart, u8 *p_data, u16 len);
static void bsp_uart_baud_rate_set(bsp_uart_t *p_uart,u32 baud_rate);
/* 外部HAL句柄声明 */
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;
extern UART_HandleTypeDef huart4;
extern UART_HandleTypeDef huart6;
extern DMA_HandleTypeDef hdma_usart1_rx;
extern DMA_HandleTypeDef hdma_usart1_tx;
extern DMA_HandleTypeDef hdma_usart2_rx;
extern DMA_HandleTypeDef hdma_usart2_tx;
extern DMA_HandleTypeDef hdma_usart3_rx;
extern DMA_HandleTypeDef hdma_usart3_tx;
extern DMA_HandleTypeDef hdma_uart4_rx;
extern DMA_HandleTypeDef hdma_uart4_tx;
extern DMA_HandleTypeDef hdma_usart6_rx;
extern DMA_HandleTypeDef hdma_usart6_tx;
/******************************************
* 结构体: com_uart1
* 功能: UART1控制实例
* 描述: 定义UART1的硬件参数和回调函数
*******************************************/
bsp_uart_t com_uart1 =
{
.rx_queue = queue(u8, UART1_RX_LEN),
.uart = &huart1,
.tx_dma = &hdma_usart1_tx,
.rx_dma = &hdma_usart1_rx,
.tx_dma_len = UART1_TX_LEN,
.rx_dma_len = UART1_RX_LEN,
.tx_addr = &uart1_tx_buff[0],
.rx_addr = &uart1_rx_buff[0],
.tx_dma_complete_flag = 1,
.rx_time_over = 0,
.relay.uart = NULL,
.init = bsp_uart_init,
.send = bsp_uart_send,
.set = bsp_uart_baud_rate_set,
.tx_dma_tc_int = bsp_uart_tx_dma_tc_int,
.rx_idle_int = bsp_uart_rx_idle_int,
.rx_time_increment_int = bsp_uart_rx_time_increment,
.rx_data_analysis = NULL,
.rx_task = bsp_uart_rx_task,
};
/******************************************
* 结构体: com_uart2
* 功能: UART2控制实例
* 描述: 定义UART2的硬件参数和回调函数
*******************************************/
bsp_uart_t com_uart2 =
{
.rx_queue = queue(u8, UART2_RX_LEN),
.uart = &huart2,
.tx_dma = &hdma_usart2_tx,
.rx_dma = &hdma_usart2_rx,
.tx_dma_len = UART2_TX_LEN,
.rx_dma_len = UART2_RX_LEN,
.tx_addr = &uart2_tx_buff[0],
.rx_addr = &uart2_rx_buff[0],
.tx_dma_complete_flag = 1,
.rx_time_over = 0,
.relay.uart = &com_uart4,
.set = bsp_uart_baud_rate_set,
.init = bsp_uart_init,
.send = bsp_uart_send,
.tx_dma_tc_int = bsp_uart_tx_dma_tc_int,
.rx_idle_int = bsp_uart_rx_idle_int,
.rx_time_increment_int = bsp_uart_rx_time_increment,
.rx_data_analysis = NULL,
.rx_task = bsp_uart_rx_task,
};
/******************************************
* 结构体: com_uart3
* 功能: UART2控制实例
* 描述: 定义UART2的硬件参数和回调函数
*******************************************/
bsp_uart_t com_uart3 =
{
.rx_queue = queue(u8, UART3_RX_LEN),
.uart = &huart3,
.tx_dma = &hdma_usart3_tx,
.rx_dma = &hdma_usart3_rx,
.tx_dma_len = UART3_TX_LEN,
.rx_dma_len = UART3_RX_LEN,
.tx_addr = &uart3_tx_buff[0],
.rx_addr = &uart3_rx_buff[0],
.tx_dma_complete_flag = 1,
.rx_time_over = 0,
.relay.uart = &com_uart3,
.set = bsp_uart_baud_rate_set,
.init = bsp_uart_init,
.send = bsp_uart_send,
.tx_dma_tc_int = bsp_uart_tx_dma_tc_int,
.rx_idle_int = bsp_uart_rx_idle_int,
.rx_time_increment_int = bsp_uart_rx_time_increment,
.rx_data_analysis = NULL,
.rx_task = bsp_uart_rx_task,
};
/******************************************
* 结构体: com_uart4
* 功能: UART4控制实例
* 描述: 定义UART4的硬件参数和回调函数
*******************************************/
bsp_uart_t com_uart4 =
{
.rx_queue = queue(u8, UART4_RX_LEN),
.uart = &huart4,
.tx_dma = &hdma_uart4_tx,
.rx_dma = &hdma_uart4_rx,
.tx_dma_len = UART4_TX_LEN,
.rx_dma_len = UART4_RX_LEN,
.tx_addr = &uart4_tx_buff[0],
.rx_addr = &uart4_rx_buff[0],
.tx_dma_complete_flag = 1,
.rx_time_over = 0,
.relay.uart = NULL,
.set = bsp_uart_baud_rate_set,
.init = bsp_uart_init,
.send = bsp_uart_send,
.tx_dma_tc_int = bsp_uart_tx_dma_tc_int,
.rx_idle_int = bsp_uart_rx_idle_int,
.rx_time_increment_int = bsp_uart_rx_time_increment,
.rx_data_analysis = NULL,
.rx_task = bsp_uart_rx_task,
};
/******************************************
* 结构体: com_uart6
* 功能: UART6控制实例
* 描述: 定义UART4的硬件参数和回调函数
*******************************************/
bsp_uart_t com_uart6 =
{
.rx_queue = queue(u8, UART6_RX_LEN),
.uart = &huart6,
.tx_dma = &hdma_usart6_tx,
.rx_dma = &hdma_usart6_rx,
.tx_dma_len = UART6_TX_LEN,
.rx_dma_len = UART6_RX_LEN,
.tx_addr = &uart6_tx_buff[0],
.rx_addr = &uart6_rx_buff[0],
.tx_dma_complete_flag = 1,
.rx_time_over = 0,
.relay.uart = NULL,
.set = bsp_uart_baud_rate_set,
.init = bsp_uart_init,
.send = bsp_uart_send,
.tx_dma_tc_int = bsp_uart_tx_dma_tc_int,
.rx_idle_int = bsp_uart_rx_idle_int,
.rx_time_increment_int = bsp_uart_rx_time_increment,
.rx_data_analysis = NULL,
.rx_task = bsp_uart_rx_task,
};
/******************************************
* 函数: bsp_uart_init
* 功能: UART初始化
* 参数: p_uart - 指向UART结构体的指针
* 返回: 无
* 描述: 初始化UART,使能空闲中断和DMA接收
*******************************************/
static void bsp_uart_init(bsp_uart_t *p_uart)
{
/* 启用空闲中断 */
__HAL_UART_ENABLE_IT(p_uart->uart, UART_IT_IDLE);
/* 重新启动接收,使用空闲中断模式 */
HAL_UARTEx_ReceiveToIdle_DMA(p_uart->uart, p_uart->rx_addr, p_uart->rx_dma_len);
}
static void bsp_uart_baud_rate_set(bsp_uart_t *p_uart,u32 baud_rate)
{
p_uart->uart->Init.BaudRate = baud_rate;
HAL_UART_Init(p_uart->uart);
}
static void bsp_uart_tx_begin_call_back(bsp_uart_t *p_uart)
{
/* RS485切换到发送模式 */
if(p_uart == &com_uart4)
{
RS485_1_TX;
}
else if(p_uart == &com_uart2)
{
RS485_2_TX;
}
else if(p_uart == &com_uart3)
{
RS485_3_TX;
}
else if(p_uart == &com_uart6)
{
RS485_4_TX;
}
}
static void bsp_uart_tx_end_call_back(bsp_uart_t *p_uart)
{
/* RS485切换到发送模式 */
if(p_uart == &com_uart4)
{
RS485_1_RX;
}
else if(p_uart == &com_uart2)
{
RS485_2_RX;
}
else if(p_uart == &com_uart3)
{
RS485_3_RX;
}
else if(p_uart == &com_uart6)
{
RS485_4_RX;
}
}
/******************************************
* 函数: bsp_uart_dma_send
* 功能: DMA发送函数
* 参数: p_uart - 指向UART结构体的指针
* p_data - 要发送的数据指针
* len - 要发送的数据长度
* 返回: 无
* 描述: 使用DMA发送数据,带有超时检测
*******************************************/
static void bsp_uart_dma_send(bsp_uart_t *p_uart, u8 *p_data, u16 len)
{
u32 tick_start, tick;
p_uart->tx_dma_complete_flag = 0;
/* 如果请求发送的长度大于缓冲区长度,则截断 */
if(p_uart->tx_dma_len < len)
len = p_uart->tx_dma_len;
/* 拷贝数据到发送缓冲区 */
memcpy(p_uart->tx_addr, p_data, len);
HAL_UART_Transmit(p_uart->uart, p_uart->tx_addr, len,50);
// /* 启动DMA发送 */
// HAL_UART_Transmit_DMA(p_uart->uart, p_uart->tx_addr, len);
//
// /* 等待发送完成,带超时检测 */
// tick_start = HAL_GetTick();
// while(!p_uart->tx_dma_complete_flag)
// {
// tick = HAL_GetTick();
// if((tick - tick_start) > 200) /* 200ms超时 */
// {
// p_uart->tx_dma_complete_flag = 1;
// break;
// }
// }
}
/******************************************
* 函数: bsp_uart_send
* 功能: UART发送函数
* 参数: p_uart - 指向UART结构体的指针
* p_data - 要发送的数据指针
* len - 要发送的数据长度
* 返回: 无
* 描述: 大数据量发送函数,支持分块发送
*******************************************/
static void bsp_uart_send(bsp_uart_t *p_uart, u8 *p_data, u16 len)
{
u16 i, send_num;
bsp_uart_tx_begin_call_back(p_uart);
/* 计算需要发送的次数 */
send_num = len / p_uart->tx_dma_len;
/* 分块发送数据 */
for(i = 0; i < send_num; i++)
{
bsp_uart_dma_send(p_uart, &p_data[p_uart->tx_dma_len * i], p_uart->tx_dma_len);
}
/* 发送剩余数据 */
len -= p_uart->tx_dma_len * i;
if(0 != len)
{
bsp_uart_dma_send(p_uart, &p_data[p_uart->tx_dma_len * i], len);
}
bsp_uart_tx_end_call_back(p_uart);
}
/******************************************
* 函数: bsp_uart_tx_dma_tc_int
* 功能: DMA发送完成中断处理
* 参数: p_uart - 指向UART结构体的指针
* 返回: 无
* 描述: 在DMA发送完成中断中调用,设置发送完成标志
*******************************************/
static void bsp_uart_tx_dma_tc_int(bsp_uart_t *p_uart)
{
p_uart->tx_dma_complete_flag = 1;
}
/******************************************
* 函数: bsp_uart_rx_idle_int
* 功能: 空闲中断处理
* 参数: p_uart - 指向UART结构体的指针
* 返回: 无
* 描述: 处理UART空闲中断,将接收到的数据存入队列
*******************************************/
static void bsp_uart_rx_idle_int(bsp_uart_t *p_uart)
{
u16 rx_length, i;
/* 停止接收 */
HAL_UART_DMAStop(p_uart->uart);
/* 计算接收到的数据长度 */
rx_length = p_uart->rx_dma_len - __HAL_DMA_GET_COUNTER(p_uart->rx_dma);
/* 如果长度为0,直接返回 */
if (rx_length == 0)
{
return;
}
/* 将接收到的数据存入队列 */
for (i = 0; i < rx_length; i++)
{
queue_push_back(p_uart->rx_queue, (void *)&p_uart->rx_addr[i]);
}
/* 开始接收超时计时 */
bsp_uart_rx_time_start(p_uart);
/* 重新启动接收 */
HAL_UARTEx_ReceiveToIdle_DMA(p_uart->uart, p_uart->rx_addr, p_uart->rx_dma_len);
}
/******************************************
* 函数: bsp_uart_rx_time_increment
* 功能: 接收超时时间递增
* 参数: p_uart - 指向UART结构体的指针
* time - 增加的时间值
* 返回: 无
* 描述: 在中断中调用,递增接收超时计数器
*******************************************/
static void bsp_uart_rx_time_increment(bsp_uart_t *p_uart, u16 time)
{
/* 如果已经开始计数,则增加时间 */
if(1 == p_uart->rx_start_flag)
{
p_uart->rx_time_count += time;
}
}
/******************************************
* 函数: bsp_uart_rx_time_start
* 功能: 启动接收超时计时
* 参数: p_uart - 指向UART结构体的指针
* 返回: 无
* 描述: 开始接收超时计数
*******************************************/
static void bsp_uart_rx_time_start(bsp_uart_t *p_uart)
{
p_uart->rx_start_flag = 1;
p_uart->rx_time_count = 0;
}
/******************************************
* 函数: bsp_uart_rx_time_stop
* 功能: 停止接收超时计时
* 参数: p_uart - 指向UART结构体的指针
* 返回: 无
* 描述: 停止接收超时计数
*******************************************/
static void bsp_uart_rx_time_stop(bsp_uart_t *p_uart)
{
p_uart->rx_start_flag = 0;
p_uart->rx_time_count = 0;
}
/******************************************
* 函数: bsp_uart_rx_task
* 功能: UART接收任务
* 参数: p_uart - 指向UART结构体的指针
* 返回: 无
* 描述: 检查接收超时,处理接收到的数据帧
*******************************************/
static void bsp_uart_rx_task(bsp_uart_t *p_uart)
{
/* 检查是否超时,接收到一帧数据 */
if(p_uart->rx_time_over < p_uart->rx_time_count)
{
/* 获取队列中数据长度 */
p_uart->rx_len = queue_size(p_uart->rx_queue);
/* 停止计时 */
bsp_uart_rx_time_stop(p_uart);
/* 检查数据长度是否有效 */
if(p_uart->rx_len <= p_uart->rx_dma_len && (0 != p_uart->rx_len))
{
/* 如果数据长度超过临时缓冲区大小,则清空队列 */
if(RX_TEMP_BUFF_NUM < p_uart->rx_len)
{
queue_clear(p_uart->rx_queue);
}
else
{
/* 从队列中取出数据到临时缓冲区 */
for(u16 i = 0; i < p_uart->rx_len; i++)
{
queue_pop(p_uart->rx_queue, &rx_temp_buff[i]);
}
/* 如果有数据解析函数,则调用解析函数 */
if(NULL != p_uart->rx_data_analysis)
{
p_uart->rx_data_analysis(rx_temp_buff, p_uart->rx_len, p_uart);
}
// if(p_uart == &com_uart6)
// {
// p_uart->send(p_uart, rx_temp_buff, p_uart->rx_len);
// }
}
}
}
}
// 错误回调函数中处理ORE
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
bsp_uart_t *p_uart = NULL;
if (huart->Instance == USART1)
{
p_uart = &com_uart1;
}
else if (huart->Instance == USART2)
{
p_uart = &com_uart2;
}
else if (huart->Instance == USART3)
{
p_uart = &com_uart3;
}
else if (huart->Instance == UART4)
{
p_uart = &com_uart4;
}
else if (huart->Instance == USART6)
{
p_uart = &com_uart6;
}
// 检查具体错误类型
if(huart->ErrorCode & HAL_UART_ERROR_NE)
{
// 处理噪声错误
__HAL_UART_CLEAR_NEFLAG(huart);
}
if(huart->ErrorCode & HAL_UART_ERROR_FE)
{
// 处理帧错误
__HAL_UART_CLEAR_FEFLAG(huart);
}
// 其他错误处理...
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_ORE) != RESET)
{
__HAL_UART_CLEAR_OREFLAG(huart); // 清除ORE标志
}
if (__HAL_UART_GET_FLAG(huart, UART_FLAG_FE) != RESET)
{
__HAL_UART_CLEAR_FEFLAG(huart); // 清除ORE标志
}
//
if(p_uart != NULL)
{
// HAL_UART_DeInit(huart);
// HAL_UART_Init(huart);
// HAL_UART_DMAStop(p_Uart->Uart);
HAL_UARTEx_ReceiveToIdle_DMA(p_uart->uart, p_uart->rx_addr, p_uart->rx_dma_len);
}
}
// 实现空闲中断回调
void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
{
if (huart->Instance == USART1)
{
bsp_uart_rx_idle_int(&com_uart1);
}
else if (huart->Instance == USART2)
{
bsp_uart_rx_idle_int(&com_uart2);
}
else if (huart->Instance == USART3)
{
bsp_uart_rx_idle_int(&com_uart3);
}
else if (huart->Instance == UART4)
{
bsp_uart_rx_idle_int(&com_uart4);
}
else if (huart->Instance == USART6)
{
bsp_uart_rx_idle_int(&com_uart6);
}
}
/* 串口接收完成回调函数 - 处理空闲中断 */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
// if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE))
// {
// __HAL_UART_CLEAR_IDLEFLAG(huart);
// if (huart->Instance == USART1)
// {
// bsp_Uart_Rx_IdleInt(&COM_Uart1);
// }
// else if (huart->Instance == USART2)
// {
// bsp_Uart_Rx_IdleInt(&COM_Uart2);
// }
// else if (huart->Instance == UART4)
// {
// bsp_Uart_Rx_IdleInt(&COM_Uart4);
// }
// }
}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
bsp_uart_tx_dma_tc_int(&com_uart1);
}
else if (huart->Instance == USART2)
{
bsp_uart_tx_dma_tc_int(&com_uart2);
}
else if (huart->Instance == USART3)
{
bsp_uart_tx_dma_tc_int(&com_uart3);
}
else if (huart->Instance == UART4)
{
bsp_uart_tx_dma_tc_int(&com_uart4);
}
else if (huart->Instance == USART6)
{
bsp_uart_tx_dma_tc_int(&com_uart6);
}
}