stm32 无线遥控HX1838或8路低电平解码接收模块Hal库代码程序

一、简介

这是一款新型的超薄38K通用红外遥控器,采用的是NEC编码格式,主要用于车载MP3、足浴盆、灯光设配、数码相框、单片机开发板和学习板等场合。因其是基于无线遥控,因此人们在使用起来显得方便、有效,现在的应用领域也越来越宽,那么针对我们公司的这款产品我们将做如下的介绍。

63be8681e1834577a8782b2733d8146e.jpg

二、技术参数红外遥控距离

大于8米发射管红外波长:940Nm

晶振频率:455KHZ的晶振

载波频率:38KHZ

编码:编码格式为NEC

尺寸:86* 40* 6mm

电源:CR2025/1600mAH

三、小板接口说明(3线制)

 VCC 外接5V

 GND 外接GND

 DO 小板数字量输出接口

四、红外遥控器采用了NEC编码规则

e8bffecbd9b34f46a81f6e03f07d3cd4.jpeg

e3c01343305a4695add67a450d28141d.jpeg

81f6e2993caf4af19250aef9e70dc62e.jpeg

64f52a4dd0dd481080b6ac30c4e6ed95.jpeg

NEC 载波频率为 38Khz

引导码:9ms 高电平 + 4.5ms 低电平

1 码 :0.56 ms 高电平 + 0.56 ms 低电平

0 码 : 0.56ms 高电平 + 1.68 ms 低电平

结束码 :0.56ms 高电平

数据帧格式:引导码 + 地址 + 地址反码 + 键值 + 键值反码 + 结束码

重复帧格式:9ms 高电平 + 2.25ms低电平 + 结束位 + 结束码

高位在前,即首先收到的是高位的数据

注:本文使用的接收头,电平极性与协议相反。所以,当捕获到一个 9ms 低电平 + 4.5ms 高电平时,即收到一个引导码。

5dec00d11a92408dbbc45a245de48d8a.jpg

2aa184aa5886480d95c96b5a11a89a27.jpg

红外线发送的每一帧数据,除了引导码以外,有32位有效数据

//HX1838.c

#define IRDA_ID 0
 //读取引脚的电平#define  IrDa_DATA_IN()       HAL_GPIO_ReadPin(GPIOD,GPIO_PIN_7)
uint32_t frame_data=0;    /* 一帧数据缓存 */
uint8_t  frame_cnt=0;
uint8_t  frame_flag=0;    /* 一帧数据接收完成标志 */
/* 获取高电平的时间 */
uint8_t Get_Pulse_Time(void)
{
  uint8_t time = 0;
  while( IrDa_DATA_IN() )
  {
    time ++;
    Delay_us(2);     // 延时 20us
    if(time == 250)
      return time;   // 超时溢出   
  }
  return time;
}
/*
 * 帧数据有4个字节,第一个字节是遥控的ID,第二个字节是第一个字节的反码
 * 第三个数据是遥控的真正的键值,第四个字节是第三个字节的反码
 */
uint8_t IrDa_Process(void)
{
  uint8_t first_byte, sec_byte, tir_byte, fou_byte;  
  
  first_byte = frame_data >> 24;
  sec_byte = (frame_data>>16) & 0xff;
  tir_byte = frame_data >> 8;
  fou_byte = frame_data;
  
  /* 记得清标志位 */
  frame_flag = 0;
  
  if( (first_byte==(uint8_t)~sec_byte) && (first_byte==IRDA_ID) )
  {
    if( tir_byte == (uint8_t)~fou_byte )
      return tir_byte;
  }
  
  return 0;   /* 错误返回 */
}

//中断

void EXTI9_5_IRQHandler(void)
{
    uint8_t pulse_time = 0;
  uint8_t leader_code_flag = 0; /* 引导码标志位,当引导码出现时,表示一帧数据开始 */
  uint8_t irda_data = 0;        /* 数据暂存位 */
  EXTI_HandleTypeDef hext;
    hext.Line=EXTI_LINE_7;
  if(HAL_EXTI_GetPending(&hext, EXTI_TRIGGER_RISING_FALLING)!= RESET) /* 确保是否产生了EXTI Line中断 */
    {   
    while(1)
    {
      if( IrDa_DATA_IN()== SET )        /* 只测量高电平的时间 */
      {       
        pulse_time = Get_Pulse_Time();    
        /* >=5ms 不是有用信号 当出现干扰或者连发码时,也会break跳出while(1)循环 */
        if( pulse_time >= 250 )                
        {
          break; /* 跳出while(1)循环 */
        }        
        if(pulse_time>=200 && pulse_time<250)         /* 获得前导位 4ms~4.5ms */
        {
          leader_code_flag = 1;
        }
        else if(pulse_time>=10 && pulse_time<50)      /* 0.56ms: 0.2ms~1ms */
        {
          irda_data = 0;
        }
        else if(pulse_time>=50 && pulse_time<100)     /* 1.68ms:1ms~2ms */
        {
          irda_data =1 ; 
        }        
        else if( pulse_time>=100 && pulse_time<=200 ) /* 2.1ms:2ms~4ms */
        {/* 连发码,在第二次中断出现 */
          frame_flag = 1;               /* 一帧数据接收完成 */
          frame_cnt++;                  /* 按键次数加1 */
          isr_cnt ++;                   /* 进中断一次加1 */
          break;                        /* 跳出while(1)循环 */
        }        
        if( leader_code_flag == 1 )
        {/* 在第一次中断中完成 */
          frame_data <<= 1;
          frame_data += irda_data;
          frame_cnt = 0;
          isr_cnt = 1;
        }
      }      
    }// while(1)   
             //清除中断标志位                HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
    //LED2_TOGGLE;
    }
}

不过有一款更加简单,只需操作GPIO就可以遥控了

26672689420a41169593be15c6367fb0.jpga092085c114a4221ac8b259a2f98567c.jpg