基本完成的所有收发功能
This commit is contained in:
105
Core/Src/main.c
105
Core/Src/main.c
@ -89,7 +89,7 @@ static volatile uint32_t u1_last_rx_time = 0;
|
||||
static uint8_t u3_rx_buffer[512];
|
||||
static volatile uint16_t u3_rx_len = 0;
|
||||
static volatile uint32_t u3_last_rx_time = 0;
|
||||
|
||||
static volatile uint32_t u3_ignore_until = 0;
|
||||
/* W5500 variables */
|
||||
#if USE_W5500
|
||||
#define SOCKET_ID 0
|
||||
@ -233,62 +233,77 @@ int main(void)
|
||||
#if USE_W5500
|
||||
loopback_udps(SOCKET_ID, ethernet_buf, local_port);
|
||||
#endif
|
||||
|
||||
// /* 强行拉低 M0 和 M1,叫醒 433 模块处于透传模式! */
|
||||
// HAL_GPIO_WritePin(M0_GPIO_Port, M0_Pin, GPIO_PIN_RESET);
|
||||
// HAL_GPIO_WritePin(GPIOB, M1_Pin, GPIO_PIN_RESET);
|
||||
|
||||
// /* ⚠️ 致命修复:网络被注释后,单片机启动太快。
|
||||
// 433模块从休眠到唤醒至少需要几百毫秒。
|
||||
// 必须改成 1000 毫秒,给硬件足够的缓冲时间! */
|
||||
// HAL_Delay(1000);
|
||||
|
||||
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1)
|
||||
/* Infinite loop */
|
||||
/* USER CODE BEGIN WHILE */
|
||||
while (1)
|
||||
{
|
||||
/* ==========================================================
|
||||
第一部分:恢复系统的核心驱动引擎 (解决网络和端口不传数据的问题)
|
||||
========================================================== */
|
||||
UART2_Print_Task(); // 引擎:负责把串口2的缓存发出去
|
||||
MultiUART_Task(); // 引擎:负责网络分发、多串口异步发送 (极其重要!)
|
||||
IO_Monitor_Task();
|
||||
/* 如果你的网络指令需要解析,取消下面两行的注释 */
|
||||
// CmdRouter_Task();
|
||||
// CmdParser_Task();
|
||||
/* === 1. 恢复系统的核心驱动引擎 === */
|
||||
UART2_Print_Task();
|
||||
MultiUART_Task();
|
||||
IO_Monitor_Task();
|
||||
|
||||
/* ==========================================================
|
||||
第二部分:网络轮询任务
|
||||
========================================================== */
|
||||
/* === 2. 网络轮询任务 === */
|
||||
#if USE_W5500
|
||||
loopback_udps(SOCKET_ID, ethernet_buf, local_port);
|
||||
#endif
|
||||
|
||||
/* ==========================================================
|
||||
第三部分:非阻塞无乱码透传 (解决485卡顿漏数据的问题)
|
||||
========================================================== */
|
||||
/* === 3. 极速无乱码透传 === */
|
||||
|
||||
/* 1. 从 433 收到无线数据 -> 发给 485 */
|
||||
/* === 方案 A:从 433 收到无线数据 -> 拆包提取ID -> 纯净透传给 485 === */
|
||||
if (u1_rx_len > 0 && (HAL_GetTick() - u1_last_rx_time > 20))
|
||||
{
|
||||
/* 改用 MultiUART_Send!它会把数据瞬间丢进发送队列,耗时0毫秒,绝不卡顿单片机! */
|
||||
MultiUART_Send(PORT_UART3, (uint8_t*)u1_rx_buffer, u1_rx_len);
|
||||
|
||||
/* 顺便发给串口2监控 */
|
||||
MultiUART_Send(PORT_UART2, (uint8_t*)u1_rx_buffer, u1_rx_len);
|
||||
|
||||
u1_rx_len = 0; /* 清空缓存 */
|
||||
static uint8_t temp_buf1[256];
|
||||
__disable_irq();
|
||||
uint16_t len = u1_rx_len;
|
||||
memcpy(temp_buf1, (uint8_t*)u1_rx_buffer, len);
|
||||
u1_rx_len = 0;
|
||||
__enable_irq();
|
||||
|
||||
/* 🚀 解析“快递单”:检查数据长度,并且第0个字节必须是我们定义的魔法帧头 0xAA */
|
||||
if (len >= 2 && temp_buf1[0] == 0xAA)
|
||||
{
|
||||
uint8_t sender_id = temp_buf1[1]; // 提取发件人的身份证
|
||||
uint16_t real_len = len - 2; // 扒掉2个字节的衣服后,真实数据的长度
|
||||
uint8_t* real_data = &temp_buf1[2]; // 真实数据的起始指针
|
||||
|
||||
/* 【追踪器】打印出来:知道是哪个设备发来的! */
|
||||
printf("\r\n[DEBUG] 收到来自 设备[%d] 的消息, 有效数据长度: %d 字节!\r\n", sender_id, real_len);
|
||||
/* 只把干净的真实数据发给 485 设备,绝不能把 0xAA 和 ID 发给 485,否则外部设备会乱码 */
|
||||
if (real_len > 0) {
|
||||
MultiUART_Send(PORT_UART3, real_data, real_len);
|
||||
MultiUART_Send(PORT_UART2, real_data, real_len); // 电脑监控原始数据
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 如果没有匹配上帧头(比如收到了环境干扰乱码),直接按原样丢弃或透传 */
|
||||
MultiUART_Send(PORT_UART3, temp_buf1, len);
|
||||
MultiUART_Send(PORT_UART2, temp_buf1, len);
|
||||
}
|
||||
}
|
||||
|
||||
/* 2. 从 485 收到设备数据 -> 通过 433 无线发射 */
|
||||
/* === 方案 B:从 485 收到设备数据 -> 穿上包装(附加ID) -> 通过 433 无线发射 === */
|
||||
if (u3_rx_len > 0 && (HAL_GetTick() - u3_last_rx_time > 20))
|
||||
{
|
||||
MultiUART_Send(PORT_UART1, (uint8_t*)u3_rx_buffer, u3_rx_len);
|
||||
|
||||
/* 【可选进阶】:如果你希望网络端(比如电脑上的UDP助手)也能收到485传来的数据,
|
||||
你可以在这里调用你的网络发送函数,把 u3_rx_buffer 发给网口 */
|
||||
|
||||
u3_rx_len = 0; /* 清空缓存 */
|
||||
static uint8_t temp_buf3[512];
|
||||
__disable_irq();
|
||||
uint16_t len = u3_rx_len;
|
||||
memcpy(temp_buf3, (uint8_t*)u3_rx_buffer, len);
|
||||
u3_rx_len = 0;
|
||||
__enable_irq();
|
||||
|
||||
/* 🚀 制作“快递包”:在最前面加上 [0xAA] 和 [本机ID] */
|
||||
static uint8_t rf_tx_buf[515];
|
||||
rf_tx_buf[0] = 0xAA; // 贴上魔法帧头
|
||||
rf_tx_buf[1] = MY_DEVICE_ID; // 贴上本机的身份证号
|
||||
memcpy(&rf_tx_buf[2], temp_buf3, len); // 把 485 收到的真实数据塞进后面
|
||||
|
||||
/* 把带有身份证的完整包裹,通过 433 发射到空气中 (长度要 +2) */
|
||||
MultiUART_Send(PORT_UART1, rf_tx_buf, len + 2);
|
||||
}
|
||||
|
||||
/* USER CODE END WHILE */
|
||||
@ -349,6 +364,7 @@ void SystemClock_Config(void)
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
|
||||
/* USER CODE BEGIN 4 */
|
||||
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
||||
{
|
||||
if (huart->Instance == USART1) {
|
||||
@ -357,8 +373,11 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
||||
HAL_UART_Receive_IT(&huart1, &rf433_uart_rx_tmp, 1);
|
||||
}
|
||||
else if (huart->Instance == USART3) {
|
||||
if (u3_rx_len < sizeof(u3_rx_buffer)) u3_rx_buffer[u3_rx_len++] = uart3_rx_byte;
|
||||
u3_last_rx_time = HAL_GetTick();
|
||||
/* 🚀 核心生效区:只有当单片机没有在发送数据时(度过屏蔽期),才允许接收 */
|
||||
if (HAL_GetTick() >= u3_ignore_until) {
|
||||
if (u3_rx_len < sizeof(u3_rx_buffer)) u3_rx_buffer[u3_rx_len++] = uart3_rx_byte;
|
||||
u3_last_rx_time = HAL_GetTick();
|
||||
}
|
||||
HAL_UART_Receive_IT(&huart3, &uart3_rx_byte, 1);
|
||||
}
|
||||
else if (huart->Instance == USART2) {
|
||||
|
||||
Reference in New Issue
Block a user