1. 项目背景与需求分析
作为一名电子爱好者,我最近遇到了一个实际问题:家中的音响红外遥控器因电池漏液导致电路板腐蚀。虽然目前还能勉强使用,但随时可能彻底报废。考虑到原厂遥控器价格昂贵且难以购买,我决定利用手头的单片机开发板重新实现一个功能相同的红外遥控器。
这个项目有几个技术难点需要解决:
- 原厂遥控器采用非标准编码和载波频率,无法直接使用通用红外协议
- 需要精确捕捉和重现原始遥控信号波形
- 要在低成本硬件平台上实现可靠的红外发射功能
2. 硬件准备与信号分析
2.1 所需材料清单
- 原装遥控器(作为信号源)
- 数字示波器(带宽至少20MHz)
- 逻辑分析仪(可选,用于长时间信号捕获)
- 红外接收二极管(如VS1838B)
- 单片机开发板(我选用STM32F103C8T6最小系统板)
- 红外发射LED(940nm波长)
- 面包板和杜邦线若干
- 焊接工具和万用表
2.2 信号捕获过程
首先需要从原遥控器提取红外信号特征。具体操作步骤:
- 拆解遥控器,找到红外LED焊点
- 用细导线将LED正负极引出,保持原电路连接
- 将示波器探头接在LED两端(注意极性)
- 按下"音量+"键,捕获完整波形
从波形分析可以看出几个关键特征:
- 载波频率:37.9kHz(非标准的38kHz)
- 编码格式:脉宽调制,引导码+32位数据
- 信号周期:约120ms
2.3 信号参数测量
使用示波器的测量功能获取精确参数:
| 参数 | 测量值 | 说明 |
|---|---|---|
| 载波频率 | 37.9kHz | 占空比约30% |
| 引导码高电平 | 4.5ms | 起始同步信号 |
| 引导码低电平 | 4.2ms | |
| 数据位高电平 | 560μs | 固定长度的脉冲 |
| 数据位0 | 1.12ms | 低电平持续时间 |
| 数据位1 | 2.25ms | 低电平持续时间 |
| 结束码 | 560μs | 最后的高电平脉冲 |
3. 单片机程序设计
3.1 开发环境配置
使用STM32CubeIDE进行开发,配置步骤如下:
- 新建STM32F103C8T6工程
- 配置定时器TIM2用于38kHz PWM生成
- 配置定时器TIM3用于精确延时控制
- 配置一个GPIO引脚控制红外LED开关
3.2 关键代码实现
c复制#define IR_LED_PIN GPIO_PIN_13
#define IR_LED_PORT GPIOC
// 定时器初始化(省略部分标准初始化代码)
void TIM2_Init(void) {
htim2.Instance = TIM2;
htim2.Init.Prescaler = 19; // 72MHz/(19+1)=3.6MHz
htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
htim2.Init.Period = 94; // 3.6MHz/(94+1)=37.9kHz
htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
HAL_TIM_PWM_Init(&htim2);
}
// 发送一个红外信号位
void send_bit(uint8_t bit_val) {
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1); // 开启载波
HAL_Delay_US(560); // 固定高电平
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1); // 关闭载波
if(bit_val) {
HAL_Delay_US(2250); // 位1的低电平时间
} else {
HAL_Delay_US(1120); // 位0的低电平时间
}
}
// 发送完整红外信号
void send_ir_code(uint32_t code) {
// 发送引导码
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
HAL_Delay_US(4500);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
HAL_Delay_US(4200);
// 发送32位数据
for(int i=0; i<32; i++) {
send_bit((code >> (31-i)) & 0x01);
}
// 发送结束码
HAL_TIM_PWM_Start(&htim2, TIM_CHANNEL_1);
HAL_Delay_US(560);
HAL_TIM_PWM_Stop(&htim2, TIM_CHANNEL_1);
}
3.3 信号解码与验证
为确保发送的信号正确,我开发了一个简单的解码程序:
c复制void decode_ir_signal(void) {
uint32_t code = 0;
// 等待引导码(省略具体实现)
// 接收32位数据
for(int i=0; i<32; i++) {
uint32_t low_time = measure_low_time();
if(low_time > 1500) { // 阈值设为1.5ms
code |= (1 << (31-i));
}
}
printf("Received code: 0x%08X\n", code);
}
通过这个解码器,可以验证发送的信号是否与原遥控器一致。
4. 硬件连接与测试
4.1 电路连接示意图
code复制STM32F103C8T6 红外LED电路
+------------+ +-----------+
| PC13 |------>| 220Ω电阻 |
| | | |
| GND |------>| 红外LED |
+------------+ +-----------+
4.2 测试步骤
- 将程序烧录到单片机
- 连接红外LED电路
- 用手机摄像头观察LED(红外光在摄像头下可见)
- 使用原装遥控器和自制遥控器分别操作音响
- 用逻辑分析仪对比两种信号波形
4.3 常见问题排查
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| 无任何反应 | LED极性接反 | 检查LED正负极连接 |
| 电阻值过大 | 减小限流电阻(最低100Ω) | |
| 响应不稳定 | 载波频率偏差 | 调整定时器分频和周期值 |
| 电源供电不足 | 增加滤波电容(100μF) | |
| 部分按键无效 | 数据编码错误 | 重新捕获并验证各按键编码 |
| 有效距离短 | LED驱动电流不足 | 使用三极管放大驱动信号 |
5. 优化与扩展
5.1 硬件优化
- 增加三极管驱动电路(如8050 NPN)提高发射功率
- 添加多个红外LED扩大发射角度
- 使用18650锂电池供电,增加移动性
5.2 软件改进
- 实现学习功能,自动记录各按键编码
- 添加省电模式,空闲时关闭红外LED
- 支持多设备控制,存储多组编码
5.3 外壳设计与制作
使用3D打印制作符合人体工程学的外壳,参考原遥控器布局设计按键位置。
6. 项目总结
通过这个项目,我掌握了以下关键技术:
- 非标准红外协议的分析方法
- 精确波形捕获和重现技巧
- STM32定时器的高级应用
- 红外信号编解码原理
实际测试表明,自制遥控器在5米范围内响应可靠,所有功能与原装遥控器完全一致。总成本不到20元,远低于原厂配件价格。
这个方案可以推广到其他非标准红外设备的遥控器替代场景。对于更复杂的设备,可以考虑加入滚动码解码功能。
