微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > MCU和单片机设计讨论 > 小白的学习红外之路 ——含源程序(绝对原创)

小白的学习红外之路 ——含源程序(绝对原创)

时间:10-02 整理:3721RD 点击:

[qq]1074219405[/qq]                            本人学习单片机快有好几个月了吧,从最开始的看老郭的十天征服单片机到现在的能自己动手制作一些小东西,其中自己也不可避免的遇到过一些问题,但最终通过问实验室的学长和自己独立思考,最终都有所斩获,小白最近在学习红外方面的知识,花了快一个星期的时间,现在终于有点眉目了。
                       红外分编码和解码,当然呢,编码我们用不着管啊,各个厂家都给我们编好了,我们接下来要做的事就是解码了,首先,我们必须要对红外有一定的了解,不管什么遥控器,它都可以分为前导码,两组用户码,数据码和数据反码。前导码就可以理解为是红外发送的预警告一样,它提醒单片机做好接受数据的准备,两组数据码其实就是用来区分不同的遥控器的,避免不同的遥控器发生互相混乱,数据码和数据反码可以用来检验数据是否发送正确。下面就附上我打的程序一起来分析一下。
#include<reg52.h>     
sbit ir=P3^2;      //红外接口标志         
unsigned char  irtime;  //红外时间用全局变量
bit ir_chuliok,irok;     //定义红外处理完成标志
unsigned char ircode[4]; //定义一个数组,用来接收4个字节的数据,两组用户码和数据码,数据反码
unsigned char irdata[33];//红外发送一次要接收33个数据
void tim0_isr () interrupt 1 //计时器功能函数
{
  irtime++;   
}
void EX0_ISR (void) interrupt 0 //外部中断0服务函数
{
static unsigned char  i;    //接收红外信号处理
static bit start;           //是否开始处理标志位   
if(start)                        
   {
    if(irtime<63&&irtime>=33)//引导码9ms+4.5ms
           i=0;//从零开始,引导码算第一个码
     irdata=irtime;//存储每个电平的持续时间,用于以后判断是0还是1
      irtime=0;//这个不能少,每次计算完后必须清零,又从头开始
      i++;
       if(i==33)//总共有33个数据,前导码+8*4(4组数据,一组8位)
          {
        irok=1;//一个字节处理完后使标志位置一,以后就可以判断其是否为一来判断是否一个字节数据接收完全
      i=0;
       }
   }
else
{
  irtime=0;
  start=1;
}
}
void init1()//定时器0初始化
{
TMOD=0x02;//定时器0工作方式2,TH0是重装值,TL0是初值
TH0=0x00; //重载值
TL0=0x00; //初始化值
ET0=1;    //开中断
TR0=1;   
}
void init0()
{
IT0 = 1;   //指定外部中断0下降沿触发,INT0 (P3.2)
EX0 = 1;   //使能外部中断
EA = 1;    //开总中断
}
void ir_chuli(void)//红外码值处理函数
{
   unsigned char i, j, k=1;
   unsigned char cord,value;
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++;
  }
  ircode=value;
  value=0;     
   }
  ir_chuliok=1;//处理完毕标志位置1
}
void main(void)
{
init0(); //初始化外部中断
init1();//初始化定时器
while(1)//主循环
  {         
  if(irok)      //如果irok==1表示接收好了,就可以进行红外处理
   {   
    ir_chuli();  //进行红外处理
    irok=0;   //标志位要清零
    }
  if(ir_chuliok)   //如果ir_chuliok==1表示处理好了,可以进行解码了
      {
    P1=ircode[2];  //这个下文独立分析
       ir_chuliok=0;
     }
}
}
    接着说,P1=ircode[2];  就是把第三个字节的数据给p1口,注意我的板子上P1口接的是led,这个是关键,我的目的是把各个按键的码值给解出来,那么,我可以按不同的按键,P1上灯的亮灭情况就不一样了,这样,我不可以通过P1口的情况把每个按键对应的值给读出来了吗,解码完成后其他的就好说啦,你想按什么按键,直接用个switch case 函数就可以调用啦,随便举个例子哈
void ir_work()    //红外键值散转程序,按什么值数码管上就显示什么值,数码管驱动程序就不写啦
{
       switch(ircode[2])//判断第三个数码值
          {
            case 0x0c:P0=DuanMa[1];break;//1 显示相应的按键值,其中case中的值可以自己解码出来,不同的遥控器可能不同
            case 0x18:P0=DuanMa[2];break;//2
            case 0x5e:P0=DuanMa[3];break;//3
            case 0x08:P0=DuanMa[4];break;//4
            case 0x1c:P0=DuanMa[5];break;//5
            case 0x5a:P0=DuanMa[6];break;//6
            case 0x42:P0=DuanMa[7];break;//7
            case 0x52:P0=DuanMa[8];break;//8
            case 0x4a:P0=DuanMa[9];break;//9
             default:break;
        }
  }
    怎么样,不论什么样的遥控器,你都可以自己给解出来,然后自己可以操控遥控器啦,想实现什么样的功能都可以自己去定义啦,你懂了吗?

自己先给自己顶一个,为电子痴狂

我支持你,我最近也在学红外,能留个qq不

可以的,我的扣扣1074219405

谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢谢放言乱说话谢谢

给力 谢谢啦

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

网站地图

Top