本文主要是介绍(红外遥控)STM32+红外模块控制格力空调,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
其他红外介绍不多说了,下面介绍一下我使用stm32控制格力空调所遇到问题。
1.红外实现过程中遇到的问题
网上大部分对格力空调红外编码的介绍都是
起始码(S)+35位数据码+连接码(C)+32位数据码
0的电平宽度为:620us低电平+540us高电平,
1的电平宽度为:620us低电平+1620us高电平
起始码S电平宽度为:9000us低电平+4500us高电平
连接码C电平宽度为:620us低电平+20000us高电平
以上是在接受端的定义,要注意分辨。发射端是相反的
红外发射端的波形。
红外接受端是以下这种
两者是不同的。网上大多是第二种容易产生误解。
格力空调的编码如下图——
网上的格式都大同小异对红外的编码产生的影响不大。
根据实际的使用,我发现我所使用的遥控器是如下这中格式,末尾的连接码不可缺少。
起始码(S)+35位数据码+连接码(C)+32位数据码+连接码(C)
而且红外遥控器会以两倍的连接码时间间隔发送两次命令。
以上是我实现红外过程中遇到的问题。
2.实现方法
使用stm32的pwm功能发出38kHz的载波,然后控制占空比以达到高低电平的实现。
//38kHz初始化RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2,ENABLE); //打开定时器2的时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); //打开GPIOA的时钟 /*注意:只有部分端口才有PWM功能*/GPIO_InitTypeDef GPIO_InitStructure;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_Init(GPIOA, &GPIO_InitStructure);TIM_InternalClockConfig(TIM2); //设置定时器2的时钟源为内部时钟源TIM_TimeBaseInitTypeDef TimBaseInitStructure; //设置时基单元TimBaseInitStructure.TIM_ClockDivision = TIM_CKD_DIV1; TimBaseInitStructure.TIM_CounterMode = TIM_CounterMode_Up; //设置计数模式为向上计数TimBaseInitStructure.TIM_Period = 101-1; //ARR(自动重装器,设置计数峰值)TimBaseInitStructure.TIM_Prescaler = 19-1; //PSC(预分频器,设置计时频率)TimBaseInitStructure.TIM_RepetitionCounter = 0; //设置计数重装值TIM_TimeBaseInit(TIM2, &TimBaseInitStructure);TIM_OCInitTypeDef TIM_OCInitStructure; //设置输出比较单元TIM_OCStructInit(&TIM_OCInitStructure); //先对TIM_OCInitStructure所有成员赋值,之后只会对部分成员重新赋值,防止出现部分成员未赋值情况TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; //设置输出比较模式为PWM1模式TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; //输出比较极性(设置REF,有效电平为高电平)TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; //输出状态使能TIM_OCInitStructure.TIM_Pulse = 0; //CRR(输出比较值)TIM_OC2Init(TIM2,&TIM_OCInitStructure); //使用输出比较通道2TIM_Cmd(TIM2,ENABLE); //定时器2使能
编码格式的实现
typedef struct{// Byte 0uint8_t Mode :3;uint8_t Power :1;uint8_t Fan :2;uint8_t SwingAuto :1;uint8_t Sleep :1;// Byte 1uint8_t Temp :4;uint8_t TimerHalfHr :1;uint8_t TimerTensHr :2;uint8_t TimerEnabled:1;// Byte 2uint8_t TimerHours:4;uint8_t Turbo :1;uint8_t Light :1;uint8_t anion :1; // model==YAW1Fuint8_t Powersv :1;// Byte 3uint8_t unknown0 :2;//00uint8_t TempExtraDegreeF:1;uint8_t UseFahrenheit :1;uint8_t unknown1 :4; // value=0b0101// Byte 4uint8_t SwingV :4;uint8_t SwingH :3;uint8_t unknown2 :1; //0// Byte 5uint8_t DisplayTemp :2;uint8_t IFeel :1;uint8_t unknown3 :3; // value = 0b100 uint8_t WiFi :1; //0uint8_t unknown4 :1; //0// Byte 6uint8_t unknown5 :8; //00000000// Byte 7uint8_t unknown6 :2; //00uint8_t Econo :1;uint8_t unknown7 :1;//0uint8_t Sum :4;}Protocol;
//红外码初始化
以及发送过程,发送都是逆序的即从低向高为发送。
void IR_Send38kHz(uint16_t time,FunctionalState NewState){if(NewState == 1){TIM_SetCompare2(TIM2,0);Delay_us(time);}else{TIM_SetCompare2(TIM2,50);Delay_us(time);}
};void IR_SendGreeH(void){TIM_SetCompare2(TIM2,50);Delay_us(GreeBitMark);TIM_SetCompare2(TIM2,0);Delay_us(GreeOneSpace);
};void IR_SendGreeL(void){TIM_SetCompare2(TIM2,50);Delay_us(GreeBitMark);TIM_SetCompare2(TIM2,0);Delay_us(GreeZeroSpace);
};void IR_SendMsg(uint8_t cnt,uint8_t data){while(cnt--){if(data&0x01){IR_SendGreeH();data=data>>1;}else{IR_SendGreeL();data=data>>1;}}
};
特别注意校验码的计算,网上有很多公式。下面我给出一种
校验码 = [(模式 – 1) + (温度 – 16) + 5 +左右扫风+换气+节能]取二进制后四位;
参考博客
GitHub - crankyoldgit/IRremoteESP8266: Infrared remote library for ESP8266/ESP32: send and receive infrared signals with multiple protocols. Based on: https://github.com/shirriff/Arduino-IRremote/
【智能电表】格力空调遥控器红外协议_格力空调红外协议-CSDN博客
格力空调遥控器红外编码透析(长码)_格力空调红外编码-CSDN博客
[LPC54102]红外编码与解码——GREE格力遥控 - NXP MCU - 电子工程世界-论坛 (eeworld.com.cn)
这篇关于(红外遥控)STM32+红外模块控制格力空调的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!