Files
433_STM32/indexed-jingling-puffin.md

622 lines
16 KiB
Markdown
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.

# 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更适合嵌入式产品应用。