原创 智能车 红外遥控器解码程序演示

2010-2-28 21:54 2887 8 8 分类: MCU/ 嵌入式

一、 实验简介:
本程序主要将现在比较常用M50462遥控器进行解码,将解码后的数据通过P2端口的数码管显示出来,为了更好的看到运行过程,特加了三个指示灯用来指示当前运行状态。P10闪亮,表示程序正在运行;P11闪亮,表示接收到数据;P12闪亮,表示触发内部的定时器操作;P13闪亮,表示正确接收完一个数据。
二、 实验原理图:


点击看大图


================================================================== //
//  开发日期:2009/01/27                      //
//  修改日期:                                                         //
//  程序备注:此程序仅为表现本机功能而演示用,当用作实际工程时请慎用。  //
//  特别声明: 此程序可作研究之用,但引用、转载、使用请注明出处。      //
//================================================================== //
#include <AT89x51.h>                   //包含51单片机相关的头文件
unsigned char  code LedShowData[]=      //定义数码管显示数据
         {0x9F,0x25,0x0D,0x99,0x49,     //1,2,3,4,5,
         0x41,0x1F,0x01,0x19,0x03};     //6,7,8,9,0,
static unsigned int RecvData;           //定义接收红外数据变量
static unsigned char CountData;         //定义红外个数计数变量
static unsigned char AddData;           //定义自增变量
static unsigned int LedFlash;           //定义闪动频率计数变量
unsigned char HeardData;                //定义接收到数据的高位变量
sbit RunLed="P1"^0;                      //定义运行指示灯变量位
sbit RecvLed="P1"^1;                     //定义接收指示灯变量位
sbit InTimeLed="P1"^2;                   //定义定时器开始指示灯变量位
sbit ReadyLed="P1"^3;                    //定义就绪指示灯变量
sbit IR1=P3^3;                         //定义红外接收端口
#define ShowPort P2                    //定义数码管显示端口
void Timer0_IR1() interrupt 1 using 3    //定义红外定时器子程序
{
 TH0=0xFF;                             //向定时器定时间寄存器填入高八位值
 TL0=0x19;                             //向定时器定时间寄存器填入低八位值
 InTimeLed=!InTimeLed;                 //将定时器指示灯进行取反
 AddData++;                            //自增变量加1
}
void Int1_IR1() interrupt 2             //定义红外接收中断子程序
{
 RecvLed=!RecvLed;                     //将红外接收数据进行取反
 ReadyLed=1;                           //红外接收数据指示灯置1
 if(4==AddData) //0                     //判断接收到的数据是0
 {
  RecvData="RecvData" | 0;               //判断到0就将当前位写0
  RecvData="RecvData" << 1;              //将当前位向左移动1位
 }
 else if(8==AddData)//1                 //判断接收到的数据是1
 {
  RecvData="RecvData" | 1;                //将当前位写1
  RecvData="RecvData" << 1;              //将当前位向左移动1位
 }
 CountData++;                          //将红外接收位计数器加1
 if(CountData==8)                       //判断是否接收到8位数据
 {
  HeardData="RecvData";                  //是8位数据时,则将数据暂存到高位变量中
 }
 else if(CountData==16)                  //判断是否接收到16位数据
 {
  ET0=0;                               //关闭红外定时器0
  EX1=0;                               //关闭红外外部中断1
  AddData="0";                            //定时时间间隔变量清零
  if(HeardData==226 || HeardData==112)   //判断用户码是否正确
  { ReadyLed="0";                         //用户码正确则就绪指示灯点亮一下
 HeardData=RecvData;                 //取出接收到的低八位数据
    switch(HeardData)                   //判断低八位数据的值下列那一位
    {
      case 32: //电源                    //说明按下了电源键
{ //在这里填写你自己的代码         //根据你的功能自己写
      break;                         //返回
    }
   case 46: //TV/AV                   //说明按下了TV/AV键
    { //在这里填写你自己的代码       //根据你的功能自己写
      break;                         //返回
    }
   case 0: //1                        //说明按下数字1键
    {ShowPort= LedShowData[0];       //数码管显示数字1
     break;                          //返回
    }
   case 8: //2                        //说明按下了数字2键
    {ShowPort= LedShowData[1];       //数码管显示数字2
     break;                          //返回
    }
      case 4: //3                        //说明按下了数字3键
    {ShowPort= LedShowData[2];       //数码管显示数字3
     break;                          //返回
    }
   case 12: //4                       //说明按下了数字4键
    {ShowPort= LedShowData[3];       //数码管显示数字4
     break;                          //返回
    }
   case 2: //5                        //说明按下了数字5键
    {ShowPort= LedShowData[4];       //数码管显示数字5
     break;                          //返回
    }
   case 10: //6                       //说明按下了数字6键
    {ShowPort= LedShowData[5];       //数码管显示数字6
     break;                          //返回
    }
      case 6: //7                        //说明按下了数字7键
       {ShowPort= LedShowData[6];       //数码管显示数字7
        break;                          //返回
       }
      case 14: //8                       //说明按下了数字8键
       {ShowPort= LedShowData[7];       //数码管显示数字8
        break;                          //返回
       }
      case 64: //9                       //说明按下了数字9键
       {ShowPort= LedShowData[8];       //数码管显示数字9
        break;                          //返回
       }
      case 72: //0/30                    //说明按下0/30键
       {ShowPort= LedShowData[9];       //数码管显示数字0
        break;                          //返回
       }
      case 68: //10+                     //说明按下10+键
       {//在这里填写你自己的代码        //根据你的功能写代码
        break;                          //返回
       }
      case 76: //20+                     //说明按下了20+键
       {//在这里填写你自己的代码       //根据你的功能写代码
        break;                          //返回
       }
      case 36: //CH-                     //说明按下了CH-键
       {//在这里填写你自己的代码        //根据你的功能写代码
     break;                          //返回
       }
      case 40: //CH+                    //说明按下了CH+键
       {//在这里填写你自己的代码        //根据你的功能写代码
     break;                          //返回
       }
     }
   }
   RecvData="0";                          //将接收到的数据清零
   CountData="0";                         //将接收计数器清零
   HeardData="0";                         //将接收高低数据变量清零
   return;                              //返回
  }
  AddData="0";                            //将定时器计数器清零
  ET0=1;                               //打开定时器中断
}
void main(void)                          //主程序入口
{
 bit ExeFlag="0";                          //定义可执行位变量
 RecvData=0;                            //将接收变量数值初始化
 CountData=0;                           //将计数器变量数值初始化
 AddData=0;                             //将定时器计数器初始化
 HeardData=0;                           //将高低计数器初始化
 LedFlash=3000;                         //对闪灯数据进行初始化
 TMOD=0x01;                             //选择定时器0为两个16位定时器
 TH0=0xFF;                              //对定时器进行计数值进行初始化
 TL0=0x19;                              //同上,时间大约为25uS
 TR0=1;                                 //同意开始定时器0
 EX1=1;                                 //同意开启外部中断1
 IT1=1;                                 //设定外部中断1为低边缘触发类型
 EA=1;                                  //总中断开启
 while(1)                               //程序主循环
 {
   while(LedFlash--)                     //闪灯总延时
    {
     if(IR1==0)                         //判断延时期间是否有红外信号输入
       {ExeFlag=1;                     //将可执行标志位置1
       }
    }
  RunLed=!RunLed;                       //运行指示灯取反
  LedFlash="3000";                        //运行闪动时间重设定
  if(ExeFlag==0)                        //判断可执行标志位
  {
   EX1=1;                               //开启外部中断1
  }
  ExeFlag="0";                            //可执行标志位置0
 }
}
四、 运行效果:
程序运行效果: 打开本机电源开关,可以看到P10不停的闪动,按下遥控器的数字键,数码管则显示相应的数字键(1-9)。可以看到P11、P12在显示后呈亮状态,则可以接收下一个数据,在上面

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
8
关闭 站长推荐上一条 /3 下一条