迅维网

查看: 1192|回复: 0
打印 上一主题 下一主题

用AT89S51单片机制作红外电视遥控器

[复制链接]
跳转到指定楼层
1#
发表于 2016-2-16 09:11:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式 来自: 山东 来自 山东

马上注册,获取阅读精华内容及下载权限

您需要 登录 才可以下载或查看,没有帐号?注册

x
  一般红外电视遥控器的输出都是用编码后串行数据对38~40kHz的方波进行脉冲幅度调制而产生的。
  当发射器按键按下后,即有遥控码发出,所按的键不同遥控编码也不同。这种遥控码具有以下特征:
  采用脉宽调制的串行码,以脉宽为0.565ms、间隔0.56ms、周期为1.125ms的组合表示二进制的“0”;以脉宽为0.565ms、间隔1.685ms、周期为2.25ms的组合表示二进制的“1”。
  上述“0”和“1”组成的32位二进制码经38kHz的载频进行二次调制,然后再通过红外发射二极管产生红外线向空间发射。一般电视遥控器的遥控编码是连续的32位二进制码组,其中前16位为用户识别码,能区别不同的红外遥控设备,防止不同机种遥控码互相干扰。后16位为8位的操作码和8位的操作反码,用于核对数据是否接收准确。
  根据红外编码的格式,发送数据前需要先发送9ms的起始码和4.5ms的结果码。
  遥控串行数据编码波形如下图所示:

                               
登录/注册后看高清大图




  接收方一般使用TL0038一体化红外线接收器进行接收解码,当TL0038接收到38kHz红外信号时,输出端输出低电平,否则为高电平。所以红外遥控器发送红外信号时,参考上面遥控串行数据编码波形图,在低电平处发送38kHz红外信号,高电平处则不发送红外信号。
  单片机红外电视遥控器电路图如下:

                               
登录/注册后看高清大图




C51程序代码:
  • #include<reg52.h>
  • static bit OP;        //红外发射管的亮灭
  • static unsigned int count;       //延时计数器
  • static unsigned int endcount; //终止延时计数
  • static unsigned char flag;      //红外发送标志
  • char iraddr1;  //十六位地址的第一个字节
  • char iraddr2;  //十六位地址的第二个字节
  • void SendIRdata(char p_irdata);
  • void delay();
  • void main(void)
  • {
  •   count = 0;
  •   flag = 0;
  •   OP = 0;
  •   P3_4 = 0;
  •   EA = 1; //允许CPU中断
  •   TMOD = 0x11; //设定时器0和1为16位模式1
  •   ET0 = 1; //定时器0中断允许
  •   TH0 = 0xFF;
  •   TL0 = 0xE6; //设定时值0为38K 也就是每隔26us中断一次
  •   TR0 = 1;//开始计数
  •   iraddr1=3;
  •   iraddr2=252;
  •   do{
  •       delay();
  •       SendIRdata(12);
  •   }while(1);
  • }
  • //定时器0中断处理
  • void timeint(void) interrupt 1
  • {
  •   TH0=0xFF;
  •   TL0=0xE6; //设定时值为38K 也就是每隔26us中断一次
  •   count++;
  •   if (flag==1)
  •   {
  •     OP=~OP;
  •   }
  •   else
  •   {
  •     OP = 0;
  •   }
  •   P3_4 = OP;
  • }
  • void SendIRdata(char p_irdata)
  • {
  •   int i;
  •   char irdata=p_irdata;
  •   //发送9ms的起始码
  •   endcount=223;
  •   flag=1;
  •   count=0;
  •   do{}while(count<endcount);
  •   //发送4.5ms的结果码
  •   endcount=117
  •   flag=0;
  •   count=0;
  •   do{}while(count<endcount);
  •   //发送十六位地址的前八位
  •   irdata=iraddr1;
  •   for(i=0;i<8;i++)
  •   {
  •      //先发送0.56ms的38KHZ红外波(即编码中0.56ms的低电平)
  •      endcount=10;
  •      flag=1;
  •      count=0;
  •      do{}while(count<endcount);
  • //停止发送红外信号(即编码中的高电平)
  •      if(irdata-(irdata/2)*2)  //判断二进制数个位为1还是0
  •      {
  •        endcount=41;  //1为宽的高电平
  •      }
  •     else
  •      {
  •      endcount=15;   //0为窄的高电平
  •      }
  •     flag=0;
  •     count=0;
  •     do{}while(count<endcount);
  •     irdata=irdata>>1;
  •   }
  •   //发送十六位地址的后八位
  •   irdata=iraddr2;
  •   for(i=0;i<8;i++)
  •   {
  •      endcount=10;
  •      flag=1;
  •      count=0;
  •      do{}while(count<endcount);
  •      if(irdata-(irdata/2)*2)
  •      {
  •         endcount=41;
  •      }
  •      else
  •      {
  •        endcount=15;
  •      }
  •      flag=0;
  •      count=0;
  •      do{}while(count<endcount);
  •      irdata=irdata>>1;
  •   }
  •   //发送八位数据
  •   irdata=p_irdata;
  •   for(i=0;i<8;i++)
  •   {
  •      endcount=10;
  •      flag=1;
  •      count=0;
  •      do{}while(count<endcount);
  •      if(irdata-(irdata/2)*2)
  •      {
  •          endcount=41;
  •      }
  •      else
  •      {
  •        endcount=15;
  •      }
  •      flag=0;
  •      count=0;
  •      do{}while(count<endcount);
  •      irdata=irdata>>1;
  •   }
  •   //发送八位数据的反码
  •   irdata=~p_irdata;
  •   for(i=0;i<8;i++)
  •   {
  •      endcount=10;
  •      flag=1;
  •      count=0;
  •      do{}while(count<endcount);
  •      if(irdata-(irdata/2)*2)
  •      {
  •          endcount=41;
  •      }
  •      else
  •      {
  •        endcount=15;
  •      }
  •      flag=0;
  •      count=0;
  •      do{}while(count<endcount);
  •      irdata=irdata>>1;
  •   }
  •   endcount=10;
  •   flag=1;
  •   count=0;
  •   do{}while(count<endcount);
  •   flag=0;
  • }
  • void delay()
  • {
  •   int i,j;
  •   for(i=0;i<400;i++)
  •   {
  •     for(j=0;j<100;j++)
  •     {
  •     }
  •   }
    }

复制代码




  制作的实物如下图所示:

                               
登录/注册后看高清大图




//STC的为
  • #include<reg52.h>
  • static bit OP;        //红外发射管的亮灭
  • static unsigned int count;       //延时计数器
  • static unsigned int endcount; //终止延时计数
  • static unsigned char flag;      //红外发送标志
  • char iraddr1;  //十六位地址的第一个字节
  • char iraddr2;  //十六位地址的第二个字节
  • sbit  HOP=P3^4;
  • void SendIRdata(char p_irdata);
  • void delay();
  • void main(void)
  • {
  •   count = 0;
  •   flag = 0;
  •   OP = 0;
  •   HOP = 0;
  •   EA = 1; //允许CPU中断
  •   TMOD = 0x11; //设定时器0和1为16位模式1
  •   ET0 = 1; //定时器0中断允许
  •   TH0 = 0xFF;
  •   TL0 = 0xE6; //设定时值0为38K 也就是每隔26us中断一次
  •   TR0 = 1;//开始计数
  •   iraddr1=3;
  •   iraddr2=252;
  •   do{
  •       delay();
  •       SendIRdata(12);
  •   }while(1);
  • }
  • //定时器0中断处理
  • void timeint(void) interrupt 1
  • {
  •   TH0=0xFF;
  •   TL0=0xE6; //设定时值为38K 也就是每隔26us中断一次
  •   count++;
  •   if (flag==1)
  •   {
  •     OP=~OP;
  •   }
  •   else
  •   {
  •     OP = 0;
  •   }
  •   HOP = OP;
  • }
  • void SendIRdata(char p_irdata)
  • {
  •   int i;
  •   char irdata=p_irdata;
  •   //发送9ms的起始码
  •   endcount=223;
  •   flag=1;
  •   count=0;
  •   do{}while(count<endcount);
  •   //发送4.5ms的结果码
  •   endcount=117;
  •   flag=0;
  •   count=0;
  •   do{}while(count<endcount);
  •   //发送十六位地址的前八位
  •   irdata=iraddr1;
  •   for(i=0;i<8;i++)
  •   {
  •      //先发送0.56ms的38KHZ红外波(即编码中0.56ms的低电平)
  •      endcount=10;
  •      flag=1;
  •      count=0;
  •      do{}while(count<endcount);
  • //停止发送红外信号(即编码中的高电平)
  •      if(irdata-(irdata/2)*2)  //判断二进制数个位为1还是0
  •      {
  •        endcount=41;  //1为宽的高电平
  •      }
  •     else
  •      {
  •      endcount=15;   //0为窄的高电平
  •      }
  •     flag=0;
  •     count=0;
  •     do{}while(count<endcount);
  •     irdata=irdata>>1;
  •   }
  •   //发送十六位地址的后八位
  •   irdata=iraddr2;
  •   for(i=0;i<8;i++)
  •   {
  •      endcount=10;
  •      flag=1;
  •      count=0;
  •      do{}while(count<endcount);
  •      if(irdata-(irdata/2)*2)
  •      {
  •         endcount=41;
  •      }
  •      else
  •      {
  •        endcount=15;
  •      }
  •      flag=0;
  •      count=0;
  •      do{}while(count<endcount);
  •      irdata=irdata>>1;
  •   }
  •   //发送八位数据
  •   irdata=p_irdata;
  •   for(i=0;i<8;i++)
  •   {
  •      endcount=10;
  •      flag=1;
  •      count=0;
  •      do{}while(count<endcount);
  •      if(irdata-(irdata/2)*2)
  •      {
  •          endcount=41;
  •      }
  •      else
  •      {
  •        endcount=15;
  •      }
  •      flag=0;
  •      count=0;
  •      do{}while(count<endcount);
  •      irdata=irdata>>1;
  •   }
  •   //发送八位数据的反码
  •   irdata=~p_irdata;
  •   for(i=0;i<8;i++)
  •   {
  •      endcount=10;
  •      flag=1;
  •      count=0;
  •      do{}while(count<endcount);
  •      if(irdata-(irdata/2)*2)
  •      {
  •          endcount=41;
  •      }
  •      else
  •      {
  •        endcount=15;
  •      }
  •      flag=0;
  •      count=0;
  •      do{}while(count<endcount);
  •      irdata=irdata>>1;
  •   }
  •   endcount=10;
  •   flag=1;
  •   count=0;
  •   do{}while(count<endcount);
  •   flag=0;
  • }
  • void delay()
  • {
  •   int i,j;
  •   for(i=0;i<400;i++)
  •   {
  •     for(j=0;j<100;j++)
  •     {
  •     }
  •   }
    }

复制代码






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

本版积分规则

快速回复 返回顶部 返回列表
附近
店铺
微信扫码查看附近店铺
维修
报价
扫码查看手机版报价
信号元
件查询
点位图 AI维修
助手



芯片搜索

快速回复