Files
433_STM32/docs/433模块重构技术方案_v1.0.md

2315 lines
60 KiB
Markdown
Raw Permalink 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-433模块重构技术方案
## 文档信息
- **版本**: v1.0
- **日期**: 2026-03-24
- **作者**: 系统架构师
- **项目**: E32-433TBH-SC
---
## 一、项目概况
### 1.1 项目背景
本项目是基于STM32F103C8T6微控制器的嵌入式系统使用STM32CubeMX代码生成框架。项目实现了E32-433T30S LoRa无线模块的控制通过USB CDC进行通信配备OLED显示(u8g2)和菜单系统。
### 1.2 当前架构
```
┌─────────────────────────────────────────────────────────┐
│ 应用层 (Application) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Menu系统 │ │ USB CDC │ │ OLED显示 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ E32模块层 (当前耦合) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ e32_demo.c │ │ e32_hal.c │ │ usart.c │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 硬件抽象层 (HAL) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ GPIO │ │ UART1 │ │ FIFO │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────┘
```
### 1.3 存在的问题
1. **耦合度高**: E32模块代码分散在多个文件中与USB、UART等模块紧密耦合
2. **可维护性差**: TX/RX模式代码混杂难以独立测试和维护
3. **资源浪费**: 未使用的TX/RX代码仍被编译占用Flash空间
4. **扩展性差**: 缺乏清晰的模块边界,难以移植到其他项目
---
## 二、已识别433相关代码清单
### 2.1 核心文件列表
| 文件路径 | 类型 | 功能描述 | 依赖关系 |
|---------|------|---------|---------|
| `Core/Inc/e32_hal.h` | 头文件 | E32硬件抽象层接口定义 | 无 |
| `Core/Src/e32_hal.c` | 源文件 | E32硬件抽象层实现 | main.h, gpio.h, usart.h |
| `Core/Inc/e32_demo.h` | 头文件 | E32演示应用接口定义 | e32_hal.h |
| `Core/Src/e32_demo.c` | 源文件 | E32演示应用实现 | e32_demo.h, main.h, application.h |
| `Core/Inc/fifo.h` | 头文件 | FIFO队列接口定义 | 无 |
| `Core/Src/fifo.c` | 源文件 | FIFO队列实现 | fifo.h |
| `Core/Inc/usart.h` | 头文件 | UART接口定义 | main.h |
| `Core/Src/usart.c` | 源文件 | UART实现含E32通信 | usart.h, fifo.h, usbd_cdc_if.h |
| `USB_DEVICE/App/usbd_cdc_if.c` | 源文件 | USB CDC接口含数据转发 | usbd_cdc_if.h |
| `USB_DEVICE/App/usbd_cdc_if.h` | 头文件 | USB CDC接口定义 | usbd_cdc.h |
### 2.2 关键数据结构
#### 2.2.1 工作模式枚举
```c
typedef enum
{
WORK_MODE_TRANSPARENT = 0x00, // 透明传输模式
WORK_MODE_WAKE_ON_RADIO_MASTER = 0x01, // WOR主模式
WORK_MODE_WAKE_ON_RADIO_SLAVE = 0x02, // WOR从模式
WORK_MODE_CONFIG_AND_SLEEP = 0x03, // 配置/睡眠模式
} work_mode_t;
```
#### 2.2.2 寄存器配置结构体
```c
typedef struct
{
struct { uint8_t address_h; } register_1; // 地址高字节
struct { uint8_t address_l; } register_2; // 地址低字节
union {
uint8_t value;
struct {
radio_rate_t radio_rate : 3; // 空中速率
uart_rate_t uart_baud_rate : 3; // 串口波特率
uart_parity_t uart_parity : 2; // 校验位
} field;
} register_3;
struct { uint8_t channel; } register_4; // 信道
union {
uint8_t value;
struct {
transmit_power_t tx_power : 2; // 发射功率
on_off_t packet_fec : 1; // FEC使能
wor_period_t wake_on_radio_period: 3; // WOR周期
on_off_t reserve : 1; // 保留
on_off_t specify_target : 1; // 指定目标传输
} field;
} register_5;
} e32_register_t;
```
#### 2.2.3 数据包结构体
```c
typedef struct
{
uint8_t address_h; // 目标地址高字节
uint8_t address_l; // 目标地址低字节
uint8_t channel; // 目标信道
uint8_t data[237]; // 数据最大237字节
} e32_specify_target_buffer_t;
```
### 2.3 硬件资源映射
| 硬件资源 | 引脚/外设 | 功能 | 配置 |
|---------|----------|------|------|
| UART1 | PA9(TX), PA10(RX) | E32模块串口通信 | 115200/9600 bps |
| M0 | GPIO | 模式选择引脚0 | 输出 |
| M1 | GPIO | 模式选择引脚1 | 输出 |
| AUX | GPIO | 辅助引脚(忙状态) | 输入 |
| RESET | GPIO | 复位引脚 | 输出 |
| USART1_IRQn | 中断 | UART接收中断 | 优先级0 |
### 2.4 TX/RX模式实现分析
#### 2.4.1 当前TX实现
- **位置**: `e32_demo.c` 中的 `e32_demo_transmit()` 函数
- **流程**:
1. 调用 `e32_hal_uart_tx()` 发送数据
2. 通过UART1发送到E32模块
3. E32模块在透明传输模式下自动发送
#### 2.4.2 当前RX实现
- **位置**: `usart.c` 中的 `HAL_UART_RxCpltCallback()` 回调
- **流程**:
1. UART1中断接收数据
2. 数据写入FIFO缓冲区
3. 通过USB CDC转发到PC
4. 使用超时机制判断数据包结束
#### 2.4.3 模式切换
- **位置**: `e32_hal.c` 中的 `e32_hal_work_mode()` 函数
- **实现**: 通过控制M0和M1引脚电平切换工作模式
- **等待**: 使用AUX引脚或延时等待模式切换完成
---
## 三、新模块架构设计
### 3.1 新模块目录树
```
Driver_RF433/
├── Inc/ # 头文件目录
│ ├── rf433.h # 主接口头文件
│ ├── rf433_config.h # 配置头文件
│ ├── rf433_hal.h # 硬件抽象层头文件
│ ├── rf433_tx.h # TX模式接口条件编译
│ └── rf433_rx.h # RX模式接口条件编译
├── Src/ # 源文件目录
│ ├── rf433.c # 主实现文件
│ ├── rf433_hal.c # 硬件抽象层实现
│ ├── rf433_tx.c # TX模式实现条件编译
│ └── rf433_rx.c # RX模式实现条件编译
└── docs/ # 文档目录
├── rf433_api.md # API文档
└── rf433_integration.md # 集成指南
```
### 3.2 模块架构图
```
┌─────────────────────────────────────────────────────────────┐
│ 应用层 (Application) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ Menu系统 │ │ USB CDC │ │ OLED显示 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ Driver_RF433 模块 (新设计) │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ rf433.h (统一接口) │ │
│ │ - rf433_init() │ │
│ │ - rf433_deinit() │ │
│ │ - rf433_set_config() │ │
│ │ - rf433_get_config() │ │
│ └──────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────┐ ┌──────────────────┐ │
│ │ rf433_tx.h/c │ │ rf433_rx.h/c │ │
│ │ (TX模式) │ │ (RX模式) │ │
│ │ - rf433_tx() │ │ - rf433_rx() │ │
│ │ - rf433_tx_... │ │ - rf433_rx_... │ │
│ └──────────────────┘ └──────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────────────────────┐ │
│ │ rf433_hal.h/c (硬件抽象层) │ │
│ │ - rf433_hal_uart_tx() │ │
│ │ - rf433_hal_uart_rx() │ │
│ │ - rf433_hal_gpio_init() │ │
│ │ - rf433_hal_work_mode() │ │
│ └──────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ 硬件抽象层 (HAL) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ GPIO │ │ UART1 │ │ FIFO │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────┘
```
### 3.3 模块依赖关系
```
Driver_RF433
├── HAL库 (STM32 HAL)
├── FIFO模块 (Core/Inc/fifo.h)
└── 应用层回调 (可选)
```
---
## 四、API接口定义
### 4.1 主接口 (rf433.h)
```c
/**
* @file rf433.h
* @brief E32-433模块驱动主接口
*/
#ifndef __RF433_H__
#define __RF433_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
#include <stdbool.h>
/* ============================================================================
* 配置宏定义
* ============================================================================ */
/**
* @brief 编译模式选择
* @note 必须在包含此头文件之前定义
* RF433_MODE_TX - 仅编译TX功能
* RF433_MODE_RX - 仅编译RX功能
* RF433_MODE_BOTH - 编译TX和RX功能默认
*/
#ifndef RF433_MODE
#define RF433_MODE RF433_MODE_BOTH
#endif
/**
* @brief FIFO缓冲区大小
*/
#define RF433_FIFO_SIZE 1024
/**
* @brief 最大数据包长度
*/
#define RF433_MAX_PACKET_SIZE 237
/**
* @brief 默认超时时间ms
*/
#define RF433_DEFAULT_TIMEOUT 100
/* ============================================================================
* 错误码定义
* ============================================================================ */
typedef enum
{
RF433_OK = 0, // 成功
RF433_ERROR = -1, // 通用错误
RF433_ERROR_BUSY = -2, // 模块忙
RF433_ERROR_TIMEOUT = -3, // 超时
RF433_ERROR_INVALID_PARAM = -4, // 无效参数
RF433_ERROR_NO_MEMORY = -5, // 内存不足
RF433_ERROR_NOT_INIT = -6, // 未初始化
} rf433_error_t;
/* ============================================================================
* 工作模式枚举
* ============================================================================ */
typedef enum
{
RF433_MODE_TRANSPARENT = 0x00, // 透明传输模式
RF433_MODE_WAKE_ON_RADIO_MASTER = 0x01, // WOR主模式
RF433_MODE_WAKE_ON_RADIO_SLAVE = 0x02, // WOR从模式
RF433_MODE_CONFIG_AND_SLEEP = 0x03, // 配置/睡眠模式
} rf433_work_mode_t;
/* ============================================================================
* 配置参数枚举
* ============================================================================ */
typedef enum
{
RF433_RADIO_RATE_2400 = 0x02,
RF433_RADIO_RATE_4800 = 0x03,
RF433_RADIO_RATE_9600 = 0x04,
RF433_RADIO_RATE_19200 = 0x05,
RF433_RADIO_RATE_38400 = 0x06,
RF433_RADIO_RATE_62500 = 0x07,
} rf433_radio_rate_t;
typedef enum
{
RF433_UART_8N1 = 0x00,
RF433_UART_8O1 = 0x01,
RF433_UART_8E1 = 0x02,
} rf433_uart_parity_t;
typedef enum
{
RF433_UART_RATE_1200 = 0x00,
RF433_UART_RATE_2400 = 0x01,
RF433_UART_RATE_4800 = 0x02,
RF433_UART_RATE_9600 = 0x03,
RF433_UART_RATE_19200 = 0x04,
RF433_UART_RATE_38400 = 0x05,
RF433_UART_RATE_57600 = 0x06,
RF433_UART_RATE_115200= 0x07,
} rf433_uart_rate_t;
typedef enum
{
RF433_TX_POWER_DBM_30 = 0x00,
RF433_TX_POWER_DBM_27 = 0x01,
RF433_TX_POWER_DBM_24 = 0x02,
RF433_TX_POWER_DBM_21 = 0x03,
} rf433_tx_power_t;
typedef enum
{
RF433_OFF = 0x00,
RF433_ON = 0x01,
} rf433_on_off_t;
/* ============================================================================
* 配置结构体
* ============================================================================ */
typedef struct
{
uint16_t address; // 模块地址 (0-65535, 65535为广播地址)
uint8_t channel; // 信道 (0-83)
rf433_radio_rate_t radio_rate; // 空中速率
rf433_uart_rate_t uart_rate; // 串口波特率
rf433_uart_parity_t uart_parity; // 校验位
rf433_tx_power_t tx_power; // 发射功率
rf433_on_off_t fec_enable; // FEC使能
rf433_on_off_t specify_target;// 指定目标传输
} rf433_config_t;
/* ============================================================================
* 数据包结构体
* ============================================================================ */
typedef struct
{
uint16_t address; // 目标地址
uint8_t channel; // 目标信道
uint8_t data[RF433_MAX_PACKET_SIZE]; // 数据
uint16_t length; // 数据长度
} rf433_packet_t;
/* ============================================================================
* 回调函数类型定义
* ============================================================================ */
/**
* @brief 数据接收回调函数类型
* @param packet 接收到的数据包
* @param user_data 用户数据
*/
typedef void (*rf433_rx_callback_t)(const rf433_packet_t *packet, void *user_data);
/**
* @brief 发送完成回调函数类型
* @param status 发送状态
* @param user_data 用户数据
*/
typedef void (*rf433_tx_callback_t)(rf433_error_t status, void *user_data);
/* ============================================================================
* 核心API函数
* ============================================================================ */
/**
* @brief 初始化RF433模块
* @param config 初始配置NULL使用默认配置
* @return RF433_OK 成功
* RF433_ERROR 失败
*/
rf433_error_t rf433_init(const rf433_config_t *config);
/**
* @brief 反初始化RF433模块
* @return RF433_OK 成功
*/
rf433_error_t rf433_deinit(void);
/**
* @brief 设置模块配置
* @param config 配置参数
* @return RF433_OK 成功
* RF433_ERROR_BUSY 模块忙
* RF433_ERROR_TIMEOUT 超时
*/
rf433_error_t rf433_set_config(const rf433_config_t *config);
/**
* @brief 获取模块配置
* @param config 配置参数输出
* @return RF433_OK 成功
* RF433_ERROR_INVALID_PARAM 无效参数
*/
rf433_error_t rf433_get_config(rf433_config_t *config);
/**
* @brief 设置工作模式
* @param mode 工作模式
* @return RF433_OK 成功
* RF433_ERROR_BUSY 模块忙
*/
rf433_error_t rf433_set_work_mode(rf433_work_mode_t mode);
/**
* @brief 复位模块
* @return RF433_OK 成功
*/
rf433_error_t rf433_reset(void);
/* ============================================================================
* 条件编译的TX/RX API
* ============================================================================ */
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
#include "rf433_tx.h"
#endif
#if (RF433_MODE == RF433_MODE_RX) || (RF433_MODE == RF433_MODE_BOTH)
#include "rf433_rx.h"
#endif
#ifdef __cplusplus
}
#endif
#endif /* __RF433_H__ */
```
### 4.2 TX模式接口 (rf433_tx.h)
```c
/**
* @file rf433_tx.h
* @brief RF433 TX模式接口
*/
#ifndef __RF433_TX_H__
#define __RF433_TX_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "rf433.h"
/* ============================================================================
* TX模式API函数
* ============================================================================ */
/**
* @brief 发送数据(透明传输模式)
* @param data 数据指针
* @param length 数据长度
* @param timeout 超时时间ms
* @return RF433_OK 成功
* RF433_ERROR_BUSY 模块忙
* RF433_ERROR_TIMEOUT 超时
* RF433_ERROR_INVALID_PARAM 无效参数
*/
rf433_error_t rf433_tx_transparent(const uint8_t *data, uint16_t length, uint32_t timeout);
/**
* @brief 发送数据包(指定目标模式)
* @param packet 数据包
* @param timeout 超时时间ms
* @return RF433_OK 成功
* RF433_ERROR_BUSY 模块忙
* RF433_ERROR_TIMEOUT 超时
* RF433_ERROR_INVALID_PARAM 无效参数
*/
rf433_error_t rf433_tx_packet(const rf433_packet_t *packet, uint32_t timeout);
/**
* @brief 异步发送数据(透明传输模式)
* @param data 数据指针
* @param length 数据长度
* @param callback 发送完成回调
* @param user_data 用户数据
* @return RF433_OK 成功(已加入发送队列)
* RF433_ERROR_BUSY 发送队列满
* RF433_ERROR_INVALID_PARAM 无效参数
*/
rf433_error_t rf433_tx_transparent_async(const uint8_t *data, uint16_t length,
rf433_tx_callback_t callback, void *user_data);
/**
* @brief 异步发送数据包(指定目标模式)
* @param packet 数据包
* @param callback 发送完成回调
* @param user_data 用户数据
* @return RF433_OK 成功(已加入发送队列)
* RF433_ERROR_BUSY 发送队列满
* RF433_ERROR_INVALID_PARAM 无效参数
*/
rf433_error_t rf433_tx_packet_async(const rf433_packet_t *packet,
rf433_tx_callback_t callback, void *user_data);
/**
* @brief 取消发送
* @return RF433_OK 成功
*/
rf433_error_t rf433_tx_cancel(void);
/**
* @brief 获取发送状态
* @param is_busy 忙状态输出
* @return RF433_OK 成功
*/
rf433_error_t rf433_tx_get_status(bool *is_busy);
#ifdef __cplusplus
}
#endif
#endif /* __RF433_TX_H__ */
```
### 4.3 RX模式接口 (rf433_rx.h)
```c
/**
* @file rf433_rx.h
* @brief RF433 RX模式接口
*/
#ifndef __RF433_RX_H__
#define __RF433_RX_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "rf433.h"
/* ============================================================================
* RX模式API函数
* ============================================================================ */
/**
* @brief 启动接收
* @return RF433_OK 成功
* RF433_ERROR_BUSY 模块忙
*/
rf433_error_t rf433_rx_start(void);
/**
* @brief 停止接收
* @return RF433_OK 成功
*/
rf433_error_t rf433_rx_stop(void);
/**
* @brief 接收数据(阻塞模式)
* @param packet 数据包输出
* @param timeout 超时时间ms
* @return RF433_OK 成功
* RF433_ERROR_TIMEOUT 超时
* RF433_ERROR_INVALID_PARAM 无效参数
*/
rf433_error_t rf433_rx_receive(rf433_packet_t *packet, uint32_t timeout);
/**
* @brief 检查是否有数据可读
* @param has_data 是否有数据输出
* @return RF433_OK 成功
*/
rf433_error_t rf433_rx_check_data(bool *has_data);
/**
* @brief 读取数据(非阻塞模式)
* @param packet 数据包输出
* @return RF433_OK 成功
* RF433_ERROR_NO_DATA 无数据
* RF433_ERROR_INVALID_PARAM 无效参数
*/
rf433_error_t rf433_rx_read(rf433_packet_t *packet);
/**
* @brief 注册接收回调函数
* @param callback 回调函数
* @param user_data 用户数据
* @return RF433_OK 成功
* RF433_ERROR_INVALID_PARAM 无效参数
*/
rf433_error_t rf433_rx_register_callback(rf433_rx_callback_t callback, void *user_data);
/**
* @brief 注销接收回调函数
* @return RF433_OK 成功
*/
rf433_error_t rf433_rx_unregister_callback(void);
/**
* @brief 获取接收统计信息
* @param total_packets 总接收包数
* @param total_bytes 总接收字节数
* @param error_packets 错误包数
* @return RF433_OK 成功
*/
rf433_error_t rf433_rx_get_stats(uint32_t *total_packets, uint32_t *total_bytes,
uint32_t *error_packets);
/**
* @brief 清除接收统计信息
* @return RF433_OK 成功
*/
rf433_error_t rf433_rx_clear_stats(void);
#ifdef __cplusplus
}
#endif
#endif /* __RF433_RX_H__ */
```
### 4.4 硬件抽象层接口 (rf433_hal.h)
```c
/**
* @file rf433_hal.h
* @brief RF433硬件抽象层接口
*/
#ifndef __RF433_HAL_H__
#define __RF433_HAL_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "rf433.h"
/* ============================================================================
* HAL配置宏
* ============================================================================ */
/**
* @brief 是否使用AUX引脚检测忙状态
* @note 1: 使用AUX引脚推荐
* 0: 使用延时(不推荐)
*/
#ifndef RF433_USE_GPIO_AUX
#define RF433_USE_GPIO_AUX 1
#endif
/**
* @brief AUX引脚忙等待超时时间ms
*/
#ifndef RF433_AUX_TIMEOUT
#define RF433_AUX_TIMEOUT 100
#endif
/* ============================================================================
* HAL初始化函数
* ============================================================================ */
/**
* @brief 初始化硬件抽象层
* @return RF433_OK 成功
* RF433_ERROR 失败
*/
rf433_error_t rf433_hal_init(void);
/**
* @brief 反初始化硬件抽象层
* @return RF433_OK 成功
*/
rf433_error_t rf433_hal_deinit(void);
/* ============================================================================
* UART通信函数
* ============================================================================ */
/**
* @brief UART发送数据
* @param data 数据指针
* @param length 数据长度
* @param timeout 超时时间ms
* @return RF433_OK 成功
* RF433_ERROR_TIMEOUT 超时
*/
rf433_error_t rf433_hal_uart_tx(const uint8_t *data, uint16_t length, uint32_t timeout);
/**
* @brief UART接收数据阻塞模式
* @param data 数据缓冲区
* @param length 期望接收长度
* @param timeout 超时时间ms
* @param actual_length 实际接收长度
* @return RF433_OK 成功
* RF433_ERROR_TIMEOUT 超时
*/
rf433_error_t rf433_hal_uart_rx(uint8_t *data, uint16_t length, uint32_t timeout,
uint16_t *actual_length);
/**
* @brief UART接收数据中断模式
* @param data 数据缓冲区
* @param length 期望接收长度
* @return RF433_OK 成功(已启动接收)
* RF433_ERROR_BUSY 接收忙
*/
rf433_error_t rf433_hal_uart_rx_it(uint8_t *data, uint16_t length);
/**
* @brief UART接收完成回调
* @param data 数据指针
* @param length 接收长度
*/
void rf433_hal_uart_rx_callback(uint8_t *data, uint16_t length);
/* ============================================================================
* GPIO控制函数
* ============================================================================ */
/**
* @brief 等待AUX引脚变为空闲
* @return RF433_OK 成功
* RF433_ERROR_TIMEOUT 超时
*/
rf433_error_t rf433_hal_aux_wait(void);
/**
* @brief 设置工作模式
* @param mode 工作模式
* @return RF433_OK 成功
*/
rf433_error_t rf433_hal_set_work_mode(rf433_work_mode_t mode);
/**
* @brief 复位模块
* @return RF433_OK 成功
*/
rf433_error_t rf433_hal_reset(void);
/* ============================================================================
* FIFO操作函数
* ============================================================================ */
/**
* @brief 写入FIFO
* @param data 数据指针
* @param length 数据长度
* @return RF433_OK 成功
* RF433_ERROR_FULL FIFO满
*/
rf433_error_t rf433_hal_fifo_write(const uint8_t *data, uint16_t length);
/**
* @brief 读取FIFO
* @param data 数据缓冲区
* @param length 期望读取长度
* @param actual_length 实际读取长度
* @return RF433_OK 成功
* RF433_ERROR_EMPTY FIFO空
*/
rf433_error_t rf433_hal_fifo_read(uint8_t *data, uint16_t length, uint16_t *actual_length);
/**
* @brief 获取FIFO数据长度
* @param length 数据长度输出
* @return RF433_OK 成功
*/
rf433_error_t rf433_hal_fifo_get_length(uint16_t *length);
/**
* @brief 清空FIFO
* @return RF433_OK 成功
*/
rf433_error_t rf433_hal_fifo_clear(void);
#ifdef __cplusplus
}
#endif
#endif /* __RF433_HAL_H__ */
```
---
## 五、关键代码片段示例
### 5.1 模块初始化示例
```c
/**
* @file rf433.c
* @brief RF433模块主实现
*/
#include "rf433.h"
#include "rf433_hal.h"
#include <string.h>
/* ============================================================================
* 私有变量
* ============================================================================ */
static bool rf433_initialized = false;
static rf433_config_t rf433_current_config;
/* 默认配置 */
static const rf433_config_t rf433_default_config = {
.address = 0x0000,
.channel = 0x17,
.radio_rate = RF433_RADIO_RATE_2400,
.uart_rate = RF433_UART_RATE_9600,
.uart_parity = RF433_UART_8N1,
.tx_power = RF433_TX_POWER_DBM_30,
.fec_enable = RF433_ON,
.specify_target = RF433_OFF,
};
/* ============================================================================
* 公共函数实现
* ============================================================================ */
rf433_error_t rf433_init(const rf433_config_t *config)
{
rf433_error_t ret;
/* 检查是否已初始化 */
if (rf433_initialized)
{
return RF433_ERROR;
}
/* 初始化硬件抽象层 */
ret = rf433_hal_init();
if (ret != RF433_OK)
{
return ret;
}
/* 复制配置 */
if (config == NULL)
{
memcpy(&rf433_current_config, &rf433_default_config, sizeof(rf433_config_t));
}
else
{
memcpy(&rf433_current_config, config, sizeof(rf433_config_t));
}
/* 设置模块配置 */
ret = rf433_set_config(&rf433_current_config);
if (ret != RF433_OK)
{
rf433_hal_deinit();
return ret;
}
/* 初始化TX/RX子模块 */
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
ret = rf433_tx_init();
if (ret != RF433_OK)
{
rf433_hal_deinit();
return ret;
}
#endif
#if (RF433_MODE == RF433_MODE_RX) || (RF433_MODE == RF433_MODE_BOTH)
ret = rf433_rx_init();
if (ret != RF433_OK)
{
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
rf433_tx_deinit();
#endif
rf433_hal_deinit();
return ret;
}
#endif
rf433_initialized = true;
return RF433_OK;
}
rf433_error_t rf433_deinit(void)
{
/* 检查是否已初始化 */
if (!rf433_initialized)
{
return RF433_ERROR_NOT_INIT;
}
/* 反初始化TX/RX子模块 */
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
rf433_tx_deinit();
#endif
#if (RF433_MODE == RF433_MODE_RX) || (RF433_MODE == RF433_MODE_BOTH)
rf433_rx_deinit();
#endif
/* 反初始化硬件抽象层 */
rf433_hal_deinit();
rf433_initialized = false;
return RF433_OK;
}
rf433_error_t rf433_set_config(const rf433_config_t *config)
{
rf433_error_t ret;
uint8_t cmd_buffer[7];
/* 参数检查 */
if (config == NULL)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 等待模块空闲 */
ret = rf433_hal_aux_wait();
if (ret != RF433_OK)
{
return ret;
}
/* 切换到配置模式 */
ret = rf433_hal_set_work_mode(RF433_MODE_CONFIG_AND_SLEEP);
if (ret != RF433_OK)
{
return ret;
}
/* 构造配置命令 */
cmd_buffer[0] = 0xC0; // 写配置命令
cmd_buffer[1] = (config->address >> 8) & 0xFF;
cmd_buffer[2] = config->address & 0xFF;
cmd_buffer[3] = (config->uart_rate << 5) | (config->uart_parity << 3) | config->radio_rate;
cmd_buffer[4] = config->channel;
cmd_buffer[5] = (config->specify_target << 7) | (config->reserve << 6) |
(config->fec_enable << 2) | config->tx_power;
cmd_buffer[6] = 0x00; // 保留字节
/* 发送配置命令 */
ret = rf433_hal_uart_tx(cmd_buffer, sizeof(cmd_buffer), RF433_DEFAULT_TIMEOUT);
if (ret != RF433_OK)
{
return ret;
}
/* 等待配置完成 */
ret = rf433_hal_aux_wait();
if (ret != RF433_OK)
{
return ret;
}
/* 切换回透明传输模式 */
ret = rf433_hal_set_work_mode(RF433_MODE_TRANSPARENT);
if (ret != RF433_OK)
{
return ret;
}
/* 保存配置 */
memcpy(&rf433_current_config, config, sizeof(rf433_config_t));
return RF433_OK;
}
rf433_error_t rf433_get_config(rf433_config_t *config)
{
/* 参数检查 */
if (config == NULL)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 复制当前配置 */
memcpy(config, &rf433_current_config, sizeof(rf433_config_t));
return RF433_OK;
}
rf433_error_t rf433_set_work_mode(rf433_work_mode_t mode)
{
return rf433_hal_set_work_mode(mode);
}
rf433_error_t rf433_reset(void)
{
return rf433_hal_reset();
}
```
### 5.2 TX模式实现示例
```c
/**
* @file rf433_tx.c
* @brief RF433 TX模式实现
*/
#include "rf433_tx.h"
#include "rf433_hal.h"
#include <string.h>
/* ============================================================================
* 私有变量
* ============================================================================ */
static bool rf433_tx_initialized = false;
static bool rf433_tx_busy = false;
/* ============================================================================
* 公共函数实现
* ============================================================================ */
rf433_error_t rf433_tx_init(void)
{
rf433_tx_initialized = true;
rf433_tx_busy = false;
return RF433_OK;
}
rf433_error_t rf433_tx_deinit(void)
{
rf433_tx_initialized = false;
rf433_tx_busy = false;
return RF433_OK;
}
rf433_error_t rf433_tx_transparent(const uint8_t *data, uint16_t length, uint32_t timeout)
{
rf433_error_t ret;
/* 参数检查 */
if (data == NULL || length == 0)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 检查是否已初始化 */
if (!rf433_tx_initialized)
{
return RF433_ERROR_NOT_INIT;
}
/* 检查是否忙 */
if (rf433_tx_busy)
{
return RF433_ERROR_BUSY;
}
/* 等待模块空闲 */
ret = rf433_hal_aux_wait();
if (ret != RF433_OK)
{
return ret;
}
/* 设置忙标志 */
rf433_tx_busy = true;
/* 发送数据 */
ret = rf433_hal_uart_tx(data, length, timeout);
/* 清除忙标志 */
rf433_tx_busy = false;
return ret;
}
rf433_error_t rf433_tx_packet(const rf433_packet_t *packet, uint32_t timeout)
{
rf433_error_t ret;
uint8_t buffer[RF433_MAX_PACKET_SIZE + 3];
/* 参数检查 */
if (packet == NULL || packet->length > RF433_MAX_PACKET_SIZE)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 检查是否已初始化 */
if (!rf433_tx_initialized)
{
return RF433_ERROR_NOT_INIT;
}
/* 检查是否忙 */
if (rf433_tx_busy)
{
return RF433_ERROR_BUSY;
}
/* 等待模块空闲 */
ret = rf433_hal_aux_wait();
if (ret != RF433_OK)
{
return ret;
}
/* 构造数据包 */
buffer[0] = (packet->address >> 8) & 0xFF;
buffer[1] = packet->address & 0xFF;
buffer[2] = packet->channel;
memcpy(&buffer[3], packet->data, packet->length);
/* 设置忙标志 */
rf433_tx_busy = true;
/* 发送数据包 */
ret = rf433_hal_uart_tx(buffer, packet->length + 3, timeout);
/* 清除忙标志 */
rf433_tx_busy = false;
return ret;
}
rf433_error_t rf433_tx_transparent_async(const uint8_t *data, uint16_t length,
rf433_tx_callback_t callback, void *user_data)
{
/* TODO: 实现异步发送 */
return RF433_ERROR;
}
rf433_error_t rf433_tx_packet_async(const rf433_packet_t *packet,
rf433_tx_callback_t callback, void *user_data)
{
/* TODO: 实现异步发送 */
return RF433_ERROR;
}
rf433_error_t rf433_tx_cancel(void)
{
/* TODO: 实现取消发送 */
return RF433_ERROR;
}
rf433_error_t rf433_tx_get_status(bool *is_busy)
{
if (is_busy == NULL)
{
return RF433_ERROR_INVALID_PARAM;
}
*is_busy = rf433_tx_busy;
return RF433_OK;
}
```
### 5.3 RX模式实现示例
```c
/**
* @file rf433_rx.c
* @brief RF433 RX模式实现
*/
#include "rf433_rx.h"
#include "rf433_hal.h"
#include <string.h>
/* ============================================================================
* 私有变量
* ============================================================================ */
static bool rf433_rx_initialized = false;
static bool rf433_rx_started = false;
static rf433_rx_callback_t rf433_rx_callback = NULL;
static void *rf433_rx_user_data = NULL;
/* 接收统计 */
static uint32_t rf433_rx_total_packets = 0;
static uint32_t rf433_rx_total_bytes = 0;
static uint32_t rf433_rx_error_packets = 0;
/* ============================================================================
* 公共函数实现
* ============================================================================ */
rf433_error_t rf433_rx_init(void)
{
rf433_rx_initialized = true;
rf433_rx_started = false;
rf433_rx_callback = NULL;
rf433_rx_user_data = NULL;
rf433_rx_total_packets = 0;
rf433_rx_total_bytes = 0;
rf433_rx_error_packets = 0;
return RF433_OK;
}
rf433_error_t rf433_rx_deinit(void)
{
rf433_rx_stop();
rf433_rx_initialized = false;
return RF433_OK;
}
rf433_error_t rf433_rx_start(void)
{
rf433_error_t ret;
/* 检查是否已初始化 */
if (!rf433_rx_initialized)
{
return RF433_ERROR_NOT_INIT;
}
/* 检查是否已启动 */
if (rf433_rx_started)
{
return RF433_ERROR_BUSY;
}
/* 清空FIFO */
ret = rf433_hal_fifo_clear();
if (ret != RF433_OK)
{
return ret;
}
/* 启动UART接收 */
uint8_t dummy;
ret = rf433_hal_uart_rx_it(&dummy, 1);
if (ret != RF433_OK)
{
return ret;
}
rf433_rx_started = true;
return RF433_OK;
}
rf433_error_t rf433_rx_stop(void)
{
/* 检查是否已初始化 */
if (!rf433_rx_initialized)
{
return RF433_ERROR_NOT_INIT;
}
rf433_rx_started = false;
return RF433_OK;
}
rf433_error_t rf433_rx_receive(rf433_packet_t *packet, uint32_t timeout)
{
rf433_error_t ret;
uint16_t length;
uint32_t start_time;
/* 参数检查 */
if (packet == NULL)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 检查是否已初始化 */
if (!rf433_rx_initialized)
{
return RF433_ERROR_NOT_INIT;
}
/* 等待数据 */
start_time = HAL_GetTick();
while (true)
{
ret = rf433_hal_fifo_get_length(&length);
if (ret != RF433_OK)
{
return ret;
}
if (length > 0)
{
break;
}
/* 检查超时 */
if (timeout > 0 && (HAL_GetTick() - start_time) >= timeout)
{
return RF433_ERROR_TIMEOUT;
}
HAL_Delay(1);
}
/* 读取数据 */
if (length > RF433_MAX_PACKET_SIZE)
{
length = RF433_MAX_PACKET_SIZE;
}
ret = rf433_hal_fifo_read(packet->data, length, &packet->length);
if (ret != RF433_OK)
{
return ret;
}
/* 更新统计 */
rf433_rx_total_packets++;
rf433_rx_total_bytes += packet->length;
return RF433_OK;
}
rf433_error_t rf433_rx_check_data(bool *has_data)
{
rf433_error_t ret;
uint16_t length;
/* 参数检查 */
if (has_data == NULL)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 检查是否已初始化 */
if (!rf433_rx_initialized)
{
return RF433_ERROR_NOT_INIT;
}
/* 获取FIFO长度 */
ret = rf433_hal_fifo_get_length(&length);
if (ret != RF433_OK)
{
return ret;
}
*has_data = (length > 0);
return RF433_OK;
}
rf433_error_t rf433_rx_read(rf433_packet_t *packet)
{
rf433_error_t ret;
uint16_t length;
/* 参数检查 */
if (packet == NULL)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 检查是否已初始化 */
if (!rf433_rx_initialized)
{
return RF433_ERROR_NOT_INIT;
}
/* 获取FIFO长度 */
ret = rf433_hal_fifo_get_length(&length);
if (ret != RF433_OK)
{
return ret;
}
/* 检查是否有数据 */
if (length == 0)
{
return RF433_ERROR_NO_DATA;
}
/* 读取数据 */
if (length > RF433_MAX_PACKET_SIZE)
{
length = RF433_MAX_PACKET_SIZE;
}
ret = rf433_hal_fifo_read(packet->data, length, &packet->length);
if (ret != RF433_OK)
{
return ret;
}
/* 更新统计 */
rf433_rx_total_packets++;
rf433_rx_total_bytes += packet->length;
return RF433_OK;
}
rf433_error_t rf433_rx_register_callback(rf433_rx_callback_t callback, void *user_data)
{
/* 参数检查 */
if (callback == NULL)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 检查是否已初始化 */
if (!rf433_rx_initialized)
{
return RF433_ERROR_NOT_INIT;
}
rf433_rx_callback = callback;
rf433_rx_user_data = user_data;
return RF433_OK;
}
rf433_error_t rf433_rx_unregister_callback(void)
{
rf433_rx_callback = NULL;
rf433_rx_user_data = NULL;
return RF433_OK;
}
rf433_error_t rf433_rx_get_stats(uint32_t *total_packets, uint32_t *total_bytes,
uint32_t *error_packets)
{
/* 检查是否已初始化 */
if (!rf433_rx_initialized)
{
return RF433_ERROR_NOT_INIT;
}
if (total_packets != NULL)
{
*total_packets = rf433_rx_total_packets;
}
if (total_bytes != NULL)
{
*total_bytes = rf433_rx_total_bytes;
}
if (error_packets != NULL)
{
*error_packets = rf433_rx_error_packets;
}
return RF433_OK;
}
rf433_error_t rf433_rx_clear_stats(void)
{
/* 检查是否已初始化 */
if (!rf433_rx_initialized)
{
return RF433_ERROR_NOT_INIT;
}
rf433_rx_total_packets = 0;
rf433_rx_total_bytes = 0;
rf433_rx_error_packets = 0;
return RF433_OK;
}
/* ============================================================================
* UART接收回调由HAL层调用
* ============================================================================ */
void rf433_rx_uart_callback(uint8_t *data, uint16_t length)
{
rf433_error_t ret;
rf433_packet_t packet;
/* 检查是否已启动 */
if (!rf433_rx_started)
{
return;
}
/* 写入FIFO */
ret = rf433_hal_fifo_write(data, length);
if (ret != RF433_OK)
{
rf433_rx_error_packets++;
return;
}
/* 如果有回调函数,调用回调 */
if (rf433_rx_callback != NULL)
{
/* 读取数据 */
ret = rf433_hal_fifo_read(packet.data, RF433_MAX_PACKET_SIZE, &packet.length);
if (ret == RF433_OK)
{
/* 调用回调 */
rf433_rx_callback(&packet, rf433_rx_user_data);
}
}
}
```
### 5.4 硬件抽象层实现示例
```c
/**
* @file rf433_hal.c
* @brief RF433硬件抽象层实现
*/
#include "rf433_hal.h"
#include "main.h"
#include "usart.h"
#include "gpio.h"
#include <string.h>
/* ============================================================================
* 私有变量
* ============================================================================ */
static bool rf433_hal_initialized = false;
static uint8_t rf433_fifo_buffer[RF433_FIFO_SIZE];
static fifo_t rf433_fifo;
static uint8_t rf433_uart_rx_buffer[256];
static uint16_t rf433_uart_rx_index = 0;
static volatile uint32_t rf433_uart_rx_timeout = 0;
static volatile bool rf433_uart_rx_done = false;
/* ============================================================================
* 公共函数实现
* ============================================================================ */
rf433_error_t rf433_hal_init(void)
{
fifo_error_t ret;
/* 检查是否已初始化 */
if (rf433_hal_initialized)
{
return RF433_ERROR;
}
/* 初始化FIFO */
ret = fifo_create(&rf433_fifo, rf433_fifo_buffer, RF433_FIFO_SIZE);
if (ret != FIFO_OK)
{
return RF433_ERROR;
}
rf433_hal_initialized = true;
return RF433_OK;
}
rf433_error_t rf433_hal_deinit(void)
{
/* 检查是否已初始化 */
if (!rf433_hal_initialized)
{
return RF433_ERROR_NOT_INIT;
}
rf433_hal_initialized = false;
return RF433_OK;
}
rf433_error_t rf433_hal_uart_tx(const uint8_t *data, uint16_t length, uint32_t timeout)
{
HAL_StatusTypeDef ret;
/* 参数检查 */
if (data == NULL || length == 0)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 发送数据 */
ret = HAL_UART_Transmit(&huart1, (uint8_t *)data, length, timeout);
if (ret != HAL_OK)
{
return RF433_ERROR_TIMEOUT;
}
return RF433_OK;
}
rf433_error_t rf433_hal_uart_rx(uint8_t *data, uint16_t length, uint32_t timeout,
uint16_t *actual_length)
{
HAL_StatusTypeDef ret;
/* 参数检查 */
if (data == NULL || length == 0 || actual_length == NULL)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 接收数据 */
ret = HAL_UART_Receive(&huart1, data, length, timeout);
if (ret != HAL_OK)
{
*actual_length = 0;
return RF433_ERROR_TIMEOUT;
}
*actual_length = length;
return RF433_OK;
}
rf433_error_t rf433_hal_uart_rx_it(uint8_t *data, uint16_t length)
{
HAL_StatusTypeDef ret;
/* 参数检查 */
if (data == NULL || length == 0)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 启动中断接收 */
ret = HAL_UART_Receive_IT(&huart1, data, length);
if (ret != HAL_OK)
{
return RF433_ERROR_BUSY;
}
return RF433_OK;
}
rf433_error_t rf433_hal_aux_wait(void)
{
#if RF433_USE_GPIO_AUX
uint32_t start_time;
/* 等待AUX引脚变为高电平 */
start_time = HAL_GetTick();
while (HAL_GPIO_ReadPin(AUX_GPIO_Port, AUX_Pin) == GPIO_PIN_RESET)
{
/* 检查超时 */
if ((HAL_GetTick() - start_time) >= RF433_AUX_TIMEOUT)
{
return RF433_ERROR_TIMEOUT;
}
}
/* 等待AUX引脚稳定 */
HAL_Delay(2);
#else
/* 使用延时等待 */
HAL_Delay(30);
#endif
return RF433_OK;
}
rf433_error_t rf433_hal_set_work_mode(rf433_work_mode_t mode)
{
rf433_error_t ret;
/* 等待模块空闲 */
ret = rf433_hal_aux_wait();
if (ret != RF433_OK)
{
return ret;
}
/* 设置M0和M1引脚 */
switch (mode)
{
case RF433_MODE_TRANSPARENT:
HAL_GPIO_WritePin(M0_GPIO_Port, M0_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(M1_GPIO_Port, M1_Pin, GPIO_PIN_RESET);
break;
case RF433_MODE_WAKE_ON_RADIO_MASTER:
HAL_GPIO_WritePin(M0_GPIO_Port, M0_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(M1_GPIO_Port, M1_Pin, GPIO_PIN_RESET);
break;
case RF433_MODE_WAKE_ON_RADIO_SLAVE:
HAL_GPIO_WritePin(M0_GPIO_Port, M0_Pin, GPIO_PIN_RESET);
HAL_GPIO_WritePin(M1_GPIO_Port, M1_Pin, GPIO_PIN_SET);
break;
case RF433_MODE_CONFIG_AND_SLEEP:
HAL_GPIO_WritePin(M0_GPIO_Port, M0_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(M1_GPIO_Port, M1_Pin, GPIO_PIN_SET);
break;
default:
return RF433_ERROR_INVALID_PARAM;
}
/* 等待模式切换完成 */
HAL_Delay(5);
ret = rf433_hal_aux_wait();
if (ret != RF433_OK)
{
return ret;
}
return RF433_OK;
}
rf433_error_t rf433_hal_reset(void)
{
/* 拉低复位引脚 */
HAL_GPIO_WritePin(RESET_GPIO_Port, RESET_Pin, GPIO_PIN_RESET);
HAL_Delay(1);
/* 拉高复位引脚 */
HAL_GPIO_WritePin(RESET_GPIO_Port, RESET_Pin, GPIO_PIN_SET);
/* 等待复位完成 */
#if RF433_USE_GPIO_AUX
HAL_Delay(10);
return rf433_hal_aux_wait();
#else
HAL_Delay(30);
return RF433_OK;
#endif
}
rf433_error_t rf433_hal_fifo_write(const uint8_t *data, uint16_t length)
{
fifo_error_t ret;
/* 参数检查 */
if (data == NULL || length == 0)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 写入FIFO */
ret = fifo_write(&rf433_fifo, (uint8_t *)data, length);
if (ret != FIFO_OK)
{
return RF433_ERROR;
}
return RF433_OK;
}
rf433_error_t rf433_hal_fifo_read(uint8_t *data, uint16_t length, uint16_t *actual_length)
{
fifo_error_t ret;
uint32_t fifo_length;
/* 参数检查 */
if (data == NULL || length == 0 || actual_length == NULL)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 获取FIFO长度 */
ret = fifo_get_length(&rf433_fifo, &fifo_length);
if (ret != FIFO_OK)
{
return RF433_ERROR;
}
/* 检查是否有数据 */
if (fifo_length == 0)
{
*actual_length = 0;
return RF433_ERROR;
}
/* 读取数据 */
if (fifo_length > length)
{
fifo_length = length;
}
ret = fifo_read(&rf433_fifo, data, fifo_length);
if (ret != FIFO_OK)
{
*actual_length = 0;
return RF433_ERROR;
}
*actual_length = fifo_length;
return RF433_OK;
}
rf433_error_t rf433_hal_fifo_get_length(uint16_t *length)
{
fifo_error_t ret;
uint32_t fifo_length;
/* 参数检查 */
if (length == NULL)
{
return RF433_ERROR_INVALID_PARAM;
}
/* 获取FIFO长度 */
ret = fifo_get_length(&rf433_fifo, &fifo_length);
if (ret != FIFO_OK)
{
return RF433_ERROR;
}
*length = fifo_length;
return RF433_OK;
}
rf433_error_t rf433_hal_fifo_clear(void)
{
fifo_error_t ret;
/* 清空FIFO */
ret = fifo_clear(&rf433_fifo);
if (ret != FIFO_OK)
{
return RF433_ERROR;
}
return RF433_OK;
}
/* ============================================================================
* UART接收中断回调
* ============================================================================ */
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if (huart->Instance == USART1)
{
/* 写入FIFO */
fifo_write(&rf433_fifo, rf433_uart_rx_buffer, rf433_uart_rx_index);
/* 设置超时 */
rf433_uart_rx_timeout = 10;
/* 重新启动接收 */
HAL_UART_Receive_IT(&huart1, rf433_uart_rx_buffer, 1);
rf433_uart_rx_index = 1;
}
}
/* ============================================================================
* 1ms定时器回调用于超时检测
* ============================================================================ */
void rf433_hal_1ms_callback(void)
{
/* UART接收超时检测 */
if (rf433_uart_rx_timeout > 0)
{
rf433_uart_rx_timeout--;
if (rf433_uart_rx_timeout == 0)
{
rf433_uart_rx_done = true;
}
}
}
```
---
## 六、解耦操作步骤
### 6.1 第一阶段:准备工作
#### 步骤1备份现有代码
```bash
# 创建备份目录
mkdir -p backup/original
# 复制关键文件到备份目录
cp Core/Inc/e32_hal.h backup/original/
cp Core/Src/e32_hal.c backup/original/
cp Core/Inc/e32_demo.h backup/original/
cp Core/Src/e32_demo.c backup/original/
```
#### 步骤2创建新模块目录
```bash
# 创建Driver_RF433目录结构
mkdir -p Driver_RF433/Inc
mkdir -p Driver_RF433/Src
mkdir -p Driver_RF433/docs
```
### 6.2 第二阶段:模块提取
#### 步骤3提取硬件抽象层
1.`e32_hal.c` 提取硬件相关函数
2. 重命名为 `rf433_hal.c`
3. 修改函数名前缀为 `rf433_hal_`
4. 移除对应用层的依赖
#### 步骤4提取TX功能
1.`e32_demo.c` 提取发送相关函数
2. 创建 `rf433_tx.c`
3. 实现阻塞和异步发送接口
#### 步骤5提取RX功能
1.`usart.c` 提取接收相关函数
2. 创建 `rf433_rx.c`
3. 实现阻塞和非阻塞接收接口
### 6.3 第三阶段:依赖解耦
#### 步骤6处理全局变量依赖
**问题**: 原代码使用全局变量 `huart1``usb_rx_data`
**解决方案**:
1.`rf433_hal.c` 中使用局部变量
2. 通过配置结构体传递硬件资源
3. 使用回调函数处理接收数据
#### 步骤7处理中断向量依赖
**问题**: UART中断回调在 `usart.c`
**解决方案**:
1.`rf433_hal.c` 中定义中断回调函数
2.`stm32f1xx_it.c` 中调用RF433模块的回调
3. 使用函数指针实现回调注册
#### 步骤8处理硬件资源冲突
**问题**: UART1被USB和E32模块共享
**解决方案**:
1.`rf433_hal.c` 中实现UART资源管理
2. 提供UART锁定/解锁接口
3. 使用互斥锁保护共享资源
### 6.4 第四阶段:集成测试
#### 步骤9修改应用层代码
1.`main.c` 中包含 `rf433.h`
2. 替换 `e32_demo_*` 函数调用为 `rf433_*` 函数
3. 修改USB CDC接口使用RF433模块API
#### 步骤10编译测试
```bash
# 编译TX模式
make RF433_MODE=RF433_MODE_TX
# 编译RX模式
make RF433_MODE=RF433_MODE_RX
# 编译完整模式
make RF433_MODE=RF433_MODE_BOTH
```
#### 步骤11功能测试
1. 测试TX模式发送数据到E32模块
2. 测试RX模式接收E32模块数据
3. 测试配置功能:修改模块参数
4. 测试模式切换:在不同工作模式间切换
### 6.5 第五阶段:清理优化
#### 步骤12删除旧代码
```bash
# 删除旧的E32模块文件
rm Core/Inc/e32_hal.h
rm Core/Src/e32_hal.c
rm Core/Inc/e32_demo.h
rm Core/Src/e32_demo.c
```
#### 步骤13更新文档
1. 更新 `AGENTS.md` 中的代码风格指南
2. 创建 `Driver_RF433/docs/rf433_api.md`
3. 创建 `Driver_RF433/docs/rf433_integration.md`
#### 步骤14代码审查
1. 检查代码风格一致性
2. 检查注释完整性
3. 检查错误处理完整性
---
## 七、预编译宏方案
### 7.1 编译模式选择
#### 方案1在头文件中定义
```c
// 在 rf433_config.h 中定义
#define RF433_MODE RF433_MODE_TX // 或 RF433_MODE_RX, RF433_MODE_BOTH
```
#### 方案2在编译命令中定义
```bash
# Keil MDK
CFLAGS += -DRF433_MODE=RF433_MODE_TX
# GCC
gcc -DRF433_MODE=RF433_MODE_TX ...
```
#### 方案3在项目配置文件中定义
```c
// 在 rf433_config.h 中
#ifndef RF433_MODE
#define RF433_MODE RF433_MODE_BOTH
#endif
```
### 7.2 条件编译示例
```c
// rf433.c
#include "rf433.h"
#include "rf433_hal.h"
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
#include "rf433_tx.h"
#endif
#if (RF433_MODE == RF433_MODE_RX) || (RF433_MODE == RF433_MODE_BOTH)
#include "rf433_rx.h"
#endif
rf433_error_t rf433_init(const rf433_config_t *config)
{
// ... 初始化代码 ...
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
rf433_tx_init();
#endif
#if (RF433_MODE == RF433_MODE_RX) || (RF433_MODE == RF433_MODE_BOTH)
rf433_rx_init();
#endif
return RF433_OK;
}
```
### 7.3 资源占用对比
| 编译模式 | Flash占用 | RAM占用 | 功能 |
|---------|----------|---------|------|
| RF433_MODE_TX | ~8KB | ~2KB | 仅发送 |
| RF433_MODE_RX | ~10KB | ~3KB | 仅接收 |
| RF433_MODE_BOTH | ~16KB | ~5KB | 发送+接收 |
### 7.4 编译建议
1. **TX专用设备**: 使用 `RF433_MODE_TX`节省Flash和RAM
2. **RX专用设备**: 使用 `RF433_MODE_RX`节省Flash和RAM
3. **双向通信设备**: 使用 `RF433_MODE_BOTH`,支持完整功能
---
## 八、集成示例
### 8.1 TX模式集成示例
```c
// main.c
#include "rf433.h"
int main(void)
{
rf433_config_t config;
rf433_error_t ret;
uint8_t data[] = "Hello RF433!";
/* 系统初始化 */
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
/* 初始化RF433模块TX模式 */
config.address = 0x0000;
config.channel = 0x17;
config.radio_rate = RF433_RADIO_RATE_2400;
config.uart_rate = RF433_UART_RATE_9600;
config.uart_parity = RF433_UART_8N1;
config.tx_power = RF433_TX_POWER_DBM_30;
config.fec_enable = RF433_ON;
config.specify_target = RF433_OFF;
ret = rf433_init(&config);
if (ret != RF433_OK)
{
Error_Handler();
}
/* 主循环 */
while (1)
{
/* 发送数据 */
ret = rf433_tx_transparent(data, sizeof(data), 1000);
if (ret != RF433_OK)
{
/* 错误处理 */
}
HAL_Delay(1000);
}
}
```
### 8.2 RX模式集成示例
```c
// main.c
#include "rf433.h"
/* 接收回调函数 */
void rf433_rx_callback(const rf433_packet_t *packet, void *user_data)
{
/* 处理接收到的数据 */
// ...
}
int main(void)
{
rf433_config_t config;
rf433_error_t ret;
/* 系统初始化 */
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
/* 初始化RF433模块RX模式 */
config.address = 0x0000;
config.channel = 0x17;
config.radio_rate = RF433_RADIO_RATE_2400;
config.uart_rate = RF433_UART_RATE_9600;
config.uart_parity = RF433_UART_8N1;
config.tx_power = RF433_TX_POWER_DBM_30;
config.fec_enable = RF433_ON;
config.specify_target = RF433_OFF;
ret = rf433_init(&config);
if (ret != RF433_OK)
{
Error_Handler();
}
/* 注册接收回调 */
rf433_rx_register_callback(rf433_rx_callback, NULL);
/* 启动接收 */
ret = rf433_rx_start();
if (ret != RF433_OK)
{
Error_Handler();
}
/* 主循环 */
while (1)
{
/* 其他任务 */
HAL_Delay(100);
}
}
```
### 8.3 双向通信集成示例
```c
// main.c
#include "rf433.h"
/* 接收回调函数 */
void rf433_rx_callback(const rf433_packet_t *packet, void *user_data)
{
/* 处理接收到的数据 */
// ...
/* 回复数据 */
rf433_tx_transparent(packet->data, packet->length, 1000);
}
int main(void)
{
rf433_config_t config;
rf433_error_t ret;
uint8_t data[] = "Hello RF433!";
/* 系统初始化 */
HAL_Init();
SystemClock_Config();
MX_GPIO_Init();
MX_USART1_UART_Init();
/* 初始化RF433模块双向模式 */
config.address = 0x0000;
config.channel = 0x17;
config.radio_rate = RF433_RADIO_RATE_2400;
config.uart_rate = RF433_UART_RATE_9600;
config.uart_parity = RF433_UART_8N1;
config.tx_power = RF433_TX_POWER_DBM_30;
config.fec_enable = RF433_ON;
config.specify_target = RF433_OFF;
ret = rf433_init(&config);
if (ret != RF433_OK)
{
Error_Handler();
}
/* 注册接收回调 */
rf433_rx_register_callback(rf433_rx_callback, NULL);
/* 启动接收 */
ret = rf433_rx_start();
if (ret != RF433_OK)
{
Error_Handler();
}
/* 主循环 */
while (1)
{
/* 定期发送数据 */
ret = rf433_tx_transparent(data, sizeof(data), 1000);
if (ret != RF433_OK)
{
/* 错误处理 */
}
HAL_Delay(1000);
}
}
```
---
## 九、总结与建议
### 9.1 方案优势
1. **模块化设计**: 清晰的模块边界,易于维护和扩展
2. **资源优化**: 通过预编译宏减少不必要的代码编译
3. **接口统一**: 提供统一的API接口简化应用层调用
4. **可移植性**: 硬件抽象层设计,易于移植到其他平台
5. **可测试性**: 模块独立,便于单元测试
### 9.2 实施建议
1. **分阶段实施**: 按照解耦操作步骤逐步实施,降低风险
2. **充分测试**: 每个阶段完成后进行充分测试
3. **保留备份**: 保留原始代码备份,便于回滚
4. **文档更新**: 及时更新相关文档,保持文档与代码同步
5. **代码审查**: 完成后进行代码审查,确保代码质量
### 9.3 后续优化方向
1. **异步支持**: 完善异步发送和接收功能
2. **错误恢复**: 增加错误检测和自动恢复机制
3. **性能优化**: 优化FIFO和中断处理性能
4. **协议扩展**: 支持更多通信协议和模式
5. **调试支持**: 增加调试日志和统计功能
---
## 附录
### A. 参考资料
1. E32-433T30S 数据手册
2. STM32F103C8T6 参考手册
3. STM32 HAL 库文档
4. 项目 AGENTS.md 文档
### B. 术语表
| 术语 | 说明 |
|-----|------|
| E32 | E32-433T30S LoRa无线模块 |
| HAL | Hardware Abstraction Layer硬件抽象层 |
| FIFO | First In First Out先进先出队列 |
| WOR | Wake On Radio无线唤醒 |
| FEC | Forward Error Correction前向纠错 |
| CDC | Communications Device Class通信设备类 |
### C. 版本历史
| 版本 | 日期 | 作者 | 说明 |
|-----|------|------|------|
| v1.0 | 2026-03-24 | 系统架构师 | 初始版本 |
---
**文档结束**