使用STM32红外模块控制格力空调

 

其他红外介绍不多说了,下面介绍一下我使用stm32控制格力空调所遇到问题。

1.红外实现过程中遇到的问题

   网上大部分对格力空调红外编码的介绍都是

    起始码(S)+35位数据码+连接码(C)+32位数据码

 

0的电平宽度为:620us低电平+540us高电平,

1的电平宽度为:620us低电平+1620us高电平

起始码S电平宽度为:9000us低电平+4500us高电平

连接码C电平宽度为:620us低电平+20000us高电平

以上是在接受端的定义,要注意分辨。发射端是相反的

红外发射端的波形。

74815d1f91b445faa56bb5f20da38639.png

红外接受端是以下这种

366726d11e8d467a975c66096662340b.png

两者是不同的。网上大多是第二种容易产生误解。

格力空调的编码如下图——

d799f9a0f461468082b8a6ae26d8b2b7.png

网上的格式都大同小异对红外的编码产生的影响不大。

根据实际的使用,我发现我所使用的遥控器是如下这中格式,末尾的连接码不可缺少。

起始码(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);	//使用输出比较通道2
  TIM_Cmd(TIM2,ENABLE);	//定时器2使能

编码格式的实现

typedef struct{
    // Byte 0
    uint8_t Mode      :3;
    uint8_t Power     :1;
    uint8_t Fan       :2;
    uint8_t SwingAuto :1;
    uint8_t Sleep     :1;
    // Byte 1
    uint8_t Temp        :4;
    uint8_t TimerHalfHr :1;
    uint8_t TimerTensHr :2;
    uint8_t TimerEnabled:1;
    // Byte 2
    uint8_t TimerHours:4;
    uint8_t Turbo     :1;
    uint8_t Light     :1;
    uint8_t anion     :1;  // model==YAW1F
    uint8_t Powersv   :1;
    // Byte 3
    uint8_t unknown0        :2;//00
    uint8_t TempExtraDegreeF:1;
    uint8_t UseFahrenheit   :1;
    uint8_t unknown1        :4;  // value=0b0101
    // Byte 4
    uint8_t SwingV      :4;
    uint8_t SwingH      :3;
    uint8_t unknown2     :1; //0
    // Byte 5
    uint8_t DisplayTemp :2;
    uint8_t IFeel       :1;
    uint8_t unknown3    :3;  // value = 0b100 
    uint8_t WiFi        :1;  //0
    uint8_t unknown4    :1;    //0
    // Byte 6
    uint8_t unknown5   :8;  //00000000
    // Byte 7
    uint8_t unknown6    :2; //00
    uint8_t Econo       :1;
    uint8_t unknown7    :1;//0
    uint8_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)

 

 

 

物联沃分享整理
物联沃-IOTWORD物联网 » 使用STM32红外模块控制格力空调

发表评论