60 KiB
60 KiB
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 存在的问题
- 耦合度高: E32模块代码分散在多个文件中,与USB、UART等模块紧密耦合
- 可维护性差: TX/RX模式代码混杂,难以独立测试和维护
- 资源浪费: 未使用的TX/RX代码仍被编译,占用Flash空间
- 扩展性差: 缺乏清晰的模块边界,难以移植到其他项目
二、已识别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 工作模式枚举
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 寄存器配置结构体
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 数据包结构体
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()函数 - 流程:
- 调用
e32_hal_uart_tx()发送数据 - 通过UART1发送到E32模块
- E32模块在透明传输模式下自动发送
- 调用
2.4.2 当前RX实现
- 位置:
usart.c中的HAL_UART_RxCpltCallback()回调 - 流程:
- UART1中断接收数据
- 数据写入FIFO缓冲区
- 通过USB CDC转发到PC
- 使用超时机制判断数据包结束
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)
/**
* @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)
/**
* @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)
/**
* @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)
/**
* @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 模块初始化示例
/**
* @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模式实现示例
/**
* @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模式实现示例
/**
* @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 硬件抽象层实现示例
/**
* @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:备份现有代码
# 创建备份目录
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:创建新模块目录
# 创建Driver_RF433目录结构
mkdir -p Driver_RF433/Inc
mkdir -p Driver_RF433/Src
mkdir -p Driver_RF433/docs
6.2 第二阶段:模块提取
步骤3:提取硬件抽象层
- 从
e32_hal.c提取硬件相关函数 - 重命名为
rf433_hal.c - 修改函数名前缀为
rf433_hal_ - 移除对应用层的依赖
步骤4:提取TX功能
- 从
e32_demo.c提取发送相关函数 - 创建
rf433_tx.c - 实现阻塞和异步发送接口
步骤5:提取RX功能
- 从
usart.c提取接收相关函数 - 创建
rf433_rx.c - 实现阻塞和非阻塞接收接口
6.3 第三阶段:依赖解耦
步骤6:处理全局变量依赖
问题: 原代码使用全局变量 huart1、usb_rx_data 等
解决方案:
- 在
rf433_hal.c中使用局部变量 - 通过配置结构体传递硬件资源
- 使用回调函数处理接收数据
步骤7:处理中断向量依赖
问题: UART中断回调在 usart.c 中
解决方案:
- 在
rf433_hal.c中定义中断回调函数 - 在
stm32f1xx_it.c中调用RF433模块的回调 - 使用函数指针实现回调注册
步骤8:处理硬件资源冲突
问题: UART1被USB和E32模块共享
解决方案:
- 在
rf433_hal.c中实现UART资源管理 - 提供UART锁定/解锁接口
- 使用互斥锁保护共享资源
6.4 第四阶段:集成测试
步骤9:修改应用层代码
- 在
main.c中包含rf433.h - 替换
e32_demo_*函数调用为rf433_*函数 - 修改USB CDC接口,使用RF433模块API
步骤10:编译测试
# 编译TX模式
make RF433_MODE=RF433_MODE_TX
# 编译RX模式
make RF433_MODE=RF433_MODE_RX
# 编译完整模式
make RF433_MODE=RF433_MODE_BOTH
步骤11:功能测试
- 测试TX模式:发送数据到E32模块
- 测试RX模式:接收E32模块数据
- 测试配置功能:修改模块参数
- 测试模式切换:在不同工作模式间切换
6.5 第五阶段:清理优化
步骤12:删除旧代码
# 删除旧的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:更新文档
- 更新
AGENTS.md中的代码风格指南 - 创建
Driver_RF433/docs/rf433_api.md - 创建
Driver_RF433/docs/rf433_integration.md
步骤14:代码审查
- 检查代码风格一致性
- 检查注释完整性
- 检查错误处理完整性
七、预编译宏方案
7.1 编译模式选择
方案1:在头文件中定义
// 在 rf433_config.h 中定义
#define RF433_MODE RF433_MODE_TX // 或 RF433_MODE_RX, RF433_MODE_BOTH
方案2:在编译命令中定义
# Keil MDK
CFLAGS += -DRF433_MODE=RF433_MODE_TX
# GCC
gcc -DRF433_MODE=RF433_MODE_TX ...
方案3:在项目配置文件中定义
// 在 rf433_config.h 中
#ifndef RF433_MODE
#define RF433_MODE RF433_MODE_BOTH
#endif
7.2 条件编译示例
// 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 编译建议
- TX专用设备: 使用
RF433_MODE_TX,节省Flash和RAM - RX专用设备: 使用
RF433_MODE_RX,节省Flash和RAM - 双向通信设备: 使用
RF433_MODE_BOTH,支持完整功能
八、集成示例
8.1 TX模式集成示例
// 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模式集成示例
// 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 双向通信集成示例
// 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 方案优势
- 模块化设计: 清晰的模块边界,易于维护和扩展
- 资源优化: 通过预编译宏减少不必要的代码编译
- 接口统一: 提供统一的API接口,简化应用层调用
- 可移植性: 硬件抽象层设计,易于移植到其他平台
- 可测试性: 模块独立,便于单元测试
9.2 实施建议
- 分阶段实施: 按照解耦操作步骤逐步实施,降低风险
- 充分测试: 每个阶段完成后进行充分测试
- 保留备份: 保留原始代码备份,便于回滚
- 文档更新: 及时更新相关文档,保持文档与代码同步
- 代码审查: 完成后进行代码审查,确保代码质量
9.3 后续优化方向
- 异步支持: 完善异步发送和接收功能
- 错误恢复: 增加错误检测和自动恢复机制
- 性能优化: 优化FIFO和中断处理性能
- 协议扩展: 支持更多通信协议和模式
- 调试支持: 增加调试日志和统计功能
附录
A. 参考资料
- E32-433T30S 数据手册
- STM32F103C8T6 参考手册
- STM32 HAL 库文档
- 项目 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 | 系统架构师 | 初始版本 |
文档结束