#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;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); /* 重新启动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); } }