3.24_433_RX版本:封装RF433模块,完成开机进入TX/RX模式并在开发板验证成功

This commit is contained in:
2026-03-24 16:59:20 +08:00
commit e439dd465e
1311 changed files with 692196 additions and 0 deletions

621
indexed-jingling-puffin.md Normal file
View File

@ -0,0 +1,621 @@
# E32-433TBH-SC 项目去UI化准备计划
## 一、项目背景与目标
### 背景
当前项目使用OLED显示屏和按键系统提供用户界面通过菜单系统配置和测试E32-433无线模块的TX发送和RX接收功能。为了简化硬件、降低成本并专注于核心无线通信功能需要删除所有UI相关代码。
### 目标
1. **删除所有UI相关代码**OLED显示、按键输入、菜单系统
2. **提取核心TX/RX功能**:保留并优化无线通信的核心逻辑
3. **实现配置文件支持**从Flash读取配置参数
4. **保留LED指示**使用LED作为状态反馈
5. **提供手动接口**:保留外部触发发送/接收的API接口
6. **支持编译模式选择**通过编译选项选择TX/RX/双模模式
### 工作模式
- **TX设备**上电后自动循环发送测试数据LED_TX闪烁指示
- **RX设备**上电后自动接收数据LED_RX闪烁指示维护丢包统计
- **手动接口**提供API供外部代码触发单次发送/接收
---
## 二、当前代码分析
### 2.1 TX模式实现application.c: 442-499
**状态机流程**
```
TX_MODE_INIT → TX_MODE_SEND → TX_MODE_WAIT → TX_MODE_END
```
**核心代码路径**
- `tx_mode_callback()` - 主状态机
- `tx_e32_send()` - 发送数据
- `e32_demo_menu_config()` - 配置模块
- `e32_demo_transmit()` - 底层发送
**数据包格式**
```c
"TX.总次数.当前序号." // 例如: "TX.010.001."
```
**配置参数**menu_config_t
```c
typedef struct {
int work_mode; // 工作模式 (0-3)
int rate_mode; // 空速模式 (2-5)
int channel; // 信道 (0-41)
int tx_power; // 发射功率 (21/24/27/30)
int tx_count; // 发送次数 (10-100)
} menu_config_t;
```
### 2.2 RX模式实现application.c: 619-719
**状态机流程**
```
RX_MODE_INIT → RX_MODE_RECV → RX_MODE_WAIT → RX_MODE_END
```
**核心代码路径**
- `rx_mode_callback()` - 主状态机
- `rx_analysis()` - 数据包解析
- `rx_mode_display()` - 丢包统计
- `uart1_check_rx_done()` - 接收检查
**丢包统计算法**
```c
lost_number = tx_number_record - rx_count;
lost_percent = (lost_number * 100) / tx_number_record;
```
### 2.3 RF433驱动层状态
**已完成的重构**
- `Driver_RF433/Inc/rf433_hal.h` - 硬件抽象层接口
- `Driver_RF433/Src/rf433_hal.c` - 硬件抽象层实现
- `Driver_RF433/Inc/rf433.h` - 主驱动接口
- `Driver_RF433/Src/rf433.c` - 主驱动实现
**已实现的API**
```c
// 初始化和配置
rf433_init()
rf433_set_config()
rf433_set_work_mode()
// TX功能
rf433_transmit()
// RX功能
rf433_rx_start()
rf433_rx_stop()
rf433_receive()
```
---
## 三、需要删除的UI相关代码
### 3.1 OLED显示相关需完全删除
**文件列表**
- `Core/Src/u8g2_hal.c` - OLED硬件接口
- `Core/Inc/u8g2_hal.h`
- `Core/Src/i2c.c` - I2C接口仅用于OLED
- `Core/Inc/i2c.h`
- `Middlewares/u8g2Lib/` - 整个U8g2图形库
**删除的函数调用**
```c
// 这些调用需要删除
OLED_ClearBuffer()
OLED_DrawStr()
OLED_DrawLine()
OLED_SendBuffer()
OLED_SetDrawColor()
OLED_DrawBox()
OLED_DrawXBMP()
```
### 3.2 按键输入相关(需完全删除)
**文件列表**
- `Core/Src/key.c` - 按键处理
- `Core/Inc/key.h`
**删除的函数调用**
```c
key_check_press()
key_set_continue()
```
### 3.3 菜单系统相关(需完全删除)
**文件列表**
- `Middlewares/MultMenu/menu/menu.c` - 菜单核心
- `Middlewares/MultMenu/menu/menu.h`
- `Middlewares/MultMenu/menu/menuConfig.h`
- `Middlewares/MultMenu/application/application.c` - 菜单应用
- `Middlewares/MultMenu/application/application.h`
- `Middlewares/MultMenu/disp/dispDirver.c` - 显示驱动
- `Middlewares/MultMenu/disp/dispDirver.h`
**删除的函数调用**
```c
Menu_Init()
Menu_Task()
AddItem()
// 所有 xxx_callback() 函数
```
### 3.4 需要保留的核心文件
**RF433驱动**
- `Driver_RF433/` - 整个目录保留
**底层硬件**
- `Core/Src/usart.c` - UART通信已集成RF433
- `Core/Src/fifo.c` - FIFO缓冲
- `Core/Src/gpio.c` - GPIO控制
- `Core/Src/tim.c` - 定时器(用于超时检测)
**USB CDC**
- `USB_DEVICE/` - 保留用于调试输出(可选)
**系统文件**
- `Core/Src/main.c` - 主程序
- `Core/Src/stm32f1xx_it.c` - 中断处理
- `Core/Src/systick.c` - 系统定时器
---
## 四、核心功能提取方案
### 4.1 TX模式提取
**创建新文件**`Core/Src/rf433_tx_app.c`
**核心功能**
```c
// TX状态机
typedef enum {
TX_STATE_INIT = 0,
TX_STATE_SENDING,
TX_STATE_WAITING,
TX_STATE_IDLE,
} tx_state_t;
// TX应用结构体
typedef struct {
tx_state_t state;
uint32_t send_count;
uint32_t total_count;
uint32_t send_interval_ms;
uint32_t last_send_time;
rf433_register_t config;
} rf433_tx_app_t;
// 核心API
rf433_error_t rf433_tx_app_init(const rf433_register_t *config);
rf433_error_t rf433_tx_app_start(uint32_t count, uint32_t interval_ms);
rf433_error_t rf433_tx_app_stop(void);
rf433_error_t rf433_tx_app_manual_send(uint8_t *data, uint16_t length);
void rf433_tx_app_task(void); // 主循环调用
```
**实现要点**
1. 去除所有OLED显示调用替换为LED控制
2. 去除按键检测改为自动循环或手动API触发
3. 保留数据包构造逻辑:`sprintf(buffer, "TX.%03d.%03d.", total, current)`
4. 保留配置流程:调用`rf433_set_config()`设置模块参数
5. 保留LED指示发送时LED_TX亮起
### 4.2 RX模式提取
**创建新文件**`Core/Src/rf433_rx_app.c`
**核心功能**
```c
// RX状态机
typedef enum {
RX_STATE_INIT = 0,
RX_STATE_RECEIVING,
RX_STATE_IDLE,
} rx_state_t;
// RX统计结构体
typedef struct {
uint32_t total_received;
uint32_t total_expected;
uint32_t lost_packets;
uint8_t lost_percent;
} rf433_rx_stats_t;
// RX应用结构体
typedef struct {
rx_state_t state;
rf433_rx_stats_t stats;
uint32_t tx_current_number;
uint32_t tx_total_number;
uint32_t tx_number_record;
rf433_register_t config;
} rf433_rx_app_t;
// 核心API
rf433_error_t rf433_rx_app_init(const rf433_register_t *config);
rf433_error_t rf433_rx_app_start(void);
rf433_error_t rf433_rx_app_stop(void);
void rf433_rx_app_task(void); // 主循环调用
rf433_error_t rf433_rx_app_get_stats(rf433_rx_stats_t *stats);
```
**实现要点**
1. 去除所有OLED显示调用替换为LED控制
2. 保留数据包解析:校验"TX"前缀,提取序号
3. 保留丢包统计算法
4. 保留LED指示接收时LED_RX闪烁
5. 提供API获取统计信息供外部查询
### 4.3 配置文件支持
**创建新文件**`Core/Src/rf433_config_file.c`
**功能实现**
```c
// Flash配置结构体对齐Flash扇区
typedef struct {
uint32_t magic; // 魔数标识 0xA5A5A5A5
uint32_t version; // 配置版本
rf433_register_t rf_config; // RF433配置
uint32_t tx_count; // 发送次数
uint32_t tx_interval; // 发送间隔
uint8_t work_mode; // 工作模式
uint8_t reserved[7]; // 对齐到16字节
uint32_t crc; // CRC校验
} rf433_flash_config_t;
// 核心API
rf433_error_t rf433_config_load(rf433_flash_config_t *config);
rf433_error_t rf433_config_save(const rf433_flash_config_t *config);
rf433_error_t rf433_config_reset_to_default(rf433_flash_config_t *config);
```
**Flash地址规划**
- 使用STM32的最后一页Flash如0x0800FC00-0x08010000
- 配置大小64字节单页足够
- 提供默认配置,首次启动时自动写入
### 4.4 手动接口API
**创建新文件**`Core/Inc/rf433_manual.h`
**接口定义**
```c
// 手动发送接口
rf433_error_t rf433_manual_send(uint8_t *data, uint16_t length);
// 手动接收接口(阻塞模式)
rf433_error_t rf433_manual_recv(uint8_t *buffer, uint16_t max_len,
uint16_t *actual_len, uint32_t timeout);
// 获取RX统计信息
rf433_error_t rf433_manual_get_rx_stats(rf433_rx_stats_t *stats);
// 重置统计信息
rf433_error_t rf433_manual_reset_stats(void);
```
---
## 五、编译模式配置
### 5.1 预编译宏定义
`rf433_config.h`中定义:
```c
// 工作模式选择(三选一)
#define RF433_WORK_MODE_TX 1 // 仅TX模式
#define RF433_WORK_MODE_RX 2 // 仅RX模式
#define RF433_WORK_MODE_DUAL 3 // 双模模式同时支持TX和RX
// 当前工作模式(在编译选项中定义)
#ifndef RF433_MODE
#define RF433_MODE RF433_WORK_MODE_TX // 默认TX模式
#endif
// 功能裁剪
#define RF433_ENABLE_CONFIG_FILE 1 // 启用配置文件
#define RF433_ENABLE_LED_INDICATOR 1 // 启用LED指示
#define RF433_ENABLE_USB_DEBUG 0 // 禁用USB调试可选
```
### 5.2 Keil项目配置
**TX设备配置**
- Preprocessor Symbols: `RF433_MODE=1`
- 保留文件:`rf433_tx_app.c`
- 排除文件:`rf433_rx_app.c`(或通过条件编译)
**RX设备配置**
- Preprocessor Symbols: `RF433_MODE=2`
- 保留文件:`rf433_rx_app.c`
- 排除文件:`rf433_tx_app.c`(或通过条件编译)
**双模设备配置**
- Preprocessor Symbols: `RF433_MODE=3`
- 保留文件:`rf433_tx_app.c``rf433_rx_app.c`
### 5.3 条件编译示例
```c
#if (RF433_MODE == RF433_WORK_MODE_TX) || (RF433_MODE == RF433_WORK_MODE_DUAL)
// TX相关代码
#include "rf433_tx_app.h"
#endif
#if (RF433_MODE == RF433_WORK_MODE_RX) || (RF433_MODE == RF433_WORK_MODE_DUAL)
// RX相关代码
#include "rf433_rx_app.h"
#endif
```
---
## 六、main.c重构方案
### 6.1 初始化流程
```c
int main(void) {
HAL_Init();
SystemClock_Config();
// 硬件初始化(保留必要部分)
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_TIM2_Init(); // 用于超时检测
#if RF433_ENABLE_USB_DEBUG
MX_USB_DEVICE_Init();
#endif
// 加载配置文件
rf433_flash_config_t config;
if (rf433_config_load(&config) != RF433_OK) {
// 加载失败,使用默认配置
rf433_config_reset_to_default(&config);
rf433_config_save(&config);
}
// 初始化RF433模块
rf433_init(&config.rf_config);
// 初始化TX/RX应用层
#if (RF433_MODE == RF433_WORK_MODE_TX) || (RF433_MODE == RF433_WORK_MODE_DUAL)
rf433_tx_app_init(&config.rf_config);
rf433_tx_app_start(config.tx_count, config.tx_interval);
#endif
#if (RF433_MODE == RF433_WORK_MODE_RX) || (RF433_MODE == RF433_WORK_MODE_DUAL)
rf433_rx_app_init(&config.rf_config);
rf433_rx_app_start();
#endif
// 启动UART接收
HAL_UART_Receive_IT(&huart1, &usb_rx_data, 1);
// 主循环
while (1) {
#if (RF433_MODE == RF433_WORK_MODE_TX) || (RF433_MODE == RF433_WORK_MODE_DUAL)
rf433_tx_app_task();
#endif
#if (RF433_MODE == RF433_WORK_MODE_RX) || (RF433_MODE == RF433_WORK_MODE_DUAL)
rf433_rx_app_task();
#endif
HAL_Delay(1);
}
}
```
### 6.2 删除的内容
```c
// 删除这些初始化
// MX_I2C2_Init(); // OLED用的I2C
// Menu_Init(); // 菜单初始化
// 删除主循环中的这些调用
// Menu_Task(); // 菜单任务
// usb_receive_to_tx_send(); // USB桥接可选保留
```
---
## 七、实施步骤
### 阶段1准备工作1-2小时
- [ ] 创建新文件模板
- `Core/Src/rf433_tx_app.c`
- `Core/Src/rf433_rx_app.c`
- `Core/Src/rf433_config_file.c`
- `Core/Inc/rf433_manual.h`
- [ ] 备份原项目代码
- [ ] 创建新的Keil项目配置TX/RX版本
### 阶段2TX功能提取2-3小时
- [ ]`application.c`提取`tx_mode_callback`核心逻辑
- [ ] 实现`rf433_tx_app.c`
- 状态机(去除菜单相关)
- 自动发送逻辑
- LED指示
- 手动发送接口
- [ ] 测试TX功能
### 阶段3RX功能提取2-3小时
- [ ]`application.c`提取`rx_mode_callback`核心逻辑
- [ ] 实现`rf433_rx_app.c`
- 状态机(去除菜单相关)
- 数据包解析
- 丢包统计
- LED指示
- 统计查询接口
- [ ] 测试RX功能
### 阶段4配置文件实现2-3小时
- [ ] 实现Flash读写函数
- [ ] 定义默认配置
- [ ] 实现配置加载/保存
- [ ] 测试配置持久化
### 阶段5删除UI代码1-2小时
- [ ] 删除OLED相关文件和调用
- [ ] 删除按键相关文件和调用
- [ ] 删除菜单系统文件和调用
- [ ] 清理main.c初始化代码
- [ ] 编译测试,确保无错误
### 阶段6集成测试2-3小时
- [ ] TX模式测试
- 自动循环发送
- LED指示正常
- 手动发送接口测试
- [ ] RX模式测试
- 自动接收
- 丢包统计准确
- LED指示正常
- [ ] 双模模式测试
- [ ] 配置文件测试
- 默认配置加载
- 配置修改和保存
- 配置恢复默认值
### 阶段7优化和文档1-2小时
- [ ] 代码优化和注释
- [ ] 编写使用说明
- [ ] 更新项目文档
- [ ] 创建编译配置说明
**总计时间11-18小时**
---
## 八、测试验证方案
### 8.1 TX模式测试
**测试项目**
1. 上电自动启动发送
2. 按配置间隔循环发送
3. LED_TX闪烁指示
4. 发送计数正确
5. 数据包格式正确:"TX.010.001."
6. 手动发送接口正常工作
**测试方法**
- 使用逻辑分析仪或示波器观察UART输出
- 使用另一台RX设备接收并验证
- 观察LED指示
### 8.2 RX模式测试
**测试项目**
1. 上电自动启动接收
2. 正确解析数据包
3. 丢包统计准确
4. LED_RX闪烁指示
5. 统计查询接口返回正确数据
**测试方法**
- 使用TX设备发送测试数据
- 通过LED观察接收状态
- 通过手动接口查询统计信息
### 8.3 配置文件测试
**测试项目**
1. 首次启动写入默认配置
2. 修改配置后重启,配置保持
3. 配置损坏时自动恢复默认值
4. 配置CRC校验正确
**测试方法**
- 修改配置参数
- 断电重启
- 读取Flash验证
---
## 九、关键文件清单
### 9.1 需要创建的文件
| 文件路径 | 功能描述 | 代码量估算 |
|---------|---------|-----------|
| `Core/Src/rf433_tx_app.c` | TX应用层实现 | ~300行 |
| `Core/Inc/rf433_tx_app.h` | TX应用层接口 | ~80行 |
| `Core/Src/rf433_rx_app.c` | RX应用层实现 | ~400行 |
| `Core/Inc/rf433_rx_app.h` | RX应用层接口 | ~100行 |
| `Core/Src/rf433_config_file.c` | 配置文件实现 | ~200行 |
| `Core/Inc/rf433_config_file.h` | 配置文件接口 | ~60行 |
| `Core/Inc/rf433_manual.h` | 手动接口定义 | ~50行 |
### 9.2 需要修改的文件
| 文件路径 | 修改内容 | 变更量 |
|---------|---------|--------|
| `Core/Src/main.c` | 重构初始化和主循环 | -50行+100行 |
| `Core/Src/usart.c` | 保留RF433集成删除USB桥接 | -20行 |
| `Core/Inc/main.h` | 删除UI相关定义 | -30行 |
### 9.3 需要删除的文件
**整个目录删除**
- `Middlewares/MultMenu/` (整个菜单系统)
- `Middlewares/u8g2Lib/` OLED图形库
**单个文件删除**
- `Core/Src/u8g2_hal.c`
- `Core/Inc/u8g2_hal.h`
- `Core/Src/i2c.c`
- `Core/Inc/i2c.h`
- `Core/Src/key.c`
- `Core/Inc/key.h`
---
## 十、风险评估与缓解措施
### 10.1 风险识别
| 风险 | 影响 | 概率 | 缓解措施 |
|------|------|------|---------|
| 删除UI后无法调试 | 高 | 中 | 保留USB CDC调试输出使用LED指示关键状态 |
| 配置文件损坏导致设备无法启动 | 中 | 低 | 提供配置恢复机制使用CRC校验 |
| TX/RX功能提取不完整 | 高 | 中 | 充分测试,保留原代码作为参考 |
| Flash写入失败 | 中 | 低 | 添加错误处理,提供默认配置 |
| LED指示不够直观 | 低 | 中 | 定义清晰的闪烁模式文档 |
### 10.2 回滚计划
如果在实施过程中发现严重问题:
1. 保留原项目代码作为备份
2. 使用Git版本控制可随时回退
3. 分阶段实施,每阶段测试通过后再进行下一阶段
## 十二、总结
本计划详细描述了如何从现有项目中提取TX/RX核心功能删除所有UI相关代码并实现
1. **纯RF433通信功能**:专注于无线收发核心逻辑
2. **配置文件支持**从Flash读取配置无需菜单设置
3. **LED状态指示**使用LED替代OLED显示
4. **手动API接口**:保留外部触发的灵活性
5. **编译模式选择**支持TX/RX/双模三种编译模式
实施完成后将得到一个精简、高效、易于集成的RF433通信模块Flash占用减少约30KB去除UI库RAM占用减少约5KB更适合嵌入式产品应用。