1. 项目概述与设计背景
红外遥控技术作为最成熟的短距离无线控制方案之一,在家电控制领域已有超过30年的应用历史。传统红外遥控系统通常采用专用解码芯片(如PT2262/PT2272)实现简单的点对点控制,这种方案虽然成本低廉但功能单一,无法满足现代智能控制需求。
本项目基于STM32F103C8T6单片机构建了一套智能化红外控制系统,其创新点在于:
- 采用软件解码替代传统硬件解码方案,通过定时器捕获功能实现NEC协议解析
- 集成SIM900A GSM模块实现双向通信能力
- 通过HTTP协议对接OneNet物联网平台
- 本地OLED显示与远程短信通知双通道反馈
1.1 核心硬件选型解析
1.1.1 主控芯片:STM32F103C8T6
选择这款ARM Cortex-M3内核单片机主要基于三点考量:
- 72MHz主频和20KB RAM足以处理红外解码和网络通信任务
- 内置5个USART接口可同时连接OLED、SIM900A和调试终端
- 丰富的定时器资源(TIM4用于红外解码时基)
1.1.2 红外接收模块:HX1838
- 载波频率:38kHz(兼容绝大多数家电遥控器)
- 接收角度:±45度
- 工作电压:2.7-5.5V(与STM32电平兼容)
- 典型应用电路只需增加一个10μF去耦电容
1.1.3 通信模块:SIM900A
- 支持GSM/GPRS Class 10
- 内置TCP/IP协议栈
- 工作频段:850/900/1800/1900MHz(需根据当地运营商选择)
- 峰值电流:2A(需独立电源设计)
2. 红外解码系统实现
2.1 NEC协议深度解析
NEC协议采用PPM(脉冲位置调制)编码,其典型帧结构包含:
- 9ms引导码(高电平)
- 4.5ms空格(低电平)
- 8位用户码+8位用户反码
- 8位按键码+8位按键反码
- 560μs结束脉冲
注意:实际解码时需要容忍±20%的时间误差,不同厂商的遥控器可能存在时序差异
2.2 硬件中断配置
c复制// 红外接收头GPIO配置(PA8)
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; // 上拉输入
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &GPIO_InitStructure);
// 外部中断配置
EXTI_InitTypeDef EXTI_InitStructure;
EXTI_InitStructure.EXTI_Line = EXTI_Line8;
EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling; // 下降沿触发
EXTI_InitStructure.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_InitStructure);
2.3 高精度时序捕获
使用TIM4定时器实现μs级时间测量:
c复制void TIM4_IRQHandler(void) {
if(TIM_GetITStatus(TIM4, TIM_IT_Update) != RESET) {
ir_time++; // 溢出计数器
TIM_ClearITPendingBit(TIM4, TIM_IT_Update);
}
}
uint32_t GetPulseWidth(void) {
uint32_t time = 0;
time = ir_time * 65536 + TIM_GetCounter(TIM4); // 计算总时间(μs)
TIM4->CNT = 0; // 计数器清零
ir_time = 0;
return time;
}
3. 云端通信实现
3.1 OneNet平台接入流程
- 创建产品:选择HTTP协议接入方式
- 添加设备:填写设备IMEI(SIM900A的IMEI号)
- 定义数据流:user_code(用户码)、key_code(按键码)
- 设计可视化界面:添加折线图、数字显示等控件
3.2 HTTP报文构造
c复制// JSON数据体示例
char json_buf[128];
sprintf(json_buf,
"{\"datastreams\":["
"{\"id\":\"user_code\",\"datapoints\":[{\"value\":\"%02X\"}]},"
"{\"id\":\"key_code\",\"datapoints\":[{\"value\":\"%02X\"}]}"
"]}",
user_code, key_code);
// 完整HTTP请求
char http_buf[256];
sprintf(http_buf,
"POST /devices/%s/datapoints HTTP/1.1\r\n"
"api-key: %s\r\n"
"Host: api.heclouds.com\r\n"
"Content-Length: %d\r\n"
"\r\n"
"%s",
DEVICE_ID, API_KEY, strlen(json_buf), json_buf);
3.3 SIM900A AT指令流程
bash复制AT+CPIN? # 检查SIM卡状态
AT+CSQ # 检查信号强度(应大于10)
AT+CGATT=1 # 附着GPRS网络
AT+CIPSTART="TCP","api.heclouds.com",80 # 建立TCP连接
AT+CIPSEND=%d # 发送数据长度
> %s # 输入HTTP报文
4. 系统调试与优化
4.1 常见问题排查表
| 现象 | 可能原因 | 解决方案 |
|---|---|---|
| 无法解码红外信号 | 1. 接收头方向错误 2. 供电电压不足 3. 载波频率不匹配 |
1. 调整接收角度 2. 检查3.3V电源 3. 更换38kHz接收头 |
| SIM900A无法联网 | 1. APN设置错误 2. 运营商频段不支持 3. 天线接触不良 |
1. 执行AT+CSTT="CMNET" 2. 检查模块频段 3. 更换外置天线 |
| 数据上传失败 | 1. 设备ID/API_KEY错误 2. JSON格式错误 3. 网络延迟 |
1. 核对平台配置 2. 使用JSON校验工具 3. 增加重试机制 |
4.2 功耗优化方案
- 红外接收模块:添加MOSFET开关电路,空闲时断电
- SIM900A模块:使用AT+CFUN=0命令进入睡眠模式
- STM32主控:配置停机模式(Stop Mode),通过红外中断唤醒
5. 进阶功能扩展
5.1 多协议支持改造
通过修改解码算法可兼容RC5、Sony SIRC等协议:
c复制enum Protocol {
NEC,
RC5,
SONY
};
void DecodeIR(Protocol proto) {
switch(proto) {
case NEC:
// NEC解码逻辑
break;
case RC5:
// 曼彻斯特解码
break;
case SONY:
// 脉冲宽度解码
break;
}
}
5.2 本地存储功能
添加SPI Flash存储历史记录:
c复制#define PAGE_SIZE 256
void SaveToFlash(uint8_t user, uint8_t key) {
static uint32_t addr = 0;
uint8_t buf[2] = {user, key};
SPI_Flash_Write(buf, addr, 2);
addr = (addr + 2) % (FLASH_SIZE - PAGE_SIZE);
}
实际开发中发现,红外接收头对环境光敏感,在强光环境下误码率会显著升高。解决方法是在接收窗口加装850nm带通滤光片,可将信噪比提升15dB以上。另外,SIM900A模块在发送HTTP数据时,建议每次发送后延迟300ms再关闭连接,避免出现TCP粘包问题。