微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 求高手详细解释下红外遥控程序

求高手详细解释下红外遥控程序

时间:10-02 整理:3721RD 点击:
求高手详细解释下红外遥控程序  主要是 “外部中断0中断处理”    “红外码值处理”  这两个函数不懂,可否解释下每个语句的意思

/*-----------------------------------------------
  名称:红外遥控器键值解码数码管显示
  编写:shanxiaodan
  日期:2011.5
  修改:无
  内容:按遥控器上的按键会在数码管上对应显示键值
  数据口P0  。P2_0为低位。P2_1为高位。
------------------------------------------------*/
#include<reg52.h>    //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
sbit IR=P3^2;  //红外接口标志
#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0替换
#define wei      P2
/*------------------------------------------------
                全局变量声明
------------------------------------------------*/
unsigned char code suma[16]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e};// 显示段码值0~F
unsigned char  irtime;//红外用全局变量
unsigned char  a,b,m,n;
bit irpro_ok,irok;
unsigned char IRcord[4];
unsigned char irdata[33];
/*------------------------------------------------
                  函数声明
------------------------------------------------*/
void Ir_work(void);
void Ircordpro(void);
void Delay(unsigned int t);
/*------------------------------------------------
                  定时器0中断处理
------------------------------------------------*/
void tim0_isr (void) interrupt 1 using 1
{
  irtime++;  //用于计数2个下降沿之间的时间
}
/*------------------------------------------------
                  外部中断0中断处理
------------------------------------------------*/
void EX0_ISR (void) interrupt 0 //外部中断0服务函数
{
  static unsigned char  i;             //接收红外信号处理
  static bit startflag;                //是否开始处理标志位
if(startflag)                        
   {
    if(irtime<63&&irtime>=33)//引导码 TC9012的头码,9ms+4.5ms
                        i=0;
                    irdata=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
                    irtime=0;
                    i++;
                            if(i==33)
                              {
                                   irok=1;
                                 i=0;
                                  }
          }
           else
                {
                irtime=0;
                startflag=1;
                }
}
/*------------------------------------------------
                定时器0初始化
------------------------------------------------*/
void TIM0init(void)//定时器0初始化
{
  TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
  TH0=0x00; //重载值
  TL0=0x00; //初始化值
  ET0=1;    //开中断
  TR0=1;   
}
/*------------------------------------------------
                  外部中断0初始化
------------------------------------------------*/
void EX0init(void)
{
IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1;   //使能外部中断
EA = 1;    //开总中断
}
/*------------------------------------------------
                  键值处理
------------------------------------------------*/
void  zuanhuan(void)                        //a--b
{  
   switch(a)
   {
         case 0x00:b=suma[0];  break;
         case 0x01:b=suma[1];  break;
         case 0x02:b=suma[2];  break;
         case 0x03:b=suma[3];  break;
         case 0x04:b=suma[4];  break;
         case 0x05:b=suma[5];  break;
         case 0x06:b=suma[6];  break;
         case 0x07:b=suma[7];  break;
         case 0x08:b=suma[8];  break;
         case 0x09:b=suma[9];  break;
         case 0x0a:b=suma[10];  break;
         case 0x0b:b=suma[11];  break;
         case 0x0c:b=suma[12];  break;
         case 0x0d:b=suma[13];  break;
         case 0x0e:b=suma[14];  break;
         case 0x0f:b=suma[15];  break;
     default:break;
   }
}
void Ir_work(void)//红外键值散转程序
{
          m=((IRcord[2])&(0xf0))>>4;                   //高四位
                  //DataPort=~m;
                  n=((IRcord[2])&(0x0f));                           //低四位
                  a=n;                                                                   //低四位转换
                  zuanhuan();
                  DataPort=b;
                  wei = 0xfe;
                  Delay(100);
                  a=m;                                                                   //高四位转换
                  zuanhuan();
                  DataPort=b;
                  wei = 0xfd;
                  Delay(100);
                  irpro_ok=0;//处理完成标志
  }
/*------------------------------------------------
                红外码值处理
------------------------------------------------*/
void Ircordpro(void)//红外码值处理函数
{
  unsigned char i, j, k;
  unsigned char cord,value;
  k=1;
  for(i=0;i<4;i++)      //处理4个字节
     {
      for(j=1;j<=8;j++) //处理1个字节8位
         {
          cord=irdata[k];
          if(cord>7)//大于某值为1,这个和晶振有绝对关系,这里使用12M计算,此值可以有一定误差
             value|=0x80;
          if(j<8)
                    {
                         value>>=1;
                        }
           k++;
         }
     IRcord=value;
     value=0;     
     }
         irpro_ok=1;//处理完毕标志位置1
}
/*------------------------------------------------
                    主函数
------------------------------------------------*/
void main(void)
{
EX0init(); //初始化外部中断
TIM0init();//初始化定时器
  DataPort=0x00; //取位码 第一位数码管选通,即二进制1111 1110

while(1)//主循环
   {
    if(irok)                        //如果接收好了进行红外处理
          {   
           Ircordpro();
           irok=0;
          }
    //if(irpro_ok)                   //如果处理好后进行工作处理,如按对应的按键后显示对应的数字等
          {
           Ir_work();
            }
   }
}
  
void Delay(unsigned int t)
{
while(--t);
}

帮你顶下~~~~~~~~~~我也在做红外~~~~~~~~不会~~~~~~

我也在做红外的,遇到好多麻烦的事啊

我也是做这个的,可惜我也不会~~~

学习下

正在学习   。

首先要知道,遥控器接收的原理

第一种:持续9ms高电平,然后持续4.5ms低电平,表示header;
第二种:持续4.5ms高电平,然后持续4.5ms低电平,表示header.
大部分的电视厂家都用这两种方式,有的用一,有的用二,如三星、NEC、松下、海尔、海信等。
这样必须先检测header,然后,持续560us的低电平为固定间隔,如三星规定持续560us高电平为0,持续1.12ms高电平为1.
这样必须使用定时器来固定计算单位,然后在INT0中计数,就可以通过两次下降沿之间的时间间隔来判断是header?还是逻辑1?还是逻辑0?然后把连续的8个bit连在一起判断这个码值是什么。

原理都差不多,可能对于header的时间,逻辑1和逻辑0的时间以及红外码的值等等每个厂家会有不同,这就需要你自己去了解清楚了后从单片机程序上去做调整了。
本人做过三星、NEC、松下、海尔等几个厂家的解码,其实程序基本差不多,只是时序稍作改动而已。

学习<<<<嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻嘻

3、63怎么确定的?

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top