找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3224|回复: 16
打印 上一主题 下一主题
收起左侧

大家晚上好,这个是我写的红外接收程序,调了很久都没调出来,帮忙看看

[复制链接]
跳转到指定楼层
楼主
ID:89646 发表于 2015-9-12 20:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

/*说明:使用的是HS0038红外接收头                                                          */
/*功能:实现红外接收,接收到的键值码于数码管显示                  */
/*思路:检测外部中断下降沿的时间,来翻译红外信号                        */
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
#define DataProt P0

sbit IR = P3^2;
sbit du = P2^6;
sbit we = P2^7;

uchar IRtime;                //存储低电平到下一个低电平持续的时间
bit IR_ok;                        //标志着已经存好了全部IRtime
bit IR_receive_ok;        //标志着接收好了键值码

uchar IRcord[4];        //存储键值码
uchar IRdata[33];        //存储数据码和用户码
uchar code leddata[]={
//0                1         2     3     4     5     6     7     8
0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F,
//9     A     B           C         D           E         F                -         .          关显示
0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71, 0x40, 0x80, 0x00
                   };

void IR_init()
{
        TMOD = 0x02;        //8位可自动装载定时器
        TH0 = 0x00;
        TL0 = 0x00;
        EA = 1;
        ET0 = 1;
        TR0 = 1;

/*        EX0 = 1;
        IT0 = 1;                //下降沿触发式中断                */
        IT0 = 1;
        EX0 = 1;
}



void IRcordpro()        //【键值码获取】将IRdata[k]里的时间数据 翻译为 用户码和用户码
{
        uchar i,j,k,dat,value;
        k = 1;                //IRdata[0]是起始位。所以k = 1:33 共32个数
        for(i = 0;i < 4;i++)
        {
                for(j = 0 ;j < 8;j++)
                {
                        dat = IRdata[k];
                        value >>= 1;
                        if(dat > 5)
                                value |= 0x80;        //先接收低位
                        k++;
                }
                IRcord[i] = value;                //将用户码和数据码保存于数组中去
                value = 0;                                //置0,以便下次用
        }
        IR_receive_ok = 1;                        //表示已经把键值码取完了
}

void IRwork()
{
        switch(IRcord[2])
        {
                case 0x45:        DataProt = leddata[10];        break;       
                case 0x46:        DataProt = leddata[11];        break;       
                case 0x47:        DataProt = leddata[12];        break;       
                case 0x44:        DataProt = leddata[13];        break;       
                case 0x40:        DataProt = leddata[14];        break;       
                case 0x43:        DataProt = leddata[15];        break;       
                case 0x07:        DataProt = leddata[16];        break;       
                case 0x15:        DataProt = leddata[17];        break;       
                case 0x09:        DataProt = 0x70;                break;       
                case 0x16:        DataProt = leddata[0];        break;       
                case 0x19:        DataProt = 0x49;                break;       
                case 0x0d:        DataProt = 0x38;                break;       
                case 0x0c:        DataProt = leddata[1];        break;       
                case 0x18:        DataProt = leddata[2];        break;       
                case 0x5e:        DataProt = leddata[3];        break;       
                case 0x08:        DataProt = leddata[4];        break;       
                case 0x1c:        DataProt = leddata[5];        break;       
                case 0x5a:        DataProt = leddata[6];        break;       
                case 0x42:        DataProt = leddata[7];        break;       
                case 0x52:        DataProt = leddata[8];        break;       
                case 0x4a:        DataProt = leddata[9];        break;
                default: break;
        }
        IR_receive_ok = 0;                        //表示已经把键值码转换完了
}

void main()
{
        IR_init();
        DataProt = 0xff;
        we = 1;
        DataProt = 0xfe;
        we = 0;
        du = 1;
        while(1)
        {
/*                if(IR_ok)
                {
                        IRcordpro();
                        IR_ok = 0;
                        if(IR_receive_ok)
                        {
                                IRwork();       
                        }
                } */
                if(IR_ok)
                {
                        IRcordpro();
                        IR_ok = 0;
                }
                if(IR_receive_ok)
                {
                        IRwork();       
                }
        }
}

void timer0()interrupt 1
{
        IRtime++;                //277us加一次
}

void int0()interrupt 0
{

        static uchar i = 0;
//        static bit start_flag = 0;
        static start_flag = 0;
        if(start_flag)
        {
                if((IRtime > 47) && (IRtime < 50))                //如果IRtime处于(13053us:13053us),表示接收到起始信号
                        i = 0;
                IRdata[i] = IRtime;
                i++;
                if(i == 33)                //已经接收完了
                {
                        IR_ok = 1;
                        i = 0;
                }       
        }
        else
        {
                start_flag = 1;
                IRtime = 0;
        }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:72947 发表于 2015-9-14 22:06 来自手机 | 只看该作者
可以参考我的贴……
学习型红外遥控8路输出端http://www.51hei.com/bbs/dpj-34267-1.html
回复

使用道具 举报

板凳
ID:90614 发表于 2015-9-20 14:36 | 只看该作者
看过了不懂
回复

使用道具 举报

地板
ID:89646 发表于 2015-9-20 15:28 | 只看该作者
qq704661078 发表于 2015-9-14 22:06
可以参考我的贴……
学习型红外遥控8路输出端http://www.51hei.com/bbs/dpj-34267-1.html

不懂汇编呢亲
回复

使用道具 举报

5#
ID:89646 发表于 2015-9-20 15:30 | 只看该作者
原来的程序调试不出来,放弃了。我重新编了一个程序,完美运行
回复

使用道具 举报

6#
ID:89646 发表于 2015-9-20 15:31 | 只看该作者

/*说明:使用的是HS0038红外接收头                                                          */
/*功能:实现红外接收,接收到的键值码于数码管显示                  */
/*思路:检测外部中断下降沿的时间,来翻译红外信号                        */
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit IR = P3^2;
sbit dula = P2^6;
sbit wela = P2^7;
uchar IRtime;
bit IR_ok;
bit IR_receive_ok;
uchar IRcord[4];
uchar IRdata[33];
unsigned char code table[]={

                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义

                         };

IR_init()
{
        TMOD = 0x02;
        TH0 = 0;
        TL0 = 0;
        EA = 1;
        ET0 = 1;
        TR0 = 1;

        IT0 = 1;
        EX0 = 1;
}
void time0() interrupt 1
{
        IRtime++;        //277.7us
}

void ex0() interrupt 0
{
        static startflag;
        static uchar i;
        if(startflag)
        {
                if(IRtime > 32 && IRtime < 52)
                        i = 0;
                IRdata[i] = IRtime;
                IRtime = 0;
                i++;
                if(i == 33)
                {
                        IR_ok = 1;
                        i = 0;
                }
        }
        else
        {
                startflag = 1;
                IRtime = 0;
        }
}

void IRcordpro()
{
        uchar i,j,k,time,value;
        k = 1;
        for(i = 0;i < 4;i++)
        {
                for(j = 0;j < 8;j++ )
                {
                        time = IRdata[k];
                        value >>= 1;
                        if(time > 5)
                                value |= 0x80;
                        k++;
                }
                IRcord[i] = value;
                value = 0;       
        }
        IR_receive_ok = 1;               
}

void IRwork()
{
        switch (IRcord[2])
        {
                case 0x45:        P0 = table[0];        break;
                case 0x46:        P0 = table[1];        break;
                case 0x47:        P0 = table[2];        break;
                case 0x44:        P0 = table[3];        break;
                case 0x40:        P0 = table[4];        break;
                case 0x43:        P0 = table[5];        break;
                case 0x07:        P0 = table[6];        break;
                case 0x15:        P0 = table[7];        break;
                case 0x09:        P0 = table[8];        break;
                case 0x16:        P0 = table[9];        break;
                case 0x19:        P0 = table[10];        break;
                case 0x0d:        P0 = table[11];        break;
                case 0x0c:        P0 = table[12];        break;
                case 0x18:        P0 = table[13];        break;
                case 0x5e:        P0 = table[14];        break;
                case 0x08:        P0 = table[15];        break;
                case 0x1c:        P0 = table[16];        break;
                case 0x5a:        P0 = table[17];        break;
                case 0x42:        P0 = table[18];        break;
                case 0x52:        P0 = table[19];        break;
                case 0x4a:        P0 = table[20];        break;
                default:        break;
        }
        IR_receive_ok = 0;
}

void main()
{
        IR_init();
        wela = 1;
        P0 = 0xfe;
        wela = 0;
        P0 = 0xff;
        dula = 1;
        P0 = 0xff;
        while(1)
        {
                if(IR_ok)
                {
                        IRcordpro();
                        IR_ok = 0;       
                }
                if(IR_receive_ok)
                {
                        IRwork();
                }
        }
}
回复

使用道具 举报

7#
ID:79544 发表于 2015-9-21 12:05 | 只看该作者
定时的问题。 if(IRtime > 32 && IRtime < 52)
回复

使用道具 举报

8#
ID:84147 发表于 2015-9-21 12:19 | 只看该作者
最近也正在学红外解码,不过还是弄不懂,有木有诀窍呀
回复

使用道具 举报

9#
ID:84147 发表于 2015-9-21 12:21 | 只看该作者
最近也在研究红外解码,但是还是搞不懂,有没有诀窍呀
回复

使用道具 举报

10#
ID:84147 发表于 2015-9-21 18:10 | 只看该作者
你的程序我验证了一下,发现只能接收一次红外码,需要单片机复位以后才能从新接收下一次遥控发射的代码,有待改进
回复

使用道具 举报

11#
ID:90771 发表于 2015-9-22 13:08 | 只看该作者
爱莫能助啊
回复

使用道具 举报

12#
ID:90780 发表于 2015-9-22 14:23 | 只看该作者
很有用啊
回复

使用道具 举报

13#
ID:89646 发表于 2015-9-26 09:55 | 只看该作者
血一 发表于 2015-9-21 18:10
你的程序我验证了一下,发现只能接收一次红外码,需要单片机复位以后才能从新接收下一次遥控发射的代码,有 ...

您印证的是我的哪一个程序,是新发的,还是一楼之前发的?
回复

使用道具 举报

14#
ID:89646 发表于 2015-9-26 09:59 | 只看该作者
腾飞的龙 发表于 2015-9-21 12:05
定时的问题。 if(IRtime > 32 && IRtime < 52)

定时没有问题
回复

使用道具 举报

15#
ID:89646 发表于 2015-9-26 10:00 | 只看该作者
血一 发表于 2015-9-21 12:21
最近也在研究红外解码,但是还是搞不懂,有没有诀窍呀

我用的算法是:测试低电平与低电平的时间,来进行解码
回复

使用道具 举报

16#
ID:79544 发表于 2015-9-26 11:05 | 只看该作者
正常的红外解码数码管显示并控制LED程序,绝对好用。
  1. /***********************************************
  2.         功能:万能红外遥控器解码并用数码管显示。
  3.                         只显示键值码.根据键值控制LED
  4.                         加上三极管就可以控制继电器
  5.         红外接收头的输出接外部中断1.  P3.3
  6.         晶振:11.0592M
  7.         单片机:STC12C5A60S2
  8.         作者 :苏义江改编自51黑论坛
  9. *************************************************/
  10. #include <stc12c5a60s2.h>
  11. //#include <reg52.h>
  12. #define uchar unsigned char
  13. #define uint unsigned int
  14. sbit dula=P0^7;
  15. sbit wela=P0^6;
  16. sbit fmq=P1^7;
  17. sbit  IR=P3^3;
  18. //共阳
  19. uchar code table[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,
  20.                                 0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,
  21.                                 0xa1,0x86,0x8e,0x89};
  22. //共阴
  23. /*uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,
  24.        0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};  */

  25. uchar f;

  26. #define Imax 14000    //此处为晶振为11.0592时的取值,
  27. #define Imin 8000    //如用其它频率的晶振时,
  28. #define Inum1 1450    //要改变相应的取值。
  29. #define Inum2 700
  30. #define Inum3 3000

  31. uchar Im[4]={0x00,0x00,0x00,0x00};
  32. uchar show[2]={0,0};
  33. unsigned long m,Tc;
  34. unsigned char IrOK;

  35. void delay(uchar i)//延时
  36. {
  37.   uchar j,k;
  38.   for(j=i;j>0;j--)
  39.     for(k=125;k>0;k--);
  40. }

  41. void display()//显示函数
  42. {
  43.    P2=table[show[0]];
  44.    dula=1;
  45.    dula=0;
  46.         P2=0xff;
  47.    
  48.    wela=0;
  49.    P2=0xfe;
  50.    wela=1;
  51.    wela=0;
  52.    delay(5);
  53.    
  54.    P2=table[show[1]];
  55.    dula=1;
  56.    dula=0;
  57.         P2=0xff;
  58.    
  59.    P2=0xfd;
  60.    wela=1;
  61.    wela=0;
  62.    delay(5);
  63. }


  64. //外部中断1解码程序
  65. void intersvr1(void) interrupt 2 using 1
  66. {
  67.         fmq=0;    //蜂鸣器响
  68.         Tc=TH0*256+TL0;   //提取中断时间间隔时长
  69.         TH0=0;
  70.     TL0=0;         //定时中断重新置零
  71.         if((Tc>Imin)&&(Tc<Imax))
  72.     {
  73.                   m=0;
  74.         f=1;
  75.                   return;
  76.      }       //找到启始码
  77.    if(f==1)
  78.    {
  79.        if(Tc>Inum1&&Tc<Inum3)
  80.                    {
  81.                            Im[m/8]=Im[m/8]>>1|0x80; m++;
  82.             }
  83.               if(Tc>Inum2&&Tc<Inum1)
  84.         {
  85.                  Im[m/8]=Im[m/8]>>1; m++; //取码
  86.                   }
  87.                   if(m==32)
  88.                    {
  89.                  m=0;  
  90.                  f=0;
  91.          if(Im[2]==~Im[3])//键值码和反码相同
  92.                {
  93.            IrOK=1; //正确至1
  94.                     }
  95.          else IrOK=0;   //取码完成后判断读码是否正确
  96.      }
  97.                //准备读下一码
  98.    }
  99.         fmq=1; //蜂鸣器关,如果嫌吵,可删掉此行和上面对应的开喇叭那一行
  100. }
  101. /*主程序*/
  102. void main(void)
  103. {
  104.     uint  a;   
  105.          m=0;
  106.     f=0;
  107.         EA=1;
  108.         IT1=1;
  109.         EX1=1;
  110.     TMOD=0x11;  
  111.     TH0=0;TL0=0;
  112.     TR0=1;
  113.          while(1)
  114.         {

  115.        if(IrOK==1)
  116.                   {
  117.                       show[1]=Im[2] & 0x0F;     //取键码的低四位
  118.            show[0]=Im[2] >> 4;  
  119.            IrOK=0;     
  120.                   }
  121.            for(a=100;a>0;a--)
  122.           {
  123.                             display();//显示键值
  124.                      }
  125.                 switch(Im[2])//读出的键值控制LED
  126.                 {
  127.                         case 0x1b:P0=0XFE;break;
  128.                         case 0x18:P0=0XFd;break;
  129.                         case 0x17:P0=0XFb;break;
  130.                         case 0x16:P0=0XF7;break;
  131.                         case 0x15:P0=0Xef;break;
  132.                         case 0x14:P0=0Xdf;break;
  133.                         default: break;
  134.                 //        return;
  135.                 }
  136.         }
  137. }
复制代码
回复

使用道具 举报

17#
ID:88716 发表于 2015-9-26 12:22 | 只看该作者
#include<reg52.h>
//typedef unsigned char uchar;
//typedef unsigned int uint;
sbit IR_INPUT=P3^2;
bit irflag=0;
unsigned char  ircode[4];
void InitInfrared()
{

        IR_INPUT=1;
        TMOD&=0xf0;
        TMOD|=0x01;
        TR0=0;
        ET0=0;
        IT0=1;
        EX0=1;
}
unsigned int GetLowTime()
{
        TH0=0;
        TL0=0;
        TR0=1;
        while(!IR_INPUT)
        {
                if(TH0>0x40)
                {
                        break;
                }
        }
        TR0=0;
        return(TH0*256+TL0);
}
unsigned int GetHighTime()
{
        TH0=0;
        TL0=0;
        TR0=1;
        while(IR_INPUT)
        {
                if(TH0>0x40)
                {
                        break;
                }
        }
        TR0=0;
        return(TH0*256+TL0);
}
void EX0_ISR() interrupt 0
{
        unsigned char i,j,byt;
        unsigned int time;
       
        time=GetLowTime();
        if((time<7833)||(time>8755))
        {
                IE0=0;
                return;
        }
        time=GetHighTime();
        if((time<3686)||(time>4608))
        {
                IE0=0;
                return;
        }
        for(i=0;i<4;i++)
        {
                for(j=0;j<8;j++)
                {
                        time=GetLowTime();
                        if((time<313)||(time>718))
                        {
                                IE0=0;
                                return;
                        }
                        time=GetHighTime();
                        if((time>313)&&(time<718))
                        {
                                byt>>=1;
                        }
                        else if((time>1345)&&(time<1751))
                        {
                                byt>>=1;
                                byt|=0x80;
                        }
                        else
                        {
                                IE0=0;
                                return;
                        }
                }
                ircode[i]=byt;
        }
        IE0=0;
        irflag=1;
}
/******************main******************************/
#include<reg52.h>
typedef unsigned char uchar;
typedef unsigned int uint;
sbit du=P2^6;
sbit we=P2^7;
uchar T0RH=0;
uchar T0RL=0;
uchar jianma1=0,jianma2=0;
unsigned char code dofly_DuanMa[]={  0x3F,          //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
                                };// 显示段码值0~9
extern bit irflag;
extern unsigned char ircode[4];
extern void InitInfrared();
void delay(uchar x)
{
        uchar y,z;
        for(y=x;y>0;y--)
        for(z=114;z>0;z--);
}
/*void ConfigTimer1(uint ms)
{
        unsigned long temp;
        temp=110592/12;
        temp=(temp*ms)/1000;
        temp=65536-temp;
        T0RH=(unsigned char)(temp>>8);
        T0RL=(unsigned char)temp;
        TMOD&=0x0f;
        TMOD|=0x10;
        TH1=T0RH;
        TL1=T0RL;
        ET1=1;
        TR1=1;
}  */
void LedScan()
{
       
        du=1;
        P0=jianma1;
        du=0;
        P0=0xff;
        we=1;
        P0=0xbf;
        we=0;
        delay(1);
        du=1;
        P0=jianma2;
        du=0;
        P0=0xff;
        we=1;
        P0=0x7f;
        we=0;
        delay(1);

}
void main()
{
        EA=1;
        InitInfrared();
//        ConfigTimer1(3);
//        PT1=0;
        while(1)
        {
                if(irflag)
                {
                        irflag=0;
                        jianma1=dofly_DuanMa[ircode[2]>>4];
                        jianma2=dofly_DuanMa[ircode[2]&0x0f];
                }
                LedScan();
        }
}
/*void time1_isr() interrupt 3
{
        TH0 = T0RH;  //重新加载重载值
    TL0 = T0RL;
    LedScan();   //数码管扫描显示       
}  */
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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