#include "uart.h" #include #include UART_HandleTypeDef huart1; UART_HandleTypeDef huart2; UART_HandleTypeDef huart3; uint16_t Rx_Len = 0; uint8_t Rx_Buf[Rx_Max] = {0}; volatile uint8_t uart1_rx_ready = 0; uint8_t uart1_rx_buf[UART1_RX_BUF_SIZE] = {0}; volatile uint8_t uart2_rx_ready = 0; uint8_t uart2_rx_buf[UART2_RX_BUF_SIZE] = {0}; static uint8_t uart1_rx_byte = 0; static uint8_t uart1_cmd_buf[UART1_RX_BUF_SIZE] = {0}; static uint8_t uart1_cmd_index = 0; static uint32_t uart1_last_rx_tick = 0; static uint8_t uart2_rx_byte = 0; static uint8_t uart2_cmd_buf[UART2_RX_BUF_SIZE] = {0}; static uint8_t uart2_cmd_index = 0; static uint32_t uart2_last_rx_tick = 0; #define UART1_CMD_TIMEOUT_MS 100u /* 无换行时,字符间隔超过该时间视为命令结束 */ #define UART2_CMD_TIMEOUT_MS 20u /* 485 返回帧较短,20ms 视为帧结束 */ void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) Error_Handler(); } void MX_USART2_UART_Init(void) { huart2.Instance = USART2; huart2.Init.BaudRate = 9600; huart2.Init.WordLength = UART_WORDLENGTH_8B; huart2.Init.StopBits = UART_STOPBITS_1; huart2.Init.Parity = UART_PARITY_NONE; huart2.Init.Mode = UART_MODE_TX_RX; huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart2.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart2) != HAL_OK) Error_Handler(); } void MX_USART3_UART_Init(void) { huart3.Instance = USART3; huart3.Init.BaudRate = 115200; /* 上电默认 115200(安全档),cat_connect_network 里再自适应切 921600 */ huart3.Init.WordLength = UART_WORDLENGTH_8B; huart3.Init.StopBits = UART_STOPBITS_1; huart3.Init.Parity = UART_PARITY_NONE; huart3.Init.Mode = UART_MODE_TX_RX; huart3.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart3.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart3) != HAL_OK) Error_Handler(); } void USART3_StartRx(void) { /* 避免重复启动 DMA: 若已在接收则先停止再启动 */ if (huart3.RxState != HAL_UART_STATE_READY) { HAL_UART_DMAStop(&huart3); } HAL_UART_Receive_DMA(&huart3, Rx_Buf, Rx_Max); __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE); } /* 运行中切换 USART3 波特率:只重写 BRR 寄存器,不动 GPIO/NVIC/DMA 配置。 * USART3 挂在 APB1(36MHz) 上 */ void USART3_SetBaudRate(uint32_t baud) { if (huart3.RxState != HAL_UART_STATE_READY) { HAL_UART_DMAStop(&huart3); } huart3.Init.BaudRate = baud; USART3->BRR = UART_BRR_SAMPLING16(36000000u, baud); __HAL_UART_CLEAR_PEFLAG(&huart3); __HAL_UART_CLEAR_FEFLAG(&huart3); __HAL_UART_CLEAR_NEFLAG(&huart3); __HAL_UART_CLEAR_OREFLAG(&huart3); __HAL_UART_CLEAR_IDLEFLAG(&huart3); HAL_UART_Receive_DMA(&huart3, Rx_Buf, Rx_Max); __HAL_UART_ENABLE_IT(&huart3, UART_IT_IDLE); } void USART1_StartRx(void) { uart1_rx_ready = 0; uart1_cmd_index = 0; uart1_last_rx_tick = 0; memset(uart1_cmd_buf, 0, sizeof(uart1_cmd_buf)); memset(uart1_rx_buf, 0, sizeof(uart1_rx_buf)); HAL_UART_Receive_IT(&huart1, &uart1_rx_byte, 1); } void USART2_StartRx(void) { uart2_rx_ready = 0; uart2_cmd_index = 0; uart2_last_rx_tick = 0; memset(uart2_cmd_buf, 0, sizeof(uart2_cmd_buf)); memset(uart2_rx_buf, 0, sizeof(uart2_rx_buf)); HAL_UART_Receive_IT(&huart2, &uart2_rx_byte, 1); } /* 从 USART2 接收缓冲区取出一帧(20ms 无新字节结束),返回帧长度,0 表示暂无完整帧 */ uint16_t USART2_GetFrame(uint8_t *out, uint16_t out_size) { if (uart2_rx_ready) { uart2_rx_ready = 0; uint16_t len = uart2_cmd_index < out_size ? uart2_cmd_index : out_size - 1; memcpy(out, uart2_cmd_buf, len); out[len] = '\0'; uart2_cmd_index = 0; return len; } return 0; } /* 中断接收回调:把单个字符追加到命令缓冲区,回车换行结束; * 无换行时,字符间隔超过 UART1_CMD_TIMEOUT_MS 自动提交 */ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if (huart->Instance == USART1) { uint8_t ch = uart1_rx_byte; if (ch == '\r' || ch == '\n') { if (uart1_cmd_index > 0) { uart1_cmd_buf[uart1_cmd_index] = '\0'; memcpy(uart1_rx_buf, uart1_cmd_buf, uart1_cmd_index + 1); uart1_rx_ready = 1; uart1_cmd_index = 0; } } else if (uart1_cmd_index < UART1_RX_BUF_SIZE - 1) { uart1_cmd_buf[uart1_cmd_index++] = ch; uart1_last_rx_tick = HAL_GetTick(); } HAL_UART_Receive_IT(&huart1, &uart1_rx_byte, 1); } else if (huart->Instance == USART2) { uint8_t ch = uart2_rx_byte; if (uart2_cmd_index < UART2_RX_BUF_SIZE - 1) { uart2_cmd_buf[uart2_cmd_index++] = ch; uart2_last_rx_tick = HAL_GetTick(); } HAL_UART_Receive_IT(&huart2, &uart2_rx_byte, 1); } } /* 在 USART2_GetFrame 被轮询前,20ms 无新字节自动提交帧 */ void USART2_Tick(void) { if (uart2_cmd_index > 0 && (HAL_GetTick() - uart2_last_rx_tick) > UART2_CMD_TIMEOUT_MS) { uart2_rx_ready = 1; } } /* 不区分大小写的字符串比较 */ static int uart_strcasecmp(const char *a, const char *b) { while (*a && *b) { char ca = (char)toupper((unsigned char)*a); char cb = (char)toupper((unsigned char)*b); if (ca != cb) return ca - cb; a++; b++; } return (char)toupper((unsigned char)*a) - (char)toupper((unsigned char)*b); } /* 检查 USART1 是否收到指定命令(不区分大小写),检查后清除 ready */ int USART1_CheckCommand(const char *cmd) { const char *got = USART1_GetCommand(); if (!got) return 0; return (uart_strcasecmp(got, cmd) == 0); } /* 获取当前接收到的命令字符串(用于自定义解析)。 * 支持两种结束方式:收到 \r/\n 立即结束;无换行时字符间隔超过 100ms 自动结束。 */ const char *USART1_GetCommand(void) { if (uart1_rx_ready) { uart1_rx_ready = 0; return (const char *)uart1_rx_buf; } if (uart1_cmd_index > 0 && (HAL_GetTick() - uart1_last_rx_tick) > UART1_CMD_TIMEOUT_MS) { uart1_cmd_buf[uart1_cmd_index] = '\0'; memcpy(uart1_rx_buf, uart1_cmd_buf, uart1_cmd_index + 1); uart1_cmd_index = 0; return (const char *)uart1_rx_buf; } return NULL; }