基于STM32的NEC红外编码解码

发布者:量子启示最新更新时间:2018-10-15 来源: eefocus关键字:STM32  NEC  红外编码解码 手机看文章 扫描二维码
随时随地手机看文章

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低电平来表示。

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

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

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

IR NEC Protocol

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

[转载]基于STM32的NEC红外编码解码                                          [转载]基于STM32的NEC红外编码解码[转载]基于STM32的NEC红外编码解码

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

用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  红外编码解码 引用地址:基于STM32的NEC红外编码解码

上一篇:基于STM32的MS5540c压强温度传感器的应用
下一篇:STM32,KEIL,MDK新建一个工程

推荐阅读最新更新时间:2024-03-16 16:16

STM32入门学习笔记之中断架构(上)
3.1 STM32F103中断概述 Cortex-M3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。但STM32并没有使用Cortex-M3内核的全部东西,而是只用了它的一部分。STM32有84个中断,包括16个内核中断和68个可屏蔽中断,具有16级可编程的中断优先级。而我们常用的就是这68个可屏蔽中断,但是STM32的68个可屏蔽中断,在STM32F103ZET6中只有60个。 3.2 STM32F103中断优先级 3.2.1 优先级结构 STM32F103的中断分为抢占优先级和响应优先级两种,这两种优先级的顺序是抢占优先级高于响应优先级,假设存在两个事件,那就会存在以下
[单片机]
全面掌握stm32的GPIO知识
1 初学者重要提示 本文主要是以stm32H7系列为主。 对于不使用的引脚,推荐设置为模拟模式,悬空即可。 GPIO的速度等级高的时候,最好使能IO补偿单元。 2 GPIO功能简介 STM32H7的GPIO特性如下: 输出状态:开漏/推挽 + 上拉/下拉电阻。 通过输出数据寄存器(GPIOx_ODR)或者外设(GPIO设置为复用模式时)输出数据。 GPIO速度等级设置。 输入状态:浮空,上拉/下拉,模拟。 通过输入数据寄存器(GPIOx_IDR)或者外设(GPIO设置为复用模式)输入数据。 通过寄存器GPIOx_BSRR实现对寄存器GPIOx_ODR的位操作。 通过配置寄存器GPIOx_LCKR的锁机制,实现冻结IO口配置。 每两
[单片机]
全面掌握<font color='red'>stm32</font>的GPIO知识
SPI接口说明及原理
1简介 SPI:Serial Peripheral Interface,是串行外设接口。 SPI是由摩托罗拉于 1985 年前后开发,是一种适用于短距离、设备到设备通信的同步串行接口。 从那时起,这种接口就已成为许多半导体制造商,特别是微控制器(MCU)和微处理器(MPU)采用的事实标准。 2SPI接口 SPI总线是一种4线总线,通常有一个主设备和一个或多个从设备,需要至少4根线,事实上3根也可以。 MOSI:Master Output Slave Input,主设备数据输出,从设备数据输入; MISO:Master Input Slave Output,主设备数据输入,从设备数据输出; SCLK:Serial Clock,时
[单片机]
SPI接口说明及原理
STM32在MDK下的一种通用建立库函数工程的方法(标准库)
物料准备 MDK4或者(MDK5+Legacy支持包) ST官方下载的库文件(STM32F10x_StdPeriph_Lib_V3.5.0) 下载地址 http://pan.baidu.com/s/1cyxwXS 库函数主要文件夹简介 需要的用的库文件都在STM32F10x_StdPeriph_Lib_V3.5.0Libraries文件夹下,它又包含了以下两个文件夹 CMSIS(一些核心和库文件代码,CMSIS主要代码) CM3DeviceSupportSTSTM32F10x文件夹 system_stm32f10x.c(STM32F10x CMSIS Cortex-M3设备访问层的系统源文件) system_stm3
[单片机]
<font color='red'>STM32</font>在MDK下的一种通用建立库函数工程的方法(标准库)
stm32 usb数据缓冲区疑问
USB不同的应用需要使用到的端点数和端点数据长度各不相同,如果为每个端点都单独规划一个存储区非常浪费。 所以STM32为USB模块提供了共512个字节的存储区,至于如何为每个端点分配使用这512B的空间,就是用户自己的事情了,这样存储区的分配就非常经济灵活。这512B空间的首地址是0x40006000。 你看到的#define ENDP2_RXADDR (0xD8),这个0xD8就是在这512B空间里的偏移地址,说明端点2收到的数据将放在0x40006000 + 0xD8 * 2的地址空间里。至于为什么要×2,是因为这部分存储区是按照2字节访问的,即每存放1个字节的数据要占据2个字节的空间。所以这段存储区的地址是从0
[单片机]
STM32库函数详解----(通用输入/输出GPIO)
初始化和配置相关函数 1.void GPIO_DeInit (GPIO_TypeDef* GPIOx) 函数解释:gpio的反初始化函数,该函数的作用是把GPIO相关的寄存器配置成上电复位后的默认状态,在第一次初始化前或者不在使用某一接口后,可以调用该函数。 参数:GPIOx,GPIO的分组,如 GPIOA,GPIOB,GPIOC等的宏定义。 2.void GPIO_Init (GPIO_TypeDef* GPIOx,GPIO_InitTypeDef* GPIO_InitStruct) 函数解释:GPIO的初始化函数,该函数的作用是对io进行初始化。 参数:(1)GPIOx,GPIO的分组,如 GPI
[单片机]
STM32学习之启动代码注释
;Reset_Handler 子程序开始 Reset_Handler PROC ;输出子程序Reset_Handler到外部文件 EXPORT Reset_Handler ;从外部文件引入__main函数 IMPORT __main ;从外部文件引入SystemInit函数 IMPORT SystemInit ;把SystemInit函数调用地址加载到通用寄存器R0 LDR R0, =SystemInit ;跳转到R0中保存的地址执行程序(调用SystemInit函数) BLX R0 ;把main函数调用地址加载到通用寄存器R0 LDR R0, =__main ;跳转到R0中保存的地址执
[单片机]
STM32的IO输入与输出
开漏输出:输出端相当于三极管的集电极. 要得到高电平状态需要上拉电阻才行. 适合于做电流型的驱动,其吸收电流的能力相对强(一般20ma以内) 开漏输出不能输出高电平,原因: 图一为开漏输出,输入1时左边三极管导通,右边三极管截止,相当于图二开关断开。相对应的输入为0时左边三极管断开,右边三极管导通,相当于图二开关闭合。闭合时输出接地,则无高电平,断开时输出为高阻态,如果输出端有接负载接地,则断开时输出依然有接地,因此开漏输出是没有高电平输出的 对于图三,接一个上拉电阻,如果开关闭合,则有电流从1K电阻和开关上流过。当我们使用输入功能时,将输出口的代码设置为1,相当图三开关断开,则有电流向输出端输入,即为高电平状态。 推挽输出:可以
[单片机]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved