红外波形分析怎么分析呀?

2020-02-04 09:04发布

   家里的电视机遥控器、音响遥控器等好多的遥控经常不知放到哪里去了,想做一个公用的遥控发射器,买了USBee AX来显示每个遥控器的波形,保存了几十个按键的波形,但是发现一个一个分析还是很困难的,有什么好的分析方法吗?希望各位多加指教。
下面是一个按键的波形:
红外图片.jpg (174.94 KB, 下载次数: 1) 下载附件 2012-4-26 21:40 上传
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
8条回答
mcu_mouse
2020-02-05 03:33
本帖最后由 mcu_mouse 于 2012-4-26 23:37 编辑

/************************* 说 明 *********************************/
/* 以一个9ms的低电平和4.5ms的高电平为引导码,后跟32位二进制代码 */
/* 前16位为8位用户码及其反码,后16位为8位的操作码及其反码 */
/* 以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示"0"; */
/* 以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示"1"。 */
/* 注意:接收码的脉宽与间隔是对发射码取反的,即间隔是0.565ms */
/******************************************************************/
#include <REGX52.h>

#define uchar unsigned char

uchar data IRcode[4];//定义一个4字节的数组用来存储代码
uchar  CodeTemp; //编码字节缓存变量
uchar i,j,k;//延时用的循环变量
sbit IRsignal=P3^2; //HS0038接收头OUT端直接连P3.2(INT0)
sbit LED = P3^5;

/**************************延时0.9ms子程序**********************/
void Delay0_9ms(void)
{
        uchar j,k;
        for(j=18;j>0;j--)
        {       
                for(k=20;k>0;k--)
                ;
        }
}

/***************************延时1ms子程序**********************/
void Delay1ms(void)
{
        uchar i,j;
        for(i=2;i>0;i--)
                for(j=230;j>0;j--)
                ;
}

/***************************延时4.5ms子程序**********************/
void Delay4_5ms(void)
{
        uchar i,j;
        for(i=10;i>0;i--)
                for(j=225;j>0;j--)
                ;
}

/**************************** 延时子程序 ************************/
void Delay(void)
{
        uchar i,j,k;
        for(i=200;i>0;i--)
                for(j=200;j>0;j--)
                        for(k=3;k>0;k--)
                        ;
}

/************************中断0解码服务子程序**********************/
void int0(void) interrupt 0 using 2
{
        EA=0;
        LED = 0;
        for(k=0;k<10;k++)
        {
                Delay0_9ms();
                if (IRsignal==1)//如果0.9ms后IRsignal=1,说明不是引导码
                {
                        k=10;break;
                }
                else
                if(k==9)                 //如果持续了10×0.9ms=9ms的低电平,说明是引导码
                {
                        while(IRsignal==0);
                        Delay4_5ms();                                        //跳过持续4.5ms的高电平
                        for(i=0;i<4;i++)                                 //分别读取4个字节
                        {
                                for(j=1;j<=8;j++)                         //每个字节8个bit的判断
                                {
                                        while(IRsignal==0);                //等待上升沿
                                        Delay0_9ms();                         //从上升沿那一时刻开始延时0.9ms,再判断IRsignal
                                        if(IRsignal==1)                 //如果IRsignal是"1",则向右移入一位"1"
                                        {
                                                Delay1ms();
                                                CodeTemp=CodeTemp|0x80;
                                                if(j<8)
                                                CodeTemp=CodeTemp>>1;
                                        }
                                        else
                                        if(j<8)CodeTemp=CodeTemp>>1;        //如果IRsignal是"0",则向右移一位,自动补"0"
                                }
                        IRcode=CodeTemp;
                        CodeTemp=0;
                        }
                        for(i=0;i<4;i++)         //通过串口将代码发出
                        {
                                SBUF=IRcode;
                                while(!TI);                        //等待一个字节发送完毕
                                TI=0;
                        }
                        Delay();
                }
        }
        EA=1;
        LED = 1;
}

/***********************串口初始化程序*********************/
void initUart(void)
{
        TMOD|=0x20;
        SCON=0x50;
        PCON|=0x80;
        TH1=0xff;        //57600bps @ 11.0592MHz
        TL1=0xff;
        TR1=1;
}

/**************************主程序*************************/
void main()
{
        initUart();
        IT0=1;        //INT0为负边沿触发, (1:负边沿触发,0:低电平触发)
        EX0=1;  //外部中断INT0开, (1:开,????? 0:关??? )
        EA=1;   //开所有中断
        CodeTemp=0; //初始化红外编码字节缓存变量
        Delay();
        while(1);
}


直接用这个程序解码红外遥控了再用串口输出就好了。或者再改成红外学习的,红外学习的话就得再加上38K的载波,
上面的是解NEC码的。再发一个解RC-5码的。自己再稍微修改下就好了。红外接收处理方面肯定是能用的。另外,这2个程序都是用的11.0592的晶振,再声明下,这2个程序都是网上的。
我稍微修改了下来用的。


#include "../Src/INC/STC_NEW_8051.H"  
#include  <stdio.h>
#include "../Src/INC/CONFIG.H"
#include "../Src/LED/LED.H"
#include "../Src/Uart/UART.H"

//==============================================================================
// 定义红外接收的接口(根据实际的硬件接线进行修改)
//==============================================================================
sbit Ir_RECV    = P3^3;    // INT1
//==============================================================================
//
// 状态机的含义:
//
//    状态S0:  初始状态
//    状态S1:  1,1 状态,在两个bit中间触发中断
//    状态S2: 0   状态
//
//    S1->S1: 1个周期
//    S1->S2: 1.5个周期
//    S2->S2: 1个周期或2个周期
//    S2->S1: 1.5个周期
//
//==============================================================================

//==============================================================================
// 时间常数(使用晶震频率为11.0592MHz)
//==============================================================================*/

#define CYCLE_1_0        0x65B    // 1776us
#define CYCLE_1_5        0x989    // 2664us
#define CYCLE_2_0        0x0CB7    // 3552us
#define TH_CYCLE_1_0    (CYCLE_1_0>>8)   //提取定时器高8位值
#define TH_CYCLE_1_5    (CYCLE_1_5>>8)
#define TH_CYCLE_2_0    (CYCLE_2_0>>8)

// 用于解码的变量
u16  nIrRecvCode=0xFFFF;        // 保存解码数值(1个开始位 1个控制位 5个地址位 6个命令位)
u8 nIrBitCount=0;        // 记录已经解码的位数
u8 nIrState=0;        // 初始状态
u8 nBuffer;

bit g_bIrOK = 0;

// 初始化中断及定时器
void IrInit()
{   
    // 定时器0
    TMOD |= 0x01;    // T0工作于方式1,即16位定时器
    ET0 = 0;        // 关定时器0中断允许
    TR0 = 0;        // 关闭定时器0
    TH0 = 0;
    TL0 = 0;
    AUXR = 0x00;
    // 外部中断源INT0
    EX1 = 1;        // 允许外部中断源INT1
    PX1 = 1;        // 外部中断源为高优先级
    IT1 = 1;        // 边缘触发
     
// 允许中断
    EA=1;
}



// 处理红外命令
void IrProcessCommand(int remotecode)
{
        nBuffer=(u8)(remotecode&0xFF);
//    speaData(nBuffer,2);           //我的自定义拆字子程序,提供给LCD1602显示
}

// 外部中断0的处理函数   SAA_3010T 解码程序
void IrInt1(void) interrupt 2  
{
    // 保存计数器的高位,作为判断周期长短的依据
    u8 HighTick = TH0;   
     
    // 重置计数器
    TH0 = 0;TL0 = 0;TR0 = 1;ET0 = 1;      
    // 状态转移图
    switch( nIrState )
    {
            case 0: // 第一个起始位                 
                nIrBitCount = 1;
                             
                nIrRecvCode = 0;

                        nIrState = 2;  
                break;
            case 1: // 状态1
                if(HighTick == TH_CYCLE_1_0) // S1->S1  (持续位1状态)
                {
                    nIrState = 1;
                    nIrBitCount++;
                    nIrRecvCode = nIrRecvCode<<1;
                    nIrRecvCode = nIrRecvCode+1;
                }
                else if(HighTick == TH_CYCLE_1_5) // S1->S2 ( 1,1,0 )  转到位0状态
                {
                    nIrState = 2;
                    nIrBitCount = nIrBitCount+2;
                    nIrRecvCode = nIrRecvCode<<1;
                    nIrRecvCode = nIrRecvCode+1;
                    nIrRecvCode = nIrRecvCode<<1;
                }
                else // 错误状态
                {
                    nIrBitCount = 0;
                    nIrState = 0;
                }
                break;
            case 2: // 状态2
                if(HighTick == TH_CYCLE_1_0) // S2->S2(持续位0状态)
                {
                    nIrState = 2;
                    nIrBitCount++;
                    nIrRecvCode = nIrRecvCode<<1;
                }
                else if(HighTick == TH_CYCLE_1_5) // S2->S1(转到位1状态)
                {
                    nIrState = 1;
                    nIrBitCount++;
                    nIrRecvCode = nIrRecvCode<<1;
                    nIrRecvCode = nIrRecvCode+1;
                }
                else if(HighTick == TH_CYCLE_2_0) // S2->S2
                {
                    // 0->1->0
                    nIrState = 2;
                    nIrBitCount = nIrBitCount+2;
                    nIrRecvCode = nIrRecvCode<<1;
                    nIrRecvCode = nIrRecvCode+1;
                    nIrRecvCode = nIrRecvCode<<1;
                }
                else // 错误状态
                {
                    nIrBitCount = 0;
                    nIrState = 0;
                }
                break;
                default:break;
    }
}

// 定时器T0的中断处理函数
void IrTimer0(void) interrupt 1
{
    ET0 = 0;        // 关定时器0中断允许
    TR0 = 0;        // 关闭定时器0

    // 出现了超时
    if( nIrBitCount == 13 )
    {
        if((nIrState == 1)||(nIrState == 2))   // 0,1
        {
            nIrBitCount ++;
            nIrRecvCode = nIrRecvCode<<1;
            nIrRecvCode = nIrRecvCode+1;
        }
    }
  
    // 检查是否有合理数据
    if( nIrBitCount == 14 )
    {                        
        // 停止中断0
        EX0 = 0;         
        // 处理遥控命令
        IrProcessCommand(~nIrRecvCode);//&0x0FFF);
     
       // 重新初始化初始化
       nIrBitCount = 0;
       nIrState = 0;
            
           g_bIrOK = 1;
//           Display(28,0);  
    }         
    // 启用中断
    EX0 = 1;
}


void KeyProcess()
{
        static u8 ncomp ;
                if(g_bIrOK == 1)
                {                               
                        u8 bdata temp[3];
                       
                        temp[2] = ( (~nIrRecvCode)) & 0x3F;
                        temp[1] = ( (~nIrRecvCode)>>6) & 0x1F;
                        temp[0]        = ( (~nIrRecvCode)>>11) & 0x07;
                       
                        if(ncomp != temp[0])
                        {
                                switch(temp[2])
                                {
                                       
                                        case 0x17:                                                //夜间        0x17
//                                                                Display(temp[2]);
//                                                                WByte(temp[2]);
                                                                break;

                                        case 0x11:                                                //演习        0x11
                                                               
                                                                break;

                                        case 0x14:                                                //保护        0x14
                                                               
                                                                break;

                                        case 0x15:                                                //校枪        0x15       
                                                               
                                                                break;

                                        case 0x12:                                                //时间        0x12       
                                                               
                                                                break;

                                        case 0x10:                                                //弹夹数        0x10       
                                                               
                                                                break;

                                        case 0x13:                                                //编号        0x13       
                                                               
                                                                break;

                                        case 0x16:                                                //设置        0x16       
                                                               
                                                                break;

                                        case 0x3A:                                                //命值        0x3A       
                                                               
                                                                break;

                                        case 0x32:                                                //1        0x32       
                                                               
                                                                break;

                                        case 0x2A:                                                //2        0x2A       
                                                               
                                                                break;

                                        case 0x22:                                                //3        0x22       
                                                               
                                                                break;

                                        case 0x39:                                                //频点        0x39       
                                                               
                                                                break;

                                        case 0x31:                                                //4        0x31       
                                                               
                                                                break;

                                        case 0x29:                                                //5        0x29       
                                                               
                                                                break;

                                        case 0x21:                                                //6        0x21       
                                                               
                                                                break;

                                        case 0x38:                                                //VIP        0x38       
                                                               
                                                                break;

                                        case 0x30:                                                //7        0x30       
                                                               
                                                                break;

                                        case 0x28:                                                //8        0x28       
                                                               
                                                                break;

                                        case 0x20:                                                //9        0x20       
                                                               
                                                                break;

                                        case 0x35:                                                //0        0x35       
                                                               
                                                                break;

                                        case 0x3F:                                                //分组        0x3F       
                                                               
                                                                break;

                                        case 0x3D:                                                //清除        0x3D       
                                                               
                                                                break;

                                        case 0x27:                                                //确认        0x27       
                                                               
                                                                break;

                                        case 0x37:                                                //A        0x37       
                                                               
                                                                break;

                                        case 0x3C:                                                //B        0x3C       
                                                               
                                                                break;

                                        case 0x34:                                                //C        0x34       
                                                               
                                                                break;
                                        case 0x26:                                                //D        0x26       
                                                               
                                                                break;
                                        default:    break;
                                }
                                ncomp = temp[0];                       
                               
                        }
                        g_bIrOK = 0;
                }
}

一周热门 更多>