保姆级教程:用STM32的定时器输入捕获功能,手把手教你解码任意红外遥控器
STM32定时器输入捕获实战从零解码未知协议红外遥控信号红外遥控技术在家电控制领域已有数十年历史但面对市面上五花八门的遥控协议开发者常常陷入协议适配的泥潭。本文将带你突破协议限制利用STM32的定时器输入捕获功能实现一套协议无关的红外信号解码方案。1. 红外信号解码的核心思路传统红外解码方案通常需要预先知道目标设备的通信协议如NEC、RC5等但现实情况是小众家电厂商常使用自定义协议同一品牌不同型号可能采用不同协议协议文档往往难以获取我们的解决方案是时间特征分析法——不关心协议的具体定义只记录信号的高低电平持续时间。这种方法的优势在于通用性强可解码任意红外遥控器实现简单无需复杂的协议解析逻辑扩展性好采集的数据可直接用于信号重放关键硬件需求常见红外接收头如VS1838BSTM32系列单片机本文以STM32F103为例逻辑分析仪可选用于调试2. 定时器输入捕获的配置艺术2.1 定时器基础配置输入捕获功能的本质是利用定时器记录信号边沿发生的精确时刻。以下是TIM2的基本配置以STM32CubeIDE为例TIM_HandleTypeDef htim2; TIM_IC_InitTypeDef sConfigIC; htim2.Instance TIM2; htim2.Init.Prescaler 71; // 72MHz/(711) 1MHz → 1μs分辨率 htim2.Init.CounterMode TIM_COUNTERMODE_UP; htim2.Init.Period 0xFFFF; // 16位最大值 htim2.Init.ClockDivision TIM_CLOCKDIVISION_DIV1; HAL_TIM_IC_Init(htim2); sConfigIC.ICPolarity TIM_INPUTCHANNELPOLARITY_RISING; // 初始捕获上升沿 sConfigIC.ICSelection TIM_ICSELECTION_DIRECTTI; sConfigIC.ICPrescaler TIM_ICPSC_DIV1; // 不分频 sConfigIC.ICFilter 0x0; // 不滤波 HAL_TIM_IC_ConfigChannel(htim2, sConfigIC, TIM_CHANNEL_1);2.2 边沿触发与时间计算红外信号通常由一系列脉冲组成我们需要交替捕获上升沿和下降沿void HAL_TIM_IC_CaptureCallback(TIM_HandleTypeDef *htim) { static uint32_t prevCapture 0; uint32_t currCapture HAL_TIM_ReadCapturedValue(htim, TIM_CHANNEL_1); if(htim-Channel HAL_TIM_ACTIVE_CHANNEL_1) { uint32_t pulseWidth currCapture - prevCapture; // 切换捕获极性 if(__HAL_TIM_GET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1) TIM_INPUTCHANNELPOLARITY_RISING) { __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_FALLING); // 记录高电平持续时间 irData.highPulse pulseWidth; } else { __HAL_TIM_SET_CAPTUREPOLARITY(htim, TIM_CHANNEL_1, TIM_INPUTCHANNELPOLARITY_RISING); // 记录低电平持续时间 irData.lowPulse pulseWidth; processPulsePair(irData.highPulse, irData.lowPulse); } prevCapture currCapture; } }2.3 抗干扰处理策略实际环境中可能遇到各种干扰需要添加以下保护措施超时检测配置定时器溢出中断当信号间隔过长时重置状态void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) { if(htim-Instance TIM2) { irData.state IR_IDLE; // 重置状态 } }数字滤波利用定时器的输入滤波器消除毛刺sConfigIC.ICFilter 0x5; // 约4个时钟周期的滤波幅度验证通过ADC检测信号强度可选3. 信号解码与协议识别3.1 原始信号采集建立数据结构存储捕获的脉冲信息#define MAX_PULSES 200 typedef struct { uint16_t highPulse[MAX_PULSES]; uint16_t lowPulse[MAX_PULSES]; uint16_t pulseCount; uint8_t state; } IR_CaptureData;3.2 协议特征提取通过统计特征识别常见协议协议类型引导脉冲特征逻辑0/1特征结束标志NEC9ms高4.5ms低560us脉冲间隔560us脉冲RC5无固定引导1.778ms位周期无固定结束Sony2.4ms高600us低600us/1200us区分0/1无固定结束3.3 通用解码算法实现void decodeIRProtocol(IR_CaptureData *data) { // 检查引导脉冲 if(data-highPulse[0] 8000 >HAL_TIM_IC_Start_DMA(htim2, TIM_CHANNEL_1, buffer, BUFFER_SIZE);双缓冲技术避免数据处理期间的信号丢失动态分辨率调整根据信号速率自动调整预分频值5. 进阶应用构建万能红外学习器基于采集的原始数据我们可以扩展以下功能红外信号数据库typedef struct { char deviceName[20]; uint16_t pulseCount; uint16_t highPulses[MAX_PULSES]; uint16_t lowPulses[MAX_PULSES]; } IR_Command;信号重放功能void replayIRSignal(TIM_HandleTypeDef *htim, IR_Command *cmd) { HAL_TIM_PWM_Start(htim, TIM_CHANNEL_1); for(int i0; icmd-pulseCount; i) { __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, cmd-highPulses[i]/2); delay_us(cmd-highPulses[i]); __HAL_TIM_SET_COMPARE(htim, TIM_CHANNEL_1, 0); delay_us(cmd-lowPulses[i]); } HAL_TIM_PWM_Stop(htim, TIM_CHANNEL_1); }实际项目中遇到的坑点某些遥控器采用载波调制需要先解调再捕获长按按键时信号可能重复发送需添加去重逻辑环境光干扰可能导致误触发建议添加硬件滤波电路
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2473063.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!