#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_RX HAL_GPIO_WritePin(RS485_EN_GPIO_Port, RS485_EN_Pin, GPIO_PIN_SET) #define RS485_TX HAL_GPIO_WritePin(RS485_EN_GPIO_Port, RS485_EN_Pin, GPIO_PIN_SET) /*缓冲收发区*/ #define RX_TEMP_BUFF_NUM (3000U) u8 Rx_Temp_Buff[RX_TEMP_BUFF_NUM]; #define UART1_TX_LEN (3000U) #define UART1_RX_LEN (3000U) #define UART2_TX_LEN (3000U) #define UART2_RX_LEN (3000U) #define UART4_TX_LEN (3000U) #define UART4_RX_LEN (3000U) 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 Uart4_TX_Buff[UART4_TX_LEN]; u8 Uart4_Rx_Buff[UART4_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 huart4; 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_uart4_rx; extern DMA_HandleTypeDef hdma_uart4_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 = 0, .relay.uart = NULL, .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 = 0, .relay.uart = &COM_Uart4, .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_Uart4 = { .RxQueue = 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_CompleteFlag = 1, .Rx_TimeOver = 0, .relay.uart = NULL, .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); /* 重新启动接收 */ HAL_UARTEx_ReceiveToIdle_DMA(p_Uart->Uart, p_Uart->Rx_Addr, p_Uart->Rx_DMA_Len); } static void bsp_Uart_DMASend(bsp_Uart_t *p_Uart,u8 *pData, u16 Len) { u32 tickstart,tick; 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(p_Uart->Uart,p_Uart->Tx_Addr,Len,500); HAL_UART_Transmit_DMA(p_Uart->Uart,p_Uart->Tx_Addr,Len); tickstart = HAL_GetTick(); while( !p_Uart->Tx_DMA_CompleteFlag) { tick = HAL_GetTick(); if((tick - tickstart) > 200) // 1000ms 超时 { p_Uart->Tx_DMA_CompleteFlag = 1; break; } } } /*大数据量发送*/ static void bsp_Uart_Send(bsp_Uart_t *p_Uart,u8 *pData, u16 Len) { u16 i,SendNum; if(p_Uart == &COM_Uart4) RS485_TX; SendNum = Len / p_Uart->Tx_DMA_Len; for(i=0;iTx_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); // HAL_UART_Receive_DMA(p_Uart->Uart, p_Uart->Rx_Addr, p_Uart->Rx_DMA_Len); HAL_UARTEx_ReceiveToIdle_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); } } } } // 错误回调函数中处理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 == UART4) { p_Uart = &COM_Uart4; } // 检查具体错误类型 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_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_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) { COM_Uart1.Tx_DMA_TCInt(&COM_Uart1); } else if (huart->Instance == USART2) { COM_Uart2.Tx_DMA_TCInt(&COM_Uart2); } else if (huart->Instance == UART4) { RS485_RX; COM_Uart4.Tx_DMA_TCInt(&COM_Uart4); } }