搜索
bottom↓
回复: 20

基于uPD6121/LC7461M/HT6222/AS6122等红外编码芯片的解码程序(ATmega16)

[复制链接]

出0入0汤圆

发表于 2005-11-5 13:01:40 | 显示全部楼层 |阅读模式
/*----------基于uPD6121/LC7461M/HT6222/AS6122等红外编码芯片的解码程序------------

            作者:Benny

            Blog:http://bennylo.mcublog.com/

            Email:89S53@163.com

            MCU: ATmega16

            Crystal: 6.0000Mhz

*/

#include <iom16v.h>

#include <macros.h>

#define uint unsigned int

#define uchar unsigned char  

#define ulong unsigned long

/*------------------------------显示-----------------------------------*/

#define LED_DATA PORTB

const uchar tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};

/*

                     0    1    2    3    4    5    6    7    8    9    A    B    C    D    E    F   

*/

void delay(void){

    uint i;

    for(i=0;i<2000;i++);

}

void dis_int(uint dis_data)

{    //四位共阴数码管,十六进制显示

     LED_DATA=tab[(uchar)((dis_data&0xf000)>>12)];   //显示千位

     PORTD=0xf7;               

     delay();                                       //延时

  

     LED_DATA=tab[(uchar)((dis_data&0x0f00)>>8)];   //显示百位

     PORTD=0xfb;

     delay();                                       //延时

                          

     LED_DATA=tab[(uchar)(dis_data&0x00f0)>>4];     //显示十位

     PORTD=0xfd;

     delay();                                        //延时

     

     LED_DATA=tab[(uchar)dis_data&0x000f];           //显示个位

     PORTD=0xfe;

     delay();                                      //延时

}

void port_init(void)

{

PORTA = 0xFF;

DDRA  = 0x00;

PORTB = 0xFF;

DDRB  = 0xFF;

PORTC = 0xFF;

DDRC  = 0xFF;

PORTD = 0xFF;

DDRD  = 0x0F;

}

void timer1_init(void)

{

TCCR1B = 0x00; //stop

TCNT1H = 0x00; //setup

TCNT1L = 0x00;

ICR1H  = 0x00;

ICR1L  = 0x08;

TCCR1A = 0x00;

/*一体化接收头的DATA引脚接到ATmega16的PD6(ICP1)引脚,采用上升沿捕捉的方法解码*/

/*晶振为6M,无分频,用8M太大(分频则太小)*/

TCCR1B = 0x41; //start Timer

}

uint arr[16];//保存捕捉值

uchar times;//记录捕捉次数

uchar index;//数组索引

uchar ir_code;//红外遥控键码

uchar OK_flag;//解码完毕标志

/*------------------------------------------------------------------------------

模块名称:PD6(ICP1)引脚上升沿捕捉中断程序

影响:    将捕捉值保存在arr[16]中

    ___           ___

   |   |         |   |

___|   |_________|   |__________

   |<-----t----->|

                   DEC                  HEX  

t=9ms          计数值=54000          0xD2F0

t=4.5ms        计数值=27000          0x6978

t=2.25ms       计数值=13500          0x34BC

t=1.125ms      计数值=6750           0x1A5E



------------------------------------------------------------------------------*/

#pragma interrupt_handler timer1_capt_isr:6

void timer1_capt_isr(void)

{   

    uint value;

    value=ICR1L;   

    //CLI();               

    value|=(uint)(ICR1H << 8);

    TCNT1H = 0x00;

    TCNT1L = 0x00;

    times++;  

    if(times>18&&times<35){

      //从第19个上升沿开始保存,直到第34个,短按时共有36个上升沿

      arr[index]=value;       

      index++;  

    }

    else if(times>=35){

        //第35个上升沿到来时,解码完毕  

       times=0;

       index=0;

       OK_flag=1;

    }

    //SEI();

}

/*------------------------------解码程序----------------------------------------

结果:得到uchar型的键码ir_code,如果解码出错,则ir_code=0xff

-----------------------------------------------------------------------------*/

void get_code(void){

        uchar i,dat,/*键码*/_dat;/*键码反码*/

        uint temp=0;

        for(i=0;i<16;i++){

           if(arr<7000){

             //“0”

             temp<<=1;

           }

           if(arr>13000){

             //“1”

             temp<<=1;

             temp|=1;                                   

           }                     

        }

        _dat=(uchar)(temp&0x00ff);/*键码*/       

        dat=(uchar)((temp>>8)&0x00ff);/*键码反码*/

           /*“键码”与“键码反码相与,如果为0则解码正确*/               

        if((dat&_dat)==0){

           ir_code=dat;

            }

        else{

           TCNT1H = 0x00;

           TCNT1L = 0x00;

           ir_code=0xff;//解码出错

            }       

        times=0;

        index=0;

}

void init_devices(void)

{

CLI();

port_init();

timer1_init();

MCUCR = 0x00;

GICR  = 0x00;

TIMSK = 0x20;

SEI();

}

void main(void){

uchar i;

init_devices();



while(1){



            if (OK_flag){

               get_code();//解码

               OK_flag=0;                       

                    }

            for(i=0;i<200;i++){

              dis_int(ir_code);//显示键码                       

            }                       



      }

}

阿莫论坛20周年了!感谢大家的支持与爱护!!

一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。

出0入0汤圆

发表于 2005-11-5 16:53:45 | 显示全部楼层
验证过的吗?

谢谢!

出0入0汤圆

 楼主| 发表于 2005-11-6 08:25:10 | 显示全部楼层
不废话吗!!不通过能放上来??

出0入0汤圆

发表于 2005-12-13 21:45:09 | 显示全部楼层
你这个是用ICC写的吗?我想用GCC把它移植到ATmega8上。

现在我有三个问题:

1、为什么是从第19个上升沿开始保存,我看了HT6221/HT6222的datasheet,不是应该从第17个上升沿开始保存的吗?(header code 9ms 有一个上升沿, off code 4.5ms没有上升沿,接着16个地址码有16个上升沿,所以总共17个上升沿。不知道我这种算法对不对)

2、对连_发的应该怎样处理?

3、最后就是关于所谓的double-key该怎样处理?

出0入0汤圆

发表于 2006-7-3 12:17:19 | 显示全部楼层
我有一个是uPD6600 743

的不知道它的解码和uPD6121有什么不同的地方是不是一样的

请指教!

谢谢了

我找不资料!

出0入0汤圆

发表于 2006-7-3 12:21:52 | 显示全部楼层
我的摇控上的

苡片一写有!

NEC JAPAN

D6600 743

9309A3004

哪位有它的资料请说给我谢谢了

不知道它和uPD6121的解码方式一样不!

出0入0汤圆

发表于 2006-7-24 12:27:53 | 显示全部楼层
go0d

出0入0汤圆

发表于 2006-8-23 18:39:48 | 显示全部楼层
楼主程序今测试了下:

  主要有两点改动



用M64,T3,晶体7.3728 ,GCC 20040214



1

void timer1_init(void)

{

TCCR3B = 0x00; //stop

TCNT3H = 0x00; //setup

TCNT3L = 0x00;

ICR3H  = 0x00;

ICR3L  = 0x08;

TCCR3A = 0x00;

/*一体化接收头的DATA引脚接到ATmega64的PE7(ICP3)引脚,采用上升沿捕捉的方法解码*/

/*晶振为7.3728M,8分频*/

TCCR1B = 0xC2; //start Timer @@@@@@@@@@@@@@@@@@@@@@@@@@@改动

}

2





SING(XXXXXXXXXXXXXXX)

{   

    uint value;

    value=ICR3L;                    

    value|=(uint)(ICR3H << 8);  

    TCNT3H = 0x00;  

    TCNT3L = 0x00;  

    times++;   

    if(times>18)&&(times<35){

      //从第19个上升沿开始保存,直到第34个,短按时共有36个上升沿

      arr[index]=value;   

      index++;   

    }

@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@改动

  else if(times>35)@@@@@@@@@@@@@@@@@@@@@@@@@@@@@改动



//else if(times>=35) //用此语句时第二个键值的第一位被上一键值的第36个脉冲复用,

{

        //第35个上升沿到来时,解码完毕   

       times=0;

       index=0;

       OK_flag=1;

    }

}




-----此内容被9810956于2006-08-23,18:42:57编辑过

出0入0汤圆

发表于 2008-5-29 17:06:12 | 显示全部楼层
找的就是这一个,好辛苦啊,太感谢了

出0入0汤圆

发表于 2008-5-29 17:06:15 | 显示全部楼层
找的就是这一个,好辛苦啊,太感谢了

出0入0汤圆

发表于 2008-9-7 15:04:48 | 显示全部楼层
哈哈!太感谢楼主了!开始试验了很多次都不成功!后来网上说并一个4.7uf到10uf左右的电解电容并完后果真就好了!http://blog.ednchina.com/zl0801/13754/message.aspx

出0入0汤圆

发表于 2009-12-18 12:40:29 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-3-22 15:58:39 | 显示全部楼层
MARK

出0入0汤圆

发表于 2010-4-14 00:23:38 | 显示全部楼层
支持一下

出0入0汤圆

发表于 2010-5-25 16:20:11 | 显示全部楼层
标记

出0入0汤圆

发表于 2011-2-28 07:42:09 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-6-22 13:24:14 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-30 16:55:22 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-8-30 22:51:24 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-9-26 21:51:46 | 显示全部楼层
mark

出0入0汤圆

发表于 2012-1-31 14:51:31 | 显示全部楼层
红外解码,MARK.
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-12 10:48

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表