339 lines
8.2 KiB
C
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);
|
|
}
|
|
}
|