STM_ATEM/User/rs485_driver.c
zhoujie 29cc814384 feat(scripts): 新增光泵磁力仪数据支持与混流解析
- 新增混流解析函数 `parse_mixed_stream()`,支持标准包与光泵包交替出现的二进制文件
- 新增光泵磁力仪模拟器 `OpticMagSimulatorThread`,以可配置频率发送BCD帧
- 新增光泵磁场显示标签页,支持文件模式与实时模式下的磁场曲线绘制
- 新增 `flash_counter` 模块,用于NOFX模式下文件序号持久化

♻️ refactor(data_storage): 重构数据存储目录与文件命名策略

- 会话目录改为按GPS日期命名(YYYYMMDD),无GPS时使用NOFX目录
- 文件命名改为基于GPS时间(HHMMSS)或Flash计数器(C开头),消除序号文件依赖
- 移除 `config_manager` 依赖和 `PARAM.TXT` 序号文件读写逻辑
- 新增 `GPS_ParseGPRMC()` 解析函数,提取日期字段用于目录命名

🐛 fix(ltc2508_driver): 修复DMA启动失败时资源泄漏问题

- SPI2/SPI3 DMA启动失败时主动停止已启动的DMA,防止资源泄漏
- 将SPI1的dummy发送缓冲区改为static,确保DMA传输期间数据有效

🐛 fix(rs485_driver): 修复DMA发送缓冲区可能被覆盖的问题

- 引入静态发送缓冲区 `s_tx_buf`,隔离调用方数据与DMA传输,防止TIM2 ISR覆盖

♻️ refactor(ATEMParse): 重构数据结构定义与解析逻辑

- 移除硬编码的V1/V2 dtype,改为动态构建 `make_dtype()` 函数
- 新增数据格式选项(GPS经纬度/光泵),支持灵活配置
- 新增文件模式下的分页浏览功能(滑块/上一页/下一页)
- 优化实时模式下的光泵数据显示与表格列过滤
2026-06-14 23:06:25 +08:00

71 lines
2.0 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "rs485_driver.h"
#include "system_monitor.h"
#include <string.h>
static UART_HandleTypeDef *g_huart_485 = NULL;
static GPIO_TypeDef* g_de_re_port = NULL;
static uint16_t g_de_re_pin = 0;
volatile uint8_t g_rs485_tx_busy = 0;
/* DMA 异步读取期间此缓冲区必须保持有效;
静态副本隔离调用方的包结构体,防止下一 TIM2 ISR 覆盖源包时 DMA 仍在读取 */
#define RS485_TX_BUF_SIZE 64
static uint8_t s_tx_buf[RS485_TX_BUF_SIZE];
void RS485_Init(UART_HandleTypeDef *huart, GPIO_TypeDef* de_re_port, uint16_t de_re_pin)
{
g_huart_485 = huart;
g_de_re_port = de_re_port;
g_de_re_pin = de_re_pin;
g_rs485_tx_busy = 0;
HAL_GPIO_WritePin(g_de_re_port, g_de_re_pin, GPIO_PIN_RESET); // 初始为接收模式
}
HAL_StatusTypeDef RS485_SendData(uint8_t *pData, uint16_t Size)
{
HAL_StatusTypeDef ret;
// 检查上一次传输是否完成
if (g_rs485_tx_busy)
{
return HAL_BUSY; // 上一次传输未完成,返回忙状态
}
if (Size > RS485_TX_BUF_SIZE) return HAL_ERROR;
memcpy(s_tx_buf, pData, Size);
g_rs485_tx_busy = 1; // 标记为忙状态
HAL_GPIO_WritePin(g_de_re_port, g_de_re_pin, GPIO_PIN_SET); // 设置为发送模式
// 使用DMA非阻塞发送
ret = HAL_UART_Transmit_DMA(g_huart_485, s_tx_buf, Size);
if (ret != HAL_OK)
{
// 如果启动DMA失败需要清除忙标志并切换回接收模式
HAL_GPIO_WritePin(g_de_re_port, g_de_re_pin, GPIO_PIN_RESET);
g_rs485_tx_busy = 0;
// 报告串口发送错误
SystemMonitor_ReportUARTTxError();
}
else
{
// 报告串口发送成功(记录字节数)
SystemMonitor_ReportUARTTx(Size);
}
return ret;
}
// UART DMA传输完成回调函数
void RS485_TxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart == g_huart_485)
{
// DMA传输完成后切换回接收模式
HAL_GPIO_WritePin(g_de_re_port, g_de_re_pin, GPIO_PIN_RESET);
g_rs485_tx_busy = 0; // 清除忙标志
}
}