NEC遥控信号解码(包含完整代码)

时间:2021-03-31 06:35:03

一、遥控器解码说明

1、遥控器的编码格式常见有两种,一种是NEC 格式,一种是RC5 格式。遥控器发出的信号,通过一个红外的接收头之后,信号被送到MCU 的一个中断引脚。通过MCU 来识别不同的时序,来实现遥控器按键信号的解码。

2、遥控器时序图及数据格式(NEC 格式)

数据格式:

NEC遥控信号解码(包含完整代码)

遥控器发送的数据码由以下部分组成:引导码,8位的客户码,8位客户码的补码,8位的按键值,8位按键值的补码

具体的时序:

单次按键时的时序:

NEC遥控信号解码(包含完整代码)

注: 一个完整的周期是108 ms

连续按键时的时续:

NEC遥控信号解码(包含完整代码)

在单次按键的时序之后,紧跟如下时序:(周期也是108ms)

二、软件设计思想及处理函数

根据遥控器信号时序的特点,在设计软件时,需要利用时序,首先找到引导区,再读取客户码(可以一次读取16位),识别是否为厂家所制定的数值;之后读取8位的按键值,并将读取到的数据保存起来

需要定义的在遥控器解码过程中用到的状态值:

#define         IR_STATE_IDLE                0x00
#define         IR_STATE_LEAD_ON             0x01
#define         IR_STATE_LEAD_OFF            0x02
#define         IR_STATE_CUSTOM              0x03
#define         IR_STATE_DATA1               0x04
#define         IR_STATE_DATA2               0x05

同时定义一下描述高低电平持续时间的一个常量

#define      IR_R_Max                         40
#define      IR_R_Min                         30

#define      IR_H_Max                         40
#define      IR_H_Min                         30

#define      IR_L_Max                         20
#define      IR_L_Min                         15

定义以下变量:

static unsigned char IrState ;
static unsigned char IrData;
static unsigned short IrCustom; 

解码的过程如下:遥控器的解码是在中断处理函数中完成的,当MCU 的中断引脚发生电平变化时,会引发中断;

void interrupt NEC_IR(void)

{

-------------------------------------

NEC遥控器中断处理

------------------------------------

}

关于RC5 格式的遥控器解码

RC5 格式的遥控器除了时序和NEC格式的遥控器有一点差别之外,软件的解码过程基本类似,不再单独描述。

三、遥控器信号解码的流程

NEC遥控信号解码(包含完整代码)

四、实现的代码(基于PIC芯片)

//----------------------------------------------------------------------------
// Function Name: NEC_IR
// Description:IR interrupt manage
// Params: None
// Returns: None
// Notes: SYS INT service process
//----------------------------------------------------------------------------
void interrupt NEC_IR(void)
{
    unsigned char t0;
    //here first things to disable the interupt!
    GIE=;
    //IR Intrupt input here.
    //preamble=9ms" --|__|--" + 4.5ms"_|--|_",others Data high 2.25ms and low 1.25ms;
    //Data =" --|__|--" + "_|--|_" high 2.25ms and low 1.25ms.
    //Repeat==9ms" --|__|--" + 2.25 ms"_|--|_".
    if(INTF)
    {
        t0 = TMR0;
        TMR0 = ;
        switch (IrState)
        {
            case IR_STATE_IDLE:
                INTEDG = ;//Rising edge trigger
                IrState = IR_STATE_LEAD_ON;
                break;
            case IR_STATE_LEAD_ON:
                INTEDG = ;//Falling edge trigger
                if((t0 > Pream_L_Min) && (t0 < Pream_L_Max))
                {
                    IrState = IR_STATE_LEAD_OFF;
                }
                else
                {
                    IrState = IR_STATE_IDLE;
                }
                break;
            case IR_STATE_LEAD_OFF:
                if ((t0 > Pream_S_Min) && (t0 < Pream_S_Max))
                {
                    IrState = IR_STATE_CUSTOM;
                    IrCustom = ;
                    BitCounter = ;
                    Repeat = ;
                }
                else
                {
                    if ((t0 > IR_R_Min) && (t0 < IR_R_Max))
                    {
                        if ((Repeat)&&(SystemState == POWER_ON_STATE))
                        {
                            Repeat = ;//IR key Repeat
                        }
                    }
                    else
                    {
                        Repeat = ;
                    }

                    INTEDG = ;
                    IrState = IR_STATE_IDLE;
                }
                break;
            case IR_STATE_CUSTOM:
                if ((t0 > IR_L_Min) && (t0 < IR_L_Max))
                {
                    IrCustom >>= ;
                }
                else
                {
                    if ((t0 > IR_H_Min) && (t0 < IR_H_Max))
                    {
                        IrCustom = ((IrCustom >> ) | 0x8000);
                    }
                    else
                    {
                        INTEDG = ;
                        IrState = IR_STATE_IDLE;
                        Repeat = ;
                        break;
                    }
                }

                )
                {
                    if (IrCustom != CustomCode)
                    {
                        INTEDG = ;
                        IrState = IR_STATE_IDLE;
                        Repeat = ;
                        break;
                    }
                    IrState = IR_STATE_DATA1;
                    BitCounter = ;
                    IrKeyCode = ;
                }
                break;
            case IR_STATE_DATA1:
                BitCounter++;
                if ((t0 > IR_L_Min) && (t0 < IR_L_Max))
                {
                    IrKeyCode >>= ;
                }
                else
                {
                    if ((t0 > IR_H_Min) && (t0 < IR_H_Max))
                    {
                        IrKeyCode = ((IrKeyCode >> ) | 0x80);
                    }
                    else
                    {
                        INTEDG = ;
                        IrState = IR_STATE_IDLE;
                        Repeat = ;
                        break;
                    }
                }
                )
                {
                    IrState = IR_STATE_DATA2;
                    BitCounter = ;
                    IrData = ;
                }
                break;
            case IR_STATE_DATA2:
                BitCounter++;
                if ((t0 > IR_L_Min) && (t0 < IR_L_Max))
                {
                    IrData >>= ;
                }
                else
                {
                    if ((t0 > IR_H_Min) && (t0 < IR_H_Max))
                    {
                        IrData = ((IrData >> ) | 0x80);
                    }
                    else
                    {
                        INTEDG = ;
                        IrState = IR_STATE_IDLE;
                        Repeat = ;
                        break;
                    }
                }
                )
                {
                    INTEDG = ;
                    IrState = IR_STATE_IDLE;
                    IrData = ~IrData;
                    if (IrKeyCode == IrData)
                    {
                                                    // Check if data is valid
                    }
                    else
                    {
                        Repeat = ;
                    }
                }
                break;
        }
        INTF=;
    }
    GIE=;
}