shuichan_old/V1.2/STM32F103_App1/HardWare/UART/uart.c

302 lines
10 KiB
C
Raw Normal View History

#include "uart.h"
#include "network.h"
#include <string.h>
#include <ctype.h>
UART_HandleTypeDef huart1;
UART_HandleTypeDef huart2;
UART_HandleTypeDef huart3;
UART_HandleTypeDef huart4;
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();
}
/* UART4: WiFi ESP-01S 模块 (PC10=TX -> ESP_RXD, PC11=RX <- ESP_TXD)
* 115200ESP-01S AT
* esp_reset AT+UART_DEF WIFI_BAUD_TARGET */
void MX_UART4_UART_Init(void)
{
huart4.Instance = UART4;
huart4.Init.BaudRate = 115200;
huart4.Init.WordLength = UART_WORDLENGTH_8B;
huart4.Init.StopBits = UART_STOPBITS_1;
huart4.Init.Parity = UART_PARITY_NONE;
huart4.Init.Mode = UART_MODE_TX_RX;
huart4.Init.HwFlowCtl = UART_HWCONTROL_NONE;
huart4.Init.OverSampling = UART_OVERSAMPLING_16;
if (HAL_UART_Init(&huart4) != 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 DMA 接收WiFi/4G 互斥复用 Rx_Buf切 WiFi 通道时必须先停 4G 接收 */
void USART3_StopRx(void)
{
__HAL_UART_DISABLE_IT(&huart3, UART_IT_IDLE);
HAL_UART_DMAStop(&huart3);
}
/* 启动 UART4 DMA+IDLE 接收:与 USART3 复用同一块 Rx_Buf两通道互斥靠 StartRx/StopRx 保证) */
void UART4_StartRx(void)
{
if (huart4.RxState != HAL_UART_STATE_READY) {
HAL_UART_DMAStop(&huart4);
}
HAL_UART_Receive_DMA(&huart4, Rx_Buf, Rx_Max);
__HAL_UART_ENABLE_IT(&huart4, UART_IT_IDLE);
}
void UART4_StopRx(void)
{
__HAL_UART_DISABLE_IT(&huart4, UART_IT_IDLE);
HAL_UART_DMAStop(&huart4);
}
/* 运行中切换 UART4 波特率:只重写 BRR 寄存器,不动 GPIO/NVIC/DMA 配置。
* UART4 APB1(36MHz) */
void UART4_SetBaudRate(uint32_t baud)
{
if (huart4.RxState != HAL_UART_STATE_READY) {
HAL_UART_DMAStop(&huart4);
}
huart4.Init.BaudRate = baud;
UART4->BRR = UART_BRR_SAMPLING16(36000000u, baud);
__HAL_UART_CLEAR_PEFLAG(&huart4);
__HAL_UART_CLEAR_FEFLAG(&huart4);
__HAL_UART_CLEAR_NEFLAG(&huart4);
__HAL_UART_CLEAR_OREFLAG(&huart4);
__HAL_UART_CLEAR_IDLEFLAG(&huart4);
HAL_UART_Receive_DMA(&huart4, Rx_Buf, Rx_Max);
__HAL_UART_ENABLE_IT(&huart4, UART_IT_IDLE);
}
/* UART 错误回调ORE(溢出) 等错误会让 HAL 中止整个 DMA 接收
* (stm32f1xx_hal_uart.c: UART_EndRxTransfer + HAL_DMA_Abort_IT)
*
* 921600 IDLE DMA
* ORE */
void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == UART4) {
__HAL_UART_CLEAR_OREFLAG(huart);
__HAL_UART_CLEAR_PEFLAG(huart);
__HAL_UART_CLEAR_FEFLAG(huart);
__HAL_UART_CLEAR_NEFLAG(huart);
__HAL_UART_CLEAR_IDLEFLAG(huart);
huart->ErrorCode = HAL_UART_ERROR_NONE;
if (NET_GetActiveBackend() == NET_BACKEND_WIFI) {
HAL_UART_Receive_DMA(&huart4, Rx_Buf, Rx_Max);
__HAL_UART_ENABLE_IT(&huart4, UART_IT_IDLE);
}
}
else if (huart->Instance == USART3) {
__HAL_UART_CLEAR_OREFLAG(huart);
__HAL_UART_CLEAR_PEFLAG(huart);
__HAL_UART_CLEAR_FEFLAG(huart);
__HAL_UART_CLEAR_NEFLAG(huart);
__HAL_UART_CLEAR_IDLEFLAG(huart);
huart->ErrorCode = HAL_UART_ERROR_NONE;
if (NET_GetActiveBackend() == NET_BACKEND_4G) {
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;
}