1. 项目背景与核心价值
十年前我第一次拆解老式电视机遥控器时,就被那小小的红外发射管迷住了——按下按键的瞬间,肉眼不可见的红外光脉冲就能精准传达指令。如今虽然智能家居普及,但红外遥控作为最成熟的近场控制技术,依然是学习嵌入式开发和无线通信原理的绝佳切入点。
这个DIY项目的核心价值在于:
- 理解红外通信的物理层编码原理(38kHz载波、NEC协议等)
- 掌握单片机定时器中断与GPIO控制技巧
- 构建完整的信号发射系统(从编码生成到红外发射)
- 获得可实际使用的自制遥控器(可兼容控制电视、空调等设备)
我选择基于STM32F103C8T6(蓝色药丸开发板)实现,因其兼具性价比(10元左右)和丰富外设(TIM定时器、PWM输出等)。实测可稳定控制5米内的格力空调,发射角度超过60度。
2. 红外通信原理深度解析
2.1 物理层信号特征
红外遥控采用波长940nm的红外LED,通过38kHz载波调制(占空比1/3)降低功耗。下图展示NEC协议典型波形:
code复制引导码 9ms高电平+4.5ms低电平
数据码 0: 560μs高+560μs低
1: 560μs高+1.68ms低
关键点:接收端TSOP4838等红外接收头会主动滤除38kHz载波,输出解调后的数字信号
2.2 NEC协议帧结构
完整的一帧包含:
- 引导码(同步信号)
- 16位设备地址(可区分不同品牌)
- 8位命令码+8位反码(校验用)
- 结束位(560μs高电平)
例如格力空调开机的原始码值为:
0x0000 0x00FF 0xA25D(地址+命令+反码)
3. 硬件设计与元件选型
3.1 核心元件清单
| 元件 | 型号 | 参数 | 单价 |
|---|---|---|---|
| MCU | STM32F103C8T6 | 72MHz Cortex-M3 | ¥10 |
| 红外LED | TSAL6200 | 940nm, 100mA | ¥0.5 |
| 三极管 | S8050 | Ic=500mA | ¥0.2 |
| 电阻 | 1/4W碳膜 | 100Ω, 1kΩ | ¥0.1 |
3.2 电路设计要点
- 驱动电路:采用三极管扩流方案(STM32 GPIO最大输出20mA,而红外LED需80-100mA)
c复制PA1(TIM2_CH2) → 1kΩ → S8050基极 S8050集电极 → 100Ω → LED阳极 LED阴极 → GND - 电源滤波:在MCU和红外LED供电端并联100μF电解电容+0.1μF瓷片电容
实测教训:未加滤波电容时,发射会导致MCU复位,因大电流脉冲引发电压跌落
4. 软件实现关键代码
4.1 定时器PWM配置
c复制// TIM2_CH2输出38kHz PWM(72MHz/(1+18)=3.79MHz, 3.79MHz/100=37.9kHz)
void PWM_Init(void) {
GPIOA->CRL &= 0xFFFFFF0F; // PA1复用推挽输出
GPIOA->CRL |= 0x000000B0;
TIM2->ARR = 99; // 自动重装载值
TIM2->CCR2 = 33; // 占空比33%
TIM2->PSC = 18; // 预分频值
TIM2->CCMR1 |= 0x0060; // PWM模式1
TIM2->CCER |= 0x0010; // OC2输出使能
TIM2->CR1 = 0x01; // 启动定时器
}
4.2 NEC协议编码函数
c复制void IR_SendNEC(uint16_t addr, uint8_t cmd) {
// 发送9ms引导码
PWM_Enable();
delay_ms(9);
PWM_Disable();
delay_ms(4.5);
// 发送地址和命令(LSB first)
sendByte(addr >> 8); // 地址高字节
sendByte(addr); // 地址低字节
sendByte(cmd); // 命令码
sendByte(~cmd); // 命令反码
// 结束脉冲
PWM_Enable();
delay_us(560);
PWM_Disable();
}
void sendByte(uint8_t data) {
for(uint8_t i=0; i<8; i++) {
PWM_Enable();
delay_us(560);
PWM_Disable();
if(data & 0x01) delay_us(1680);
else delay_us(560);
data >>= 1;
}
}
5. 信号抓取与调试技巧
5.1 逻辑分析仪捕获
使用Saleae Logic配合红外接收头捕获信号时注意:
- 采样率至少2MHz(确保捕获560μs窄脉冲)
- 添加自定义协议解码器(NEC格式模板)
- 检查引导码时长误差(应在±10%以内)
5.2 常见问题排查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 设备无响应 | LED极性接反 | 用手机摄像头检查红外光(可见紫光) |
| 控制距离短 | 驱动电流不足 | 减小限流电阻(最低至68Ω) |
| 按键连发 | 未加按键消抖 | 增加20ms延时或硬件RC滤波 |
| 误触发 | 环境光干扰 | 给接收头加遮光罩 |
6. 进阶优化方向
- 学习模式:通过VS1838B接收头录制原始红外信号,存储到Flash实现万能遥控
c复制uint32_t rawData[200]; // 存储高低电平持续时间 while(IR_IN_PIN) { rawData[i++] = get_time_us(); } - 低功耗设计:
- 休眠模式下电流可降至15μA(STM32 STOP模式)
- 采用MOSFET(如SI2302)替代三极管降低导通损耗
- 外壳3D打印:使用FreeCAD设计符合人体工学的外壳,预留电池仓和按键孔位
这个项目最让我惊喜的是,用成本不到20元的自制遥控器,成功替代了原厂售价120元的空调遥控。当按下自制按键听到"滴"的响应声时,那种成就感是买现成产品无法比拟的。
