红外遥控器的解码

2020-01-22 12:01发布

红外遥控器的解码
实测距离10米时不会错误或需要重复按遥控器 (*^__^*) ……


接收头 (原文件名:接收头.jpg.jpg)


正确解码 (原文件名:20110103426.jpg)
第一行显示的是:地址码+地址码+操作码+操作码反码  接受数据正确时第二行显示OK  旁边的数字是连_发次数


错误解码 (原文件名:20110103427.jpg)
第一行显示的是:地址码+地址码+操作码+操作码反码  接受数据错误时第二行显示error  旁边的数字是连_发次数


51开发板配的万能遥控器 (原文件名:20110103428.jpg)
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
97条回答
qq335702318
1楼-- · 2020-01-25 01:37
回复【24楼】tyqhaha
-----------------------------------------------------------------------

51单片机啊
beijisnow
2楼-- · 2020-01-25 05:48
楼主帮忙看看我改写的Sony SIRC解码  看是否有问题呀。

SONY SIRC参考:
http://davidallmon.com/sirc/sirc.php
http://www.8051projects.net/out.php?link=http://sbprojects.com/knowledge/ir/sirc.htm


#include <reg51.h>
/******************************************************************/
/*                     函 数 声 明                                */
/******************************************************************/
void Timer0init(void);     //定时器0初始化
void EX0init(void);        //外部中断初始化
void Decode(void);         //解码子程序
/******************************************************************/
/*                     宏  定  义  区                             */
/*  由于遥控器和程序存在一定误差,必须允许编码时长有一定的范围    */
/*  以下定义了时长和范围以及本机地址。用于调试                    */
/******************************************************************/
#define Guide_timer 22              //引导码最短时长
#define IR_L_timer_min 10           //数据0 最短时长
#define IR_L_timer_max 14           //数据0 最长时长
#define IR_H_timer_min 16           //数据1 最短时长
#define IR_H_timer_max 20           //数据1 最长时长
#define TIMER0_COUNT 0x9c           //定时器定时时间 100us
#define Timeout_cnt 240             //超时时长
/******************************************************************/
/*                    变  量  保  存  区                          */
/******************************************************************/
static unsigned char Timer0_cnt;            //定时器计数值
static unsigned char Timer0_cnt_bk;
static bit timeout;                         //超时标志
static bit Guide;                           //引导码有效
static unsigned char IR_time[13];           //保存每两个下降沿之间的时间间隔
static unsigned int  IR_12bit;
static unsigned char IR_Command;            //7bit命令  保存一次解码后接受到的数据
static unsigned char IR_Address;             //5bit地址  保存一次解码后接受到的数据
static unsigned char IR_Newkey;
/************ 编解码说明 ***************
引导码:2.4ms低电平+ 0.6ms高电平
数据0:0.6ms低电平+0.6ms高电平
数据1:1.2ms低电平+0.6ms高电平
*****************************************/
/******************************************************************/
/*                   红 外 遥 控 解 码                            */
/* CPU & XTAL :51   @ 12Mhz                                     */
/* 支持的红外编码方案: Sony                                     */
/* 编码格式:引导信号 + 7bit command + 5bit address              */
/******************************************************************/
/******************************************************************/
/*                   定时器0初始化                                */
/*                   定时值:100us                                */
/*                   方式2 自动重载                               */
/******************************************************************/
void Timer0init(void)//定时器0初始化
{
    //定时值 100us
    TMOD=0x02;             //定时器0工作方式2 自动重载
    TH0=TIMER0_COUNT;      //重载值
    TL0=TIMER0_COUNT;      //初始化值
    ET0=1;                 //定时器0中断有效
    TR0=1;                 //定时开始
}
/******************************************************************/
/*                   外部中断初始化                               */
/*                   中断端口:外部中断0 P3.2                     */
/*                   触发方式:下降沿                             */
/******************************************************************/
void EX0init(void)
{
    EA = 1;    //总中断开
    IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
    EX0 = 1;   //外部中断有效
}
/******************************************************************/
/*                   Timer0中断子程序                             */
/******************************************************************/
void Timer0(void) interrupt 1 using 1
{
    Timer0_cnt++;
    if(Timer0_cnt>Timeout_cnt)
    {
        timeout=1;    //超时标志
    }
}
/******************************************************************/
/*                    外部中断0函数                               */
/* 下降沿触发                                                     */
/******************************************************************/
void ex0_isr (void) interrupt 0 using 0
{
    static unsigned char m=0;
    Timer0_cnt_bk=Timer0_cnt; //备份时间计数值,即前一个下降沿到本下降沿的时间间隔
    Timer0_cnt=0x00;          //清空时间计数值
    if(timeout)               //如果超时
    {
        TL0=TIMER0_COUNT;    //初始化定时器0
        Timer0_cnt=0x00;     //清空时间计数值
        timeout=0;           //清除超时标志
        Guide=0;             //清除引导标志
        m=0;                 //复位数据位
    }
    else
    {
        if(Guide)                           //如果引导码有效
        {
            IR_time[m++]=Timer0_cnt_bk;    //保存时间间隔
            if(m==12)                      //接收够12bit数据后
            {
                m=0;
                Guide=0;                    //清除引导标志
                Decode();                   //解码
            };
        };
        if(Timer0_cnt_bk>Guide_timer)    //如果时间间隔>引导码时长
        {
            Guide=1;                       //使能引导标志
            m=0;
        };
    };
}
/******************************************************************/
/*                       解码子程序                               */
/******************************************************************/
void Decode(void)
{
    unsigned char bitcounter,timecounter=0x00;
    EX0 = 0;   //外部中断无效
    for(bitcounter=12; bitcounter>0; bitcounter--)
    {
        {
            if((IR_time[timecounter]>IR_L_timer_min)&(IR_time[timecounter]<IR_L_timer_max))//数据"0" 0.6ms低电平+0.6ms高电平
            {
                IR_12bit>>=1;
                IR_12bit&=0x7f;
            }
            else if((IR_time[timecounter]>IR_H_timer_min)&(IR_time[timecounter]<IR_H_timer_max)) //数据"1" 1.2ms低电平+0.6ms高电平
            {
                IR_12bit>>=1;
                IR_12bit|=0x80;
            }
            timecounter++;
        }
    }
    IR_12bit>>=4;                               //再右移4位 使command低位对齐
    IR_Command=(char)IR_12bit&0x7f;    //保留低7位
    IR_12bit>>=7;                               //再右移7位 使address低位对齐
    IR_Address=(char)IR_12bit&0x1f;    //保留低5位
    if(IR_Address==0x01)          //地址码=1
    {
        IR_Newkey=1;
    }
    EX0 = 1;              //重新开放外部中断
}
/******************************************************************/
/*                    键 处 理 函 数                              */
/* 正确接收数据并解码时被中断程序调用                             */
/* 按键处理函数结束前外部中断不开放                               */
/* 此处保存按键处理函数,键值在于结构体IR_data                    */
/******************************************************************/
void main()
{
    Timer0init();//定时器0初始化
    EX0init();   //外部中断初始化
    while(1)
    {
        ;
    }
}
beijisnow
3楼-- · 2020-01-25 07:36
发现bug  改了一下

void Decode(void)
{
    unsigned char bitcounter,timecounter=0x00;
    EX0 = 0;   //外部中断无效
    for(bitcounter=12; bitcounter>0; bitcounter--)
    {
        {
            if((IR_time[timecounter]>IR_L_timer_min)&(IR_time[timecounter]<IR_L_timer_max))      //数据"0" 0.6ms低电平+0.6ms高电平
            {
                IR_12bit>>=1;
                IR_12bit&=0xf7ff;  //16位int数的第12位置0
            }
            else if((IR_time[timecounter]>IR_H_timer_min)&(IR_time[timecounter]<IR_H_timer_max)) //数据"1" 1.2ms低电平+0.6ms高电平
            {
                IR_12bit>>=1;
                IR_12bit|=0x800;  //16位int数的第12位置1
            }
            timecounter++;
        }
    }
    IR_Command=(char)IR_12bit&0x7f;    //保留低7位
    IR_12bit>>=7;                      //再右移7位 使address低位对齐
    IR_Address=(char)IR_12bit&0x1f;    //保留低5位
    if(IR_Address==0x01)               //地址码=1
    {
        IR_Newkey=1;
    }
    EX0 = 1;              //重新开放外部中断
}
fedora10
4楼-- · 2020-01-25 07:46
 精彩回答 2  元偷偷看……
hmzwm
5楼-- · 2020-01-25 11:57
谢谢楼主,下载了,调试通过!
zd305
6楼-- · 2020-01-25 15:25
mark!!!

一周热门 更多>