首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

51单片机-红外遥控解码

51单片机-红外遥控解码

关键词: 51单片机 , 红外遥控





IR(Infrared Radiation)通用红外遥控系统由发射和接受两大部分组成,应用编/解码专用集成电路芯片来进行控制操作。发射部分包括键盘矩阵,编码调制,LED红外线发射。接受部分包括光,电转化放大器,解调,解码电路。接收电路可以使用一种集红外线接受和放大于一体的一体化红外接收器,不需要任何外接元件,就能完成从红外线接受到输出与TTL电平信号兼容的所有工作,而体积和普通的塑料三极管大小一样。它适合于各种红外线遥控和红外线数据传输。接收器对外只有3个引脚OUT,GND,VCC与单片机接口非常方便。





发射码的格式:





遥控器输出波形:





接受到的波形和发送的波形正好是反向,比如发送的是一高电平然后一低电平,接受的会是一低电平和一高电平。





外部中断触发方式:低电平和下降沿。

下面这段代码的作用是用遥控器向单片机发送数据,单片机响应并改变数码管上的数据。

这段代码仍然有问题,正在调试中,路过的大牛希望给与指导:

#include <reg52.h>
#define uint unsigned int
#define uchar unsigned char
uint irtime,startflag,i,bitnum,decodeok,receiveok;
uchar irdata[33],disp[8],vcode[4];
unsigned char code duan[]={ 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
                            0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
unsigned char code wei[]={ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07};

void delay(int k){
        int i,j;
          for(i = 0; i < k; i++)
          for(j = 0; j < 0xff; j++)
        ;
}

void Time0_Init(){
          EA = 1;
         ET0 = 1;
          TH0 = 0x00;
          TL0 = 0x00;
        TMOD = 0x02;
          TR0 = 1;
}

void Int0_Init(){
         EA = 1;
         IT0 = 1;
         EX0 = 1;
}

void Irpro(){
         disp[0] = vcode[0] / 16; //把十六进制的数转化成两位显示
         disp[1] = vcode[0] % 16;
         disp[2] = vcode[1] / 16;
         disp[3] = vcode[1] % 16;
         disp[4] = vcode[2] / 16;
         disp[5] = vcode[2] % 16;
         disp[6] = vcode[3] / 16;
         disp[7] = vcode[3] % 16;
}

void display(){
     for(i = 0; i < 8; i++){
       P1 = wei[ i];
       P2 = duan[disp[ i]];
       delay(1);
         }
}

void decode(){
        uint k,i,j;
         uchar value;
         j = 1;
         for(k = 0; k < 4; k++){
                 value = 0;
                 for(i = 0; i < 8; i++){
                         if(irdata[j]>6) //如果大于6个irtime是高电平
                        value |= 0x01 << i; j++;
                }
                vcode[k] = value;
         }
         decodeok = 1;
}
  
void main(){
        Time0_Init(); //对定时器中断进行初始化
        Int0_Init(); //对下降沿中断进行初始化
        while(1){
                if(receiveok == 1){ //如果接受成功进行解码
                        receiveok = 0;
                        decode();
                }
                if(decodeok == 1){ //如果解码成功,转换一下格式准备显示
                        decodeok = 0;
                        Irpro();
                }
                display();
        }
}

void time0() interrupt 1{ //由于是模式2,8位自动重装,所以一个irtime为256us
        irtime++;
}

void int0() interrupt 0{
        if(startflag){
                if(irtime > 32){ //如果是引导信息,则bitnum清零
                bitnum = 0;
                 }
                irdata[bitnum] = irtime; //装载数据,包括1位引导位,16位用户码,8位数据码和8位数据码反码
                irtime = 0;
                 bitnum++;
                if(bitnum == 33){ //装载数据完成
                        bitnum = 0;
                        receiveok = 1;
                 }
        }
        else{
                startflag = 1; //遇到第一个下降沿让irtime为0,遇到第二个时计算用了多少个irtime
                irtime = 0;
        }
}


返回列表