STM32F103xx红外接收处理与红外技术详解

STM32F103c6t6+红外遥控+红外接收模块

  • 前言
  • 一、什么红外通信协议
  • 1.1、NEC 协议
  • 1.1-1,NEC 协议 位 的定义
  • 1.1-2,红外遥控以NEC 协议数据“单发”的格式
  • 1.1-3,红外遥控以NEC 协议“连发”数据格式
  • 1.1-4捕获红外信号的思路
  • 二、红外接收程序
  • 2.1、由外部中断接收红外信号
  • 2.1-1、GUA_Infrared_Receiver.c 文件
  • 2.1-2、GUA_Infrared_Receiver.h 文件
  • 2.1-3、main.c 文件
  • 效果演示
  • 相关参考资料链接
  • 前言

    红外传感只占用了STM32的一个引脚(外部中断引脚)就可以实现无数的数据传输,单片机也就对不同的红外数据进行接收与程序存储的信息进行比较,再在执行主程序·····
    下面是本人对红外接收的处理,以及相应的一些简单的主函数执行。

    一、什么红外通信协议

    1.1、NEC 协议

  • 8位地址码和8位用户码;
  • 增加8位地址反码和8位用户反码的传输(以确保可靠性);
  • PWM脉冲位置调制,以发射红外载波的占空比代表“0”和“1”;
  • 载波频率为38Khz;
  • 1.1-1,NEC 协议 位 的定义

    如何判断数据的一个位是 “1” 还是 “0” :

  • 一个逻辑 “1” 传输需要2.25ms(560us脉冲+1680us低电平);
  • 一个逻辑 “0” 的传输需要1.125ms(560us脉冲+560us低电平);
  • 所以,每位的周期为 2.25ms 或者 1.12ms ,(分别代表“1”和“0”)
  • 1.1-2,红外遥控以NEC 协议数据“单发”的格式

    一个正常的数据包 :

  • 开头:发送的是9ms高电平+4.5ms低电平。为引导码。
  • 紧接着是:8bit的地址码+8bit地址反码+8bit用户码+8bit用户反码。为32位的数据。
  • 单次发送时

    1.1-3,红外遥控以NEC 协议“连发”数据格式

    连续发送数据包 :

  • 长按红外遥控按键时,每隔 110ms 重复发送一次。但是命令只发送一次,重复发送的是 9ms 高电平+2.25ms 低电平+0.56ms 高电平+低电平
  • 连续发送时

    1.1-4捕获红外信号的思路

  • 接收程序思路分析: STM32红外接收分析
  • 关于理解 NEC 协议+程序设置思路: 红外遥控+定时器计时
  • +定时器实现解码红外NEC协议: STM32定时器实现红外接收与解码
  • 二、红外接收程序

    2.1、由外部中断接收红外信号

    2.1-1、GUA_Infrared_Receiver.c 文件

  • 针对大佬的代码进行了自己的理解与修改,增加了解译红外遥控发送的32位数据(地址码+地址反码+用户码+用户反码)的函数。
  • 这里最核心的,属红外接收处理时对高低电平时间的判断,经过不断的修正电平维持时间,就可以将红外遥控发送的数据捕获到。
  • 针对不同的遥控可能因为单片机频率和红外接收模块各因素,需要修改判断电平维持时间的范围。处理红外接收的函数
  • GUA_U8 GUA_Infrared_Receiver_Process(void)
    
  • 在红外接收处理函数处,我增加串口输出的功能,每到一个接收出错退出循环的同时将上次计时的值从串口打印出来,由此知道红外接收输入引脚上电平变化的时间间隔。对不同的遥控按键发送的协议解读有实用价值。
    红外接收处理出错时执行
  • /6		else if(GUA_Infrared_Receiver_Process() == GUA_INFRARED_RECEIVER_ERROR)
    		{ 											//否则、串口显示已经累加的时间(uS)和 解码错误提示
    			Serial_SendNumber(nGUA_Time_Num,4);			
    			Serial_SendString(" GUA_INFRARED_RECEIVER_ERROR  \r\n");
    			gGUA_InfraredReceiver_Data=0;
    		}
    
  • 还有,红外发送过来的键码解读成功后,将其 地址码+地址反码+用户码+用户反码 都打印在串口上,由此,可以看到用户码(命令键)的十进制,再换算成十六进制后就可以进行比较与传递。 跳转到该子函数执行串口显示
  • /5			Show_Data();       		 //显示红外接收到的数据
    
  • 这里对于红外连续发送时的处理比较随便,但是效果还是达到了。不符合该函数判断的红外协议并不会被捕获到。

  • 四重对电平维持时间判断关卡决定了数据的保存与否。

  • 
    #include "GUA_Infrared_Receiver.h"
    
    /*********************外部变量************************/
    GUA_U32 gGUA_InfraredReceiver_Data = 0;  //一个接收红外原始数据的变量(32位)
    
    /********************保存红外数据的变量*************/
    uint8_t IR_RECEIVE[5];   // 每一项保存一个字节数据
    int down16,up16;         // 分别保存低十六位和高十六位数据
    
    uint8_t IR_State;		
    uint8_t IR_DataFlag;    //单发标志
    uint8_t IR_RepeatFlag;  //连发标志
    
    /*********************内部函数************************/
    static void GUA_Infrared_Receiver_IO_Init(void);
    static GUA_U16 GUA_Infrared_Receiver_GetHighLevelTime(void);
    static GUA_U16 GUA_Infrared_Receiver_GetLowLevelTime(void);
    
    //******************************************************************************        
    //name:             GUA_Infrared_Receiver_IO_Init        
    //introduce:        红外接收的IO初始化  
    static void GUA_Infrared_Receiver_IO_Init(void)
    {   
        GPIO_InitTypeDef GPIO_InitStructure;	//IO结构体
    //	//失能JTAG和SWD在PB3上的功能使用
    //	GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable, ENABLE);
    //	GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable, ENABLE);
    	//时钟使能
    RCC_APB2PeriphClockCmd(GUA_INFRARED_RECEIVER_RCC | RCC_APB2Periph_AFIO, ENABLE);
    
    	//红外接收IO配置
        GPIO_InitStructure.GPIO_Pin = GUA_INFRARED_RECEIVER_PIN;        
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 
        GPIO_Init(GUA_INFRARED_RECEIVER_PORT, &GPIO_InitStructure);  
    
        GPIO_EXTILineConfig(GUA_INFRARED_RECEIVER_PORTSOURCE, GUA_INFRARED_RECEIVER_PINSOURCE); 
    }
    
    //******************************************************************************            
    //name:             GUA_Infrared_Receiver_Exti_Init
    //introduce:        红外接收的IO中断初始化                             
    //******************************************************************************
    static void GUA_Infrared_Receiver_Exti_Init(void)
    {   
    	NVIC_InitTypeDef NVIC_InitStructure;
        EXTI_InitTypeDef EXTI_InitStructure;
    	//中断配置
        EXTI_InitStructure.EXTI_Line = GUA_INFRARED_RECEIVER_EXTI_LINE;
        EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger =  EXTI_Trigger_Falling ;  
        EXTI_InitStructure.EXTI_LineCmd = ENABLE;
        EXTI_Init(&EXTI_InitStructure);
    
        NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
    	NVIC_Init(&NVIC_InitStructure);
    }
    
    //******************************************************************************        
    //name:             GUA_Infrared_Receiver_Init 
    //introduce:        红外接收初始化 
    //******************************************************************************  
    void GUA_Infrared_Receiver_Init(void)
    {
    	GUA_Infrared_Receiver_IO_Init();  //初始化IO
    	GUA_Infrared_Receiver_Exti_Init();  //初始化中断配置
    }
    
    //******************************************************************************        
    //name:             GUA_Infrared_Receiver_GetHighLevelTime  
    //introduce:        红外接收获取高电平维持时间
    //****************************************************************************** 
    static GUA_U16 GUA_Infrared_Receiver_GetHighLevelTime(void)
    {
        GUA_U16 nGUA_Num = 0;
    	//判断是否一直为高电平
    while(GPIO_ReadInputDataBit(GUA_INFRARED_RECEIVER_PORT, GUA_INFRARED_RECEIVER_PIN) == Bit_SET)
        {
    		//超时超时溢出
            if(nGUA_Num >= 250) 
            {
                return nGUA_Num;
            }
            nGUA_Num++;	 	//计延时20us的次数
            Delay_us(20);	//该延时针对外部晶振8000的STM32C8T6核心板,对于不同类型不同外部晶振的开发板需要根据波形图调整延时,保证20us延时       
        }
    
        return nGUA_Num;
    }
    
    //******************************************************************************        
    //name:             GUA_Infrared_Receiver_GetLowLevelTime  
    //introduce:        红外接收获取低电平维持时间
    //****************************************************************************** 
    static GUA_U16 GUA_Infrared_Receiver_GetLowLevelTime(void)
    {
        GUA_U16 nGUA_Num = 0;
    
    	//判断是否一直为低电平
        while(GPIO_ReadInputDataBit(GUA_INFRARED_RECEIVER_PORT, GUA_INFRARED_RECEIVER_PIN) == Bit_RESET)
        {
            if(nGUA_Num >= 500) 
            {
                return nGUA_Num;
            }
    
            nGUA_Num++;
    
            delay_us(20);//该延时针对外部晶振8000的STM32C8T6核心板,对于不同类型不同外部晶振的开发板需要根据波形图调整延时,保证低电平延时                   
        }
    
        return nGUA_Num;
    }
    
    //******************************************************************************            
    //name:             GUA_Infrared_Receiver_Process  
    //introduce:        红外接收的处理函数 
    // 该函数是关键所在:处理红外信号看接收管OUT引脚电平维持时间,高低电平一定时间后状态变化。
    //                  依据电平维持时间,判断:引导码、32位数据···
    //******************************************************************************
    GUA_U16 nGUA_Time_Num;
    GUA_U8 nGUA_Data;
    GUA_U8 nGUA_Byte_Num;
    GUA_U8 nGUA_Bit_Num;
    GUA_U32 ContinuousReceiver_Data;  //保存上次捕获的32位原始的数据
    //
    GUA_U8 GUA_Infrared_Receiver_Process(void)
    {
         nGUA_Time_Num = 0;
         nGUA_Data = 0;
         nGUA_Byte_Num = 0;
         nGUA_Bit_Num = 0;
    
    	//接收引导码9ms的低电平,过滤无用信号>10ms或<8ms
        nGUA_Time_Num = GUA_Infrared_Receiver_GetLowLevelTime();
        if((nGUA_Time_Num > 500) || (nGUA_Time_Num < 400))
        {
    //1		Serial_SendString("\r\n 1: error occurred \r\n");     //_________
            return GUA_INFRARED_RECEIVER_ERROR;
        }   
    	//接收引导码4.5ms的高电平,过滤无用信号>5ms或<4ms     //250ms时是连续发送信号
        nGUA_Time_Num = GUA_Infrared_Receiver_GetHighLevelTime();
        if((nGUA_Time_Num > 250) || (nGUA_Time_Num < 100))                   //200<=  >=250
        {
    //2		Serial_SendString("\r\n 2: error occurred \r\n");     //_________
            return GUA_INFRARED_RECEIVER_ERROR;
        }   
    	
    	//接收4字节数据(分别有:用户反码、用户码、地址反码、地址码)
        for(nGUA_Byte_Num = 0; nGUA_Byte_Num < 4; nGUA_Byte_Num++)
        {
    		//接收位数据(每字节8位)
            for(nGUA_Bit_Num = 0; nGUA_Bit_Num < 8; nGUA_Bit_Num++)
            {
    			//接收每bit的前0.56ms的低电平,过滤无用信号>1.2ms或<0.40ms
                nGUA_Time_Num = GUA_Infrared_Receiver_GetLowLevelTime();
                if((nGUA_Time_Num > 60) || (nGUA_Time_Num < 20))
                {
    //3				Serial_SendString("\r\n 3: error occurred \r\n");     //_________
                    return GUA_INFRARED_RECEIVER_ERROR;
                }
    			//接收每bit的后高电平时长:高电平数据,1.68ms(1.2ms~2.0ms),低电平数据,0.56ms(0.2ms~1ms),过滤其他无用信号
    			nGUA_Time_Num = GUA_Infrared_Receiver_GetHighLevelTime();
                if((nGUA_Time_Num >=60) && (nGUA_Time_Num < 100))   //25  50
                {
                    nGUA_Data = 1;
                }
                else if((nGUA_Time_Num >=10) && (nGUA_Time_Num < 50))   //50 90
                {
                    nGUA_Data = 0;
                }
                else
                {
    				if(nGUA_Time_Num == 250)   //红外连续发送情况下,退出循环直接赋予上次的数据
    				{
    					IR_RepeatFlag = 1;     //连续收发标志置一
    					IR_DataFlag = 0;		//单发标志置零
    					gGUA_InfraredReceiver_Data = ContinuousReceiver_Data;
    					return GUA_INFRARED_RECEIVER_OK;    
    				}else{
    //4					Serial_SendString("\r\n 4: error occurred \r\n");     //_________
    					return GUA_INFRARED_RECEIVER_ERROR;
    				}
                }
    			//保存数据
                gGUA_InfraredReceiver_Data <<= 1;   
                gGUA_InfraredReceiver_Data |= nGUA_Data;                        
            }
        }
    	
    	IR_DataFlag = 1;     //单次收发标志置一
    	IR_RepeatFlag = 0;   //连发标志置零
    	ContinuousReceiver_Data = gGUA_InfraredReceiver_Data;
        return GUA_INFRARED_RECEIVER_OK;    
    }
    
    //*******************************************************************************
    //》》》》》》》》》》》》》》中断处理函数《《《《《《《《《《《《《《《《《《
    void EXTI9_5_IRQHandler(void)
    {
    	if(EXTI_GetITStatus(GUA_INFRARED_RECEIVER_EXTI_LINE) != RESET)
    	{
    		EXTI_ClearITPendingBit(GUA_INFRARED_RECEIVER_EXTI_LINE);
    		EXTI->IMR &= ~(GUA_INFRARED_RECEIVER_EXTI_LINE);
    	  
    		if(GUA_Infrared_Receiver_Process() == GUA_INFRARED_RECEIVER_OK) //如果捕获到有效数据
    		{
    			down16=gGUA_InfraredReceiver_Data;
    			up16=gGUA_InfraredReceiver_Data>>16;
    			//-----------从上到下依次为用户反码、用户码、地址反码、地址码
    			IR_RECEIVE[3]=down16;
    			IR_RECEIVE[2]=(down16>>8);
    			IR_RECEIVE[1]=up16;
    			IR_RECEIVE[0]=(up16>>8);
    
    //5			Show_Data();       		 //显示红外接收到的数据
    		}	
    /*6		else if(GUA_Infrared_Receiver_Process() == GUA_INFRARED_RECEIVER_ERROR)
    		{ 											//否则、串口显示已经累加的时间(uS)和 解码错误提示
    			Serial_SendNumber(nGUA_Time_Num,4);			
    			Serial_SendString(" GUA_INFRARED_RECEIVER_ERROR  \r\n");
    			gGUA_InfraredReceiver_Data=0;
    		}
    		*/
    	}
    	EXTI->IMR|=(GUA_INFRARED_RECEIVER_EXTI_LINE);
    }
    
    /***********************调试键码的函数(串口输出)*********************************
      *
      *函数: 显示出已经捕获得到的红外数据,
      *		  如果解码成功,可以获得红外数据(地址码+地址反码+用户码+用户反码)
      *		  (通过串口发送相关信息,使用Serial_SendNumber()可以在调试窗口文本类得到十进制格式,
      *		    再将数据十进制换算成十六进制就可以进行比较和传递。)
      *参数:无
    **/
    void Show_Data(void)
    {
    //	Serial_SendArray(IR_RECEIVE,32);
    	Serial_SendString("\r\n GUA_INFRARED_RECEIVER_OK  ");
    	Serial_SendString("\r\n 用户反码:  ");
    	Serial_SendNumber( IR_RECEIVE[3],4);
    	Serial_SendString("\r\n 用户码:  ");
    	Serial_SendNumber( IR_RECEIVE[2],4);
    	Serial_SendString("\r\n 地址反码:  ");
    	Serial_SendNumber( IR_RECEIVE[1],4);
    	Serial_SendString("\r\n 地址码:  ");
    	Serial_SendNumber( IR_RECEIVE[0],4);
    }
    /************************************五个可获取红外相关数据的函数***********************************
      * @brief  红外遥控获取收到数据帧标志位
      * @param  无
      * @retval 是否收到数据帧,1为收到,0为未收到
      */
    uint8_t IR_GetDataFlag(void)
    {
    	if(IR_DataFlag)
    	{
    		IR_DataFlag=0;
    		return 1;
    	}
    	return 0;
    }
    /**
      * @brief  红外遥控获取收到连发帧标志位
      * @param  无
      * @retval 是否收到连发帧,1为收到,0为未收到
      */
    uint8_t IR_GetRepeatFlag(void)
    {
    	if(IR_RepeatFlag)
    	{
    		IR_RepeatFlag=0;
    		return 1;
    	}
    	return 0;
    }
    /**
      * @brief  红外遥控获取收到的地址数据
      * @param  无
      * @retval 收到的地址码数据
      */
    uint8_t IR_GetAddress(void)
    {
    	return IR_RECEIVE[0];
    }
    /**
      * @brief  红外遥控获取收到的命令数据
      * @param  无
      * @retval 收到的用户码数据
      */
    uint8_t IR_GetUserCode(void)
    {
    	return IR_RECEIVE[2];
    }
    
    
    /***
      * @brief  为获得的红外用户码(命令)数据赋予一个数字身份
      * @param  无
      * @retval 收到的用户码的新身份
      */
    uint8_t IR_CommandSymbol(void)
    {
    	unsigned char Num;
    	switch(IR_RECEIVE[2])
    	{
    		case IR_0: Num=0;break;            //0 代表 0键:
    		case IR_1: Num= 1;break;           //1 代表 1键:	
    		case IR_2: Num= 2;break;           //2 代表 2键:
    		case IR_3: Num= 3;break;           //3 代表 3键: 	
    		case IR_4: Num= 4;break;           //4 代表 4键:
    		case IR_5: Num= 5;break;           //5 代表 5键:	
    		case IR_6: Num= 6;break;           //6 代表 6键:
    		case IR_7: Num= 7;break;           //7 代表 7键:
    		case IR_8: Num= 8;break;           //8 代表 8键:
    		case IR_9: Num= 9;break;           //9 代表 9键:
    		case IR_POWER: Num= 11;break;       //11 代表 OnOff键:
    		case IR_MODE:  Num= 12;break;       //12 代表 Mode键:		
    		case IR_MUTE:  Num= 13;break;       //13 代表 Mute键:
    		case IR_START_STOP: Num= 21;break;  //21 代表 Pause键:
    		case IR_PREVIOUS:   Num= 22;break;  //22 代表 Left键:	
    		case IR_NEXT: Num= 23;break;        //23 代表 Right键:
    		case IR_EQ:   Num= 31;break;        //31 代表 EQ键:
    		case IR_VOL_MINUS: Num= 32;break;   //32 代表 VolADD键	
    		case IR_VOL_ADD:   Num= 33;break;   //33 代表 VolDOW键
    		case IR_RPT: Num= 42;break;         //42 代表 RPT键:		
    		case IR_USD: Num= 43;break;			//43 代表 U_SD键:
    		default :break;
    	}
    	return Num;	
    }
    
    
    

    2.1-2、GUA_Infrared_Receiver.h 文件

  • 得到的红外遥控键码(用户码)进行了(十六进制的)宏定义。
  • 而主要利用的是,我将用户码进行了重新的命名,针对不同的按键__相应有代表数字。其由函数:uint8_t IR_CommandSymbol(void) 来实现。
  • 如何利用这些函数,请看主函数。
  • //******************************************************************************              
    //name:             GUA_Infrared_Receiver.h               
    //******************************************************************************    
    #ifndef _GUA_INFRARED_RECEIVER_H_
    #define _GUA_INFRARED_RECEIVER_H_
    
    #include "main.h"
    .............略了一些定义
    .............
    //红外接收引脚
    #define GUA_INFRARED_RECEIVER_PORT               GPIOB
    #define GUA_INFRARED_RECEIVER_PIN                GPIO_Pin_5
    #define GUA_INFRARED_RECEIVER_RCC                RCC_APB2Periph_GPIOB
    
    //中断
    #define GUA_INFRARED_RECEIVER_EXTI_LINE          EXTI_Line5
    #define GUA_INFRARED_RECEIVER_PORTSOURCE         GPIO_PortSourceGPIOB
    #define GUA_INFRARED_RECEIVER_PINSOURCE          GPIO_PinSource5
    
    #define TRUE            0
    #define FALSE           1
    
    #define GUA_INFRARED_RECEIVER_OK                0
    #define GUA_INFRARED_RECEIVER_ERROR             1
    
    /*********************外部变量************************/
    extern GUA_U32 gGUA_InfraredReceiver_Data;          //一个接收红外原始数据的变量(32位)
    
    /********************* 函数声明 ************************/ 
    extern void GUA_Infrared_Receiver_Init(void);
    extern GUA_U8 GUA_Infrared_Receiver_Process(void);
    void Show_Data(void);
    
    
    //**************************************************************
    //》》》》》》》》》》能在主函数里调用的函数《《《《《《《《《《《
    //**************************************************************
    
    uint8_t IR_GetDataFlag(void);     	//  是否按一次	(单发)
    uint8_t IR_GetRepeatFlag(void);   	//	是否为连按	(连发)
    uint8_t IR_GetAddress(void);		// 	地址码
    uint8_t IR_GetUserCode(void);		//	用户码(按键命令)
    uint8_t IR_CommandSymbol(void);   	//	将用户码转换出一个对应的数字身份
    
    //***********************************************************************
    //***********************************************************************
    //从“调试键码的函数”获得相应用户码,并转换位16进制后,对遥控发送的键码(用户码)进行宏定义
    #define IR_POWER		0xA2
    #define IR_MODE			0x62
    #define IR_MUTE			0xE2
    #define IR_START_STOP	0x22
    #define IR_PREVIOUS		0x02
    #define IR_NEXT			0xC2
    #define IR_EQ			0xE0
    #define IR_VOL_MINUS	0xA8
    #define IR_VOL_ADD		0x90
    #define IR_0			0x68
    #define IR_RPT			0x98
    #define IR_USD			0xB0
    #define IR_1			0x30
    #define IR_2			0x18
    #define IR_3			0x7A
    #define IR_4			0x10
    #define IR_5			0x38
    #define IR_6			0x5A
    #define IR_7			0x42
    #define IR_8			0x4A
    #define IR_9			0x52
    
    #endif
    

    2.1-3、main.c 文件

    1. 很显然,IR_GetDataFlag()和 IR_GetRepeatFlag()两个函数是判断是否有接收到红外信号。
    2. IR_GetAddress()和IR_GetUserCode()两个函数就是分别获得红外数据中“地址码”和“用户码”。
    3. IR_CommandSymbol()函数是根据遥控器上按键对“用户码”进行了重新命名定义,就方便于使用与记忆。
    #include "main.h"
    
    uint8_t Num;
    uint8_t Address;
    uint8_t Command;
    uint8_t One_More =1,Command_early;
    uint8_t Information;
    
    void Click_Button_(void);
    void Continuous_Button_(void);
    
    int main(void)
    {
    	OLED_Init();
    	LED_Init();
    	Serial_Init();
    	GUA_Infrared_Receiver_Init(); //红外接收初始化
    	
    	Serial_SendString("\r\n Is OK \r\n");
    	OLED_ShowString(1, 1,"User Add   CMD  ");
    	OLED_ShowString(2, 1,"0000 0000  00   ");
    	LED2_OFF();
    	LED2_OFF();
    	while (1)
    	{
    		if(IR_GetDataFlag())  //若红外单发
    		{
    			LED2_Turn();
    			OLED_ShowNum(2,1,IR_GetUserCode(),4);
    			OLED_ShowNum(2,6,IR_GetAddress(),4);
    			OLED_ShowNum(2,12,IR_CommandSymbol(),2);
    			if(((int )IR_CommandSymbol() >= 0) && ((int )IR_CommandSymbol() <= 9) )
    			{
    				Serial_SendString("\r\n 你按下了——键 ");   // 打印按键0到9
    				Serial_SendNumber(IR_CommandSymbol(),1);
    			}
    			else if(IR_CommandSymbol() == 6)   //当然该判断是不会执行了,因为已经满足了前面一个的判断条件
    			{
    				Serial_SendString("\r\n 你按下的是键“6”");
    			}
    			else if(IR_CommandSymbol() == 11)
    			{
    				Serial_SendString("\r\n 你按了开关键");
    			}
    			else if(IR_CommandSymbol() == 12)
    			{
    				OLED_ShowString(3,1,"  Happy Happy");
    				OLED_ShowString(4,2,"Happy every day");
    			}
    			else if(IR_CommandSymbol() == 22)
    			{
    				Serial_SendString("\r\n 上一曲");
    			}
    			else if(IR_CommandSymbol() == 23)
    			{
    				Serial_SendString("\r\n 下一曲");
    			}
    		}
    		if(IR_GetDataFlag() || IR_GetRepeatFlag()) //若红外单发或连发
    		{
    			if(IR_CommandSymbol() == 32)
    			{
    				Serial_SendString("\r\n 音量- -");
    			}else if(IR_CommandSymbol() == 33)
    			{
    				Serial_SendString("\r\n 音量+ +");
    			}
    		}
    	}
    }
    
    

    效果演示

    红外接收视频演示

    相关参考资料链接

    1、典型的 NEC 协议传输格式:红外遥控原理

    3、该参考程序的原版来源: STM32之红外接收

    物联沃分享整理
    物联沃-IOTWORD物联网 » STM32F103xx红外接收处理与红外技术详解

    发表评论