Files
2026-09-09 14:54:40 +08:00

339 lines
8.2 KiB
C

#include "bsp_Uart.h"
#include "string.h"
#define RS485_RX //HAL_GPIO_WritePin(RS485_EN_GPIO_Port, RS485_EN_Pin, GPIO_PIN_RESET)
#define RS485_TX //HAL_GPIO_WritePin(RS485_EN_GPIO_Port, RS485_EN_Pin, GPIO_PIN_SET)
/*缓冲收发区*/
#define RX_TEMP_BUFF_NUM (512U)
u8 Rx_Temp_Buff[RX_TEMP_BUFF_NUM];
#define UART1_TX_LEN (256U)
#define UART1_RX_LEN (256U)
#define UART2_TX_LEN (256U)
#define UART2_RX_LEN (256U)
#define UART3_TX_LEN (512U)
#define UART3_RX_LEN (512U)
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];
static void bsp_Uart_Init(bsp_Uart_t *p_Uart);
static void bsp_Uart_Send(bsp_Uart_t *p_Uart,u8 *pData, u16 Len);
static void bsp_Uart_Rx_IdleInt(bsp_Uart_t *p_Uart);
static void bsp_Uart_Rx_TimeIncrement(bsp_Uart_t *p_Uart,u16 Time);
static void bsp_Uart_Rx_Task(bsp_Uart_t *p_Uart);
static void bsp_Uart_Rx_TimeStart(bsp_Uart_t *p_Uart);
static void bsp_Uart_Tx_DMA_TCInt(bsp_Uart_t *p_Uart);
extern UART_HandleTypeDef huart1;
extern UART_HandleTypeDef huart2;
extern UART_HandleTypeDef huart3;
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;
bsp_Uart_t COM_Uart1 =
{
.RxQueue = 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_CompleteFlag = 1,
.Rx_TimeOver = 10,
.Init = bsp_Uart_Init,
.Send = bsp_Uart_Send,
.Tx_DMA_TCInt = bsp_Uart_Tx_DMA_TCInt,
.Rx_IdleInt = bsp_Uart_Rx_IdleInt,
.Rx_TimeIncrementInt = bsp_Uart_Rx_TimeIncrement,
.Rx_DataAnalysis = NULL,
.Rx_Task = bsp_Uart_Rx_Task,
};
bsp_Uart_t COM_Uart2 =
{
.RxQueue = 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_CompleteFlag = 1,
.Rx_TimeOver = 10,
.Init = bsp_Uart_Init,
.Send = bsp_Uart_Send,
.Tx_DMA_TCInt = bsp_Uart_Tx_DMA_TCInt,
.Rx_IdleInt = bsp_Uart_Rx_IdleInt,
.Rx_TimeIncrementInt = bsp_Uart_Rx_TimeIncrement,
.Rx_DataAnalysis = NULL,
.Rx_Task = bsp_Uart_Rx_Task,
};
bsp_Uart_t COM_Uart3 =
{
.RxQueue = 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_CompleteFlag = 1,
.Rx_TimeOver = 10,
.Init = bsp_Uart_Init,
.Send = bsp_Uart_Send,
.Tx_DMA_TCInt = bsp_Uart_Tx_DMA_TCInt,
.Rx_IdleInt = bsp_Uart_Rx_IdleInt,
.Rx_TimeIncrementInt = bsp_Uart_Rx_TimeIncrement,
.Rx_DataAnalysis = NULL,
.Rx_Task = bsp_Uart_Rx_Task,
};
/* 初始化函数 */
static void bsp_Uart_Init(bsp_Uart_t *p_Uart)
{
/*配置数据解析函数*/
//p_Uart->Rx_DataAnalysis = NULL;
/* 启用空闲中断 */
__HAL_UART_ENABLE_IT(p_Uart->Uart, UART_IT_IDLE);
/* 启动DMA接收 */
HAL_UART_Receive_DMA(p_Uart->Uart, p_Uart->Rx_Addr, p_Uart->Rx_DMA_Len);
}
/* 判断DMA发送是否完成 */
static uint8_t bsp_Uart_IsDMATxComplete(bsp_Uart_t *p_Uart)
{
// 方法1.1: 检查DMA状态
if (HAL_DMA_GetState(p_Uart->Tx_DMA) == HAL_DMA_STATE_READY) {
return 1;
}
// // 方法1.2: 检查UART状态
// if (HAL_UART_GetState(p_Uart->Uart) == HAL_UART_STATE_READY) {
// return 1;
// }
//
// 方法1.3: 检查DMA传输计数器
if (__HAL_DMA_GET_COUNTER(p_Uart->Tx_DMA) == 0) {
return 1;
}
return 0;
}
static void bsp_Uart_DMASend(bsp_Uart_t *p_Uart,u8 *pData, u16 Len)
{
while( !p_Uart->Tx_DMA_CompleteFlag)
{
}
p_Uart->Tx_DMA_CompleteFlag = 0;
if(p_Uart->Tx_DMA_Len < Len)
Len = p_Uart->Tx_DMA_Len;
memcpy(p_Uart->Tx_Addr, pData, Len); /*拷贝数据到发送缓冲*/
HAL_UART_Transmit_DMA(p_Uart->Uart,p_Uart->Tx_Addr,Len);
// while (!bsp_Uart_IsDMATxComplete(p_Uart)); /*等待传输完成标志*/
// //传输是否完成
//
// while (HAL_UART_GetState(&huart1) == HAL_UART_STATE_BUSY_TX) {
// // 短暂延时,避免忙等
// }
}
/*大数据量发送*/
static void bsp_Uart_Send(bsp_Uart_t *p_Uart,u8 *pData, u16 Len)
{
u16 i,SendNum;
if(p_Uart->Uart == &huart1)
RS485_TX;
SendNum = Len / p_Uart->Tx_DMA_Len;
for(i=0;i<SendNum;i++)
{
bsp_Uart_DMASend(p_Uart,&pData[p_Uart->Tx_DMA_Len * i], p_Uart->Tx_DMA_Len);
}
/*发送剩余数据*/
Len -= p_Uart->Tx_DMA_Len * i;
if(0 == Len)
{
return ;
}
else
{
bsp_Uart_DMASend(p_Uart,&pData[p_Uart->Tx_DMA_Len * i],Len);
}
}
static void bsp_Uart_Tx_DMA_TCInt(bsp_Uart_t *p_Uart)
{
p_Uart->Tx_DMA_CompleteFlag = 1;
}
/*空闲接收中断*/
static void bsp_Uart_Rx_IdleInt(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->RxQueue, (void *)&p_Uart->Rx_Addr[i]);
}
/* 开始计数 */
bsp_Uart_Rx_TimeStart(p_Uart);
/* 重新启动DMA接收 */
HAL_UART_Receive_DMA(p_Uart->Uart, p_Uart->Rx_Addr, p_Uart->Rx_DMA_Len);
}
/*中断计数*/
static void bsp_Uart_Rx_TimeIncrement(bsp_Uart_t *p_Uart,u16 Time)
{
/*开始计数*/
if(1 == p_Uart->Rx_StartFlag)
{
p_Uart->Rx_TimeCount += Time;
}
}
/*开始计数*/
static void bsp_Uart_Rx_TimeStart(bsp_Uart_t *p_Uart)
{
p_Uart->Rx_StartFlag = 1;
p_Uart->Rx_TimeCount = 0;
}
/*停止计数*/
static void bsp_Uart_Rx_TimeStop(bsp_Uart_t *p_Uart)
{
p_Uart->Rx_StartFlag = 0;
p_Uart->Rx_TimeCount = 0;
}
static void bsp_Uart_Rx_Task(bsp_Uart_t *p_Uart)
{
/*超时计数完成,接收到一帧数据*/
if(p_Uart->Rx_TimeOver < p_Uart->Rx_TimeCount)
{
p_Uart->Rx_Len = queue_size(p_Uart->RxQueue);
/*停止计数*/
bsp_Uart_Rx_TimeStop(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->RxQueue);
}
else
{
for(u16 i = 0;i < p_Uart->Rx_Len;i++)
{
queue_pop(p_Uart->RxQueue,&Rx_Temp_Buff[i]);
}
if(NULL != p_Uart->Rx_DataAnalysis)
{
p_Uart->Rx_DataAnalysis(Rx_Temp_Buff,p_Uart->Rx_Len,p_Uart); /*解析数据*/
}
//p_Uart->Send(p_Uart,Rx_Temp_Buff,p_Uart->Rx_Len);
}
}
}
}
///* 串口接收完成回调函数 - 处理空闲中断 */
//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 == USART3)
// {
// bsp_Uart_Rx_IdleInt(&COM_Uart3);
// }
// else if (huart->Instance == UART4)
// {
// bsp_Uart_Rx_IdleInt(&COM_Uart4);
// }
// }
//}
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
RS485_RX;
COM_Uart1.Tx_DMA_TCInt(&COM_Uart1);
}
else if (huart->Instance == USART2)
{
COM_Uart2.Tx_DMA_TCInt(&COM_Uart2);
}
else if (huart->Instance == USART3)
{
COM_Uart3.Tx_DMA_TCInt(&COM_Uart3);
}
}