×
单片机 > 单片机程序设计 > 详情

基于STM32的NEC红外编码解码

发布时间:2020-06-18 发布时间:
|

NEC的红外遥控协议


The NEC protocol uses pulse distance encoding of thebits. Each pulse is a 560µs long 38kHz carrier burst (about 21 cycles). Alogical "1" takes 2.25ms to transmit, while a logical "0"is only half of that, being 1.125ms. The recommended carrier duty-cycle is 1/4or 1/3. 

遥控载波的频率为38KHz,红外发射端发送的编码规则如下:

   系统引导码高电平9ms,低电平4.5ms;地址码16位,数据码16位,共32位;0用“高电平0.56ms+低电平0.565ms”来表示,1用“高电平0.56ms+低电平1.6875ms”来表示,结束码用0.5625ms的高电平表示,连发码由9ms高电平+2.5m低电平+0.56ms高电平+97.94ms低电平来表示。

一个简码=引导码+地址码+数据码+结束位。

一个连发码=引导码+地址码+数据码+连发码。

而红外接收端接收到脉冲时为低电平,没有脉冲的时候为高电平,这样在接收端接收到的信号和发射端反相:

当数据发送结束后会加上一个结束码(0.565低电平),若数据发送完后按键仍处于按下状态则以连发码取代结束码,连发码“为由9ms低电平+2.5m高电平+0.56ms低电平+97.94ms高电平”。 

                                          

上图为红外遥控收发原理图。

用STM32实现红外解码源程序如下:

使用3.5库函数

void TIM2_IRQHandler(void)
{
  static u16 IR_LastPluse = 0; // static ±äÁ¿ Ö»µÚÒ»´Îʱ³õʼ»¯
   static u8  IR_Sta = 0; //
   static u32 IR_Code = 0;
   static u8  IR_PluseCnt = 0;  //
   static u8  IR_Up = 0; //
   u16 IR_ThisPluse;
   u16 IR_PluseSub;
 if ( TIM_GetITStatus( TIM2, TIM_IT_CC4 ) == SET )
 {
      TIM_ClearFlag( TIM2, TIM_IT_CC4 );
      IR_ThisPluse = TIM_GetCapture4( TIM2 );
      if ( IR_ThisPluse > IR_LastPluse )
     {
         IR_PluseSub = IR_ThisPluse - IR_LastPluse;
     }
      else
  {
         IR_PluseSub = 0xffff - IR_LastPluse + IR_ThisPluse;
    }     
  IR_LastPluse = IR_ThisPluse;
    IR_PluseCnt++; 
  if ( IR_PluseCnt == 2 )
  {
   if (( IR_PluseSub > 5000 ) && ( IR_PluseSub < 8000 )) // 10ms~16ms
   {
    IR_Sta = 0x01;
   }
  }
  else if ( IR_Sta & 0x01 ) // ??????,????
  {
   if (( IR_PluseSub < 450 ) || ( IR_PluseSub > 1300 )) //less than 0.9ms or more than 2.6ms
   {
    IR_Sta          = 0;
    IR_PluseCnt  = 0;
    IR_Code       = 0;
   }
   else
   {
    IR_Code <<= 1;
    if (( IR_PluseSub > 900 ) && ( IR_PluseSub < 1300 )) // 1.8ms~2.6ms
    {
     IR_Code |= 0x01;
    }
    if ( IR_PluseCnt == 34 )
    {
     CTRL_IR = IR_Code;
     IR_Sta = 0x02;    
    }
   }
  }
  else if ( IR_Sta & 0x02 )
  {
   switch ( IR_PluseCnt )
   {
    case 35:
    {
     if ( ( IR_PluseSub < 4500 ) || ( IR_PluseSub > 7000 ) )// less than 9ms or more than 14ms
     {
      IR_PluseCnt--;
     }
     break;
    }
    case 36:
    {
     IR_PluseCnt = 34;
     if ( ( IR_PluseSub > 45000) && ( IR_PluseSub < 60000 ) ) //90ms~120ms
     {
      CTRL_IR = IR_Code;
   //Á¬·¢Âë
    
     }
     break;
    }
   }
  }
 }
 
 if ( TIM_GetITStatus( TIM2, TIM_IT_Update ) == SET )
 {
  TIM_ClearFlag( TIM2, TIM_IT_Update );
   IR_Up++;
   if ( IR_Up >= 3 )
   {
     IR_Up=0;
   IR_Code     = 0;
    IR_Sta      = 0;
    IR_PluseCnt = 0;
    IR_PluseSub =0;
   Display_Data(CTRL_IR);  
   } 
}
}

void InputCaptureInit( void )
{
 TIM_ICInitTypeDef  TIM_ICInitStructure;
 TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;
 
 RCC_Configuration();
 NVIC_Configuration();
 GPIO_Configuration();
  GPIO_ResetBits(GPIOA,T_OE);     //disable the chip 4094 output
 Turn_Off_All_Red();
  Turn_Off_All_Grn();
 //GPIO_ResetBits(GPIOC,T_STB);  //disable the chip 4094 input
   GPIO_SetBits(GPIOA,T_OE);       //enable the chip 4094 output

 TIM_TimeBaseInitStructure.TIM_Period        = 0xffff;   // 16???
 TIM_TimeBaseInitStructure.TIM_Prescaler     = 72*2-1;   // 144?? 2us
 TIM_TimeBaseInitStructure.TIM_ClockDivision = 0;        // ???
 TIM_TimeBaseInitStructure.TIM_CounterMode   = TIM_CounterMode_Up; // ????
 TIM_TimeBaseInit( TIM2, &TIM_TimeBaseInitStructure );
 TIM_ITConfig( TIM2, TIM_IT_Update, DISABLE );
 TIM_ClearFlag(TIM2, TIM_FLAG_Update);
 
 TIM_ICInitStructure.TIM_Channel     = TIM_Channel_4;   // ????2
 TIM_ICInitStructure.TIM_ICPolarity  = TIM_ICPolarity_Falling;  // ?????
 TIM_ICInitStructure.TIM_ICPrescaler = TIM_ICPSC_DIV1;   //
 TIM_ICInitStructure.TIM_ICSelection = TIM_ICSelection_DirectTI;
 TIM_ICInitStructure.TIM_ICFilter    = 0x0;
 TIM_ICInit( TIM2, &TIM_ICInitStructure );
 TIM_ITConfig( TIM2, TIM_IT_CC4, DISABLE );
 TIM_ClearFlag( TIM2, TIM_FLAG_CC4 );
 
 TIM_Cmd( TIM2, ENABLE );
 TIM_ITConfig(  TIM2,TIM_IT_Update|TIM_IT_CC4 , ENABLE );
}

rcc gpio nvic配置就不写了。记得把用到的挂到时钟线上,tim2用cmd使能了就行。


关键字:STM32  NEC  红外编码解码 

『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
51单片机CO2检测显示程序解析