保姆级教程:用STM32F103C8T6的PWM驱动红外模块,实现格力空调万能遥控器

张开发
2026/4/14 17:53:20 15 分钟阅读

分享文章

保姆级教程:用STM32F103C8T6的PWM驱动红外模块,实现格力空调万能遥控器
从零构建格力空调万能遥控器基于STM32F103C8T6的PWM红外协议全解析在智能家居DIY领域红外遥控器改造一直是最具实用价值的入门项目之一。本文将带您完整实现一个能精准控制格力空调的STM32红外发射器使用最常见的STM32F103C8T6开发板蓝桥杯竞赛和正点原子开发板标配型号和廉价的红外发射模块。不同于简单的代码复制我们会深入解析格力空调特有的起始码35位连接码32位连接码帧结构并通过PWM精确生成38kHz载波与协议时序。1. 硬件准备与电路连接1.1 所需材料清单核心控制器STM32F103C8T6最小系统板市场价约15-20元红外发射模块38kHz红外发射管建议选用TSAL6200辅助元件100Ω限流电阻NPN三极管如S8050面包板与杜邦线1.2 电路连接示意图STM32F103C8T6 红外发射电路 PA1 (PWM输出) ────┬─── 100Ω电阻 ────┤ │ │ └─── NPN三极管基极 发射极接地 集电极接红外管负极 红外管正极接3.3V注意红外发射管有极性区分长脚为正极。实际连接时建议用万用表二极管档确认。1.3 引脚配置原理STM32的定时器TIM2通道2PA1引脚将产生38kHz PWM载波。当需要发送红外信号时我们通过控制PWM的占空比来模拟协议要求的各种电平宽度载波周期26.3μs (38kHz倒数)有效信号PWM占空比50%13.15μs高13.15μs低静默状态PWM输出保持低电平2. 格力空调红外协议深度解析2.1 帧结构示意图格力空调采用独特的双数据段结构[起始码S] [35位数据] [连接码C] [32位数据] [连接码C]每个部分的时序要求如下表所示信号类型发射端电平宽度μs接收端电平宽度μs起始码S9000低 4500高4500高 9000低数据位0620低 540高540高 620低数据位1620低 1620高1620高 620低连接码C620低 20000高20000高 620低关键细节实际发射时所有电平极性需要反转即发射端的低电平对应接收端的高电平2.2 数据格式详解格力协议采用7字节56位数据结构但实际只使用前35位和后32位。以下是一个典型的功能控制位分布typedef struct { // 第一段35位数据 uint8_t power : 1; // 开关机标志 uint8_t mode : 3; // 模式选择(自动/制冷/除湿/送风/制热) uint8_t fan : 2; // 风速档位 uint8_t temp : 4; // 温度设置(16-30℃) // 第二段32位数据 uint8_t swing_v : 4; // 垂直扫风 uint8_t turbo : 1; // 强力模式 uint8_t econo : 1; // 节能模式 uint8_t light : 1; // 显示屏开关 } GreeProtocol;2.3 校验码计算方法格力空调采用4位校验和计算规则如下取前6个字节的低4位相加加上固定值0x0C对结果取低4位作为校验码具体实现代码uint8_t calculate_checksum(GreeProtocol *proto) { uint8_t sum 0x0C; // 基础值 uint8_t *data (uint8_t*)proto; for(int i0; i6; i) { sum (data[i] 0x0F); // 累加每个字节的低4位 } return sum 0x0F; // 取最后4位 }3. PWM驱动实现详解3.1 定时器配置步骤以下是STM32标准外设库的配置代码void PWM_Init(void) { GPIO_InitTypeDef GPIO_InitStruct; TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct; TIM_OCInitTypeDef TIM_OCStruct; // 1. 时钟使能 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE); // 2. GPIO配置复用推挽输出 GPIO_InitStruct.GPIO_Pin GPIO_Pin_1; GPIO_InitStruct.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStruct.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStruct); // 3. 时基单元配置38kHz载波 TIM_TimeBaseStruct.TIM_Prescaler 72 - 1; // 72MHz/72 1MHz TIM_TimeBaseStruct.TIM_Period 26 - 1; // 1MHz/26 ≈ 38.46kHz TIM_TimeBaseStruct.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseInit(TIM2, TIM_TimeBaseStruct); // 4. 输出比较配置PWM模式1 TIM_OCStruct.TIM_OCMode TIM_OCMode_PWM1; TIM_OCStruct.TIM_OutputState TIM_OutputState_Enable; TIM_OCStruct.TIM_Pulse 13; // 50%占空比 TIM_OCStruct.TIM_OCPolarity TIM_OCPolarity_High; TIM_OC2Init(TIM2, TIM_OCStruct); // 5. 启动定时器 TIM_Cmd(TIM2, ENABLE); }3.2 信号发送核心算法通过动态调整PWM占空比实现协议要求的各种电平#define BIT_MARK 620 #define ZERO_SPACE 540 #define ONE_SPACE 1620 void send_bit(uint8_t bit_val) { // 发送起始位固定620μs低电平 TIM_SetCompare2(TIM2, 0); delay_us(BIT_MARK); // 发送数据位高电平持续时间不同 TIM_SetCompare2(TIM2, 13); // 50%占空比 delay_us(bit_val ? ONE_SPACE : ZERO_SPACE); } void send_frame(uint8_t *data, uint16_t bit_count) { // 发送起始码 TIM_SetCompare2(TIM2, 0); delay_us(9000); TIM_SetCompare2(TIM2, 13); delay_us(4500); // 逐位发送数据 for(int i0; ibit_count; i) { uint8_t byte_pos i / 8; uint8_t bit_pos i % 8; send_bit((data[byte_pos] bit_pos) 0x01); } // 发送连接码 TIM_SetCompare2(TIM2, 0); delay_us(620); TIM_SetCompare2(TIM2, 13); delay_us(20000); }4. 完整控制流程与调试技巧4.1 典型控制序列初始化硬件PWM、GPIO、定时器构建协议帧GreeProtocol cmd; cmd.power 1; // 开机 cmd.mode 2; // 制冷模式 cmd.temp 25 - 16; // 25℃偏移量16 cmd.fan 2; // 中等风速 cmd.checksum calculate_checksum(cmd);发送完整帧send_frame((uint8_t*)cmd, 35); // 第一段35位 send_connect_code(); send_frame((uint8_t*)cmd 4, 32); // 第二段32位 send_connect_code();4.2 常见问题排查表现象可能原因解决方案空调完全无反应红外发射管极性接反检查LED正负极连接偶尔能触发载波频率偏差过大用示波器校准38kHz频率按键响应不稳定时序精度不足改用硬件定时器延时校验失败结构体字节对齐问题添加__packed关键字修饰4.3 进阶优化建议载波增强在红外管回路串联多个发射管不超过3个提高发射功率低功耗设计在两次发送之间将GPIO设为模拟输入模式减少功耗协议扩展通过分析不同型号格力遥控器的数据包添加特殊功能支持实际测试中发现格力空调对时序的要求相对宽松但连接码的20ms静默期必须准确。建议用逻辑分析仪捕获原始遥控器信号作为参考特别是检查第二段数据后的连接码是否完整发送。

更多文章