找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 10416|回复: 8
打印 上一主题 下一主题
收起左侧

proteus仿真红外线遥控模拟

  [复制链接]
跳转到指定楼层
楼主
  红外线编码是数据传输和家用电器遥控常用的一种通讯方法,其实质是一种脉宽调制的串行通讯。家电遥控中常用的红外线编码电路有μPD6121G型HT622型和7461型等。
    这里就以这些电路的编码格式来仿真怎样使用单片机的捕获中断功能来实现其解码。    红外线通讯的发送部分主要是把待发送的数据转换成一定格式的脉冲,然后驱动红外发光管向外发送数据。接收部分则是完成红外线的接收、放大、解调,还原成同步发射格式相同(但高、低电位刚好相反的脉冲信号)。这些工作通常由一体化的接收头来完成,主要输出TTL兼容电平。最后通过解码把脉冲信号转换成数据,从而实现数据的传输。
   本单元就是来完成一体化接收头接受到的红外遥控器编码后的输出数据,所以只要单片机完成本单元的解码任务,并成功实现之后,只要将IR引脚接上红外接收头之后就可以实现红外遥控的功能了。
  这是我积累前人经验和自己实践的成果,并且已经有硬件的成功案例,并非只是理论.

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. #include <AT89X51.h>

  2. static bit OP;        //红外发射管的亮灭
  3. static unsigned int count;       //延时计数器
  4. static unsigned int endcount; //终止延时计数
  5. static unsigned char Flag;      //红外发送标志
  6. char iraddr1;  //十六位地址的第一个字节
  7. char iraddr2;  //十六位地址的第二个字节

  8. void SendIRdata(char p_irdata);
  9. void delay();
  10. char getkey()
  11. {
  12.           P1=0xfe;P3_6=P3_7=1;P3_3=1;
  13.           if(!P1_4)return 1;   //ON
  14.           if(!P1_5)return 2;   //7
  15.           if(!P1_6)return 3;   //8
  16.           if(!P1_7)return 4;   //9
  17.           if(!P3_6)return 5;   //X
  18.           if(!P3_7)return 6;   //÷
  19.           P1=0xfd;
  20.           if(!P1_4)return 11; //+-
  21.           if(!P1_5)return 12; //4
  22.           if(!P1_6)return 13; //5
  23.           if(!P1_7)return 14; //6
  24.           if(!P3_6)return 15; //-
  25.           if(!P3_7)return 16; //MRC
  26.           P1=0xfb;
  27.           if(!P1_4)return 21; //%
  28.           if(!P1_5)return 22; //1
  29.           if(!P1_6)return 23; //2
  30.           if(!P1_7)return 24; //3
  31.           if(!P3_6)return 25; //+
  32.           if(!P3_7)return 26; //M-
  33.           P1=0xf7;
  34.           if(!P1_4)return 31; //□
  35.           if(!P1_5)return 32; //0
  36.           if(!P1_6)return 33; //.
  37.           if(!P1_7)return 34; //=
  38.           if(!P3_6)return 35; //+
  39.           if(!P3_7)return 36; //M+

  40.           P1=0xfF;P3_3=0;
  41.           if(!P1_4)return 41; //
  42.           if(!P1_5)return 42; //
  43.           if(!P1_6)return 43; //
  44.           if(!P1_7)return 44; //
  45.           if(!P3_6)return 45; //
  46.           if(!P3_7)return 46; //
  47.           return 0;
  48. }

  49. void main(void)
  50. {
  51.   char key;
  52.   count = 0;
  53.   Flag = 0;
  54.   OP = 0;
  55.   P3_4 = 1;
  56.   EA = 1; //允许CPU中断
  57.   TMOD = 0x11; //设定时器0和1为16位模式1
  58.   ET0 = 1; //定时器0中断允许

  59.   P1=0xff;
  60.   TH0 = 0xFF;
  61.   TL0 = 0xE6; //设定时值0为38K 也就是每隔26us中断一次  
  62.   TR0 = 1;//开始计数

  63.   iraddr1=0xff;
  64.   iraddr2=0xff;


  65.   do{
  66.           key=getkey();
  67.       if(key==1)SendIRdata(0x12);//set
  68.       if(key==11)SendIRdata(0x0b);//exit
  69.       if(key==25||key==35)SendIRdata(0x1a);//+
  70.       if(key==15)SendIRdata(0x1e);//-
  71.       if(key==6)SendIRdata(0x0e);//↑ ÷
  72.       if(key==16)SendIRdata(0x1d);//↓ MRC

  73.       if(key==26)SendIRdata(0x1f);//← M-
  74.       if(key==36)SendIRdata(0x1b);//→ M+
  75.       if(key==32)SendIRdata(0x00);//0
  76.       if(key==22)SendIRdata(0x01);//1
  77.       if(key==23)SendIRdata(0x02);//2

  78.       if(key==24)SendIRdata(0x03);//3
  79.       if(key==12)SendIRdata(0x04);//4
  80.       if(key==13)SendIRdata(0x05);//5
  81.       if(key==14)SendIRdata(0x06);//6
  82.       if(key==2)SendIRdata(0x07);//7
  83.       if(key==3)SendIRdata(0x08);//8

  84.       if(key==4)SendIRdata(0x09);//9
  85.       if(key==21)SendIRdata(0x2A);//%
  86.       if(key==5)SendIRdata(0x2B);//X
  87.       if(key==33)SendIRdata(0x2C);//.
  88.       if(key==34)SendIRdata(0x2D);//=
  89.       if(key==31)SendIRdata(0x2E);//□

  90.       if(key==41)SendIRdata(0x2F);//
  91.       if(key==42)SendIRdata(0x30);//
  92.       if(key==43)SendIRdata(0x31);//
  93.       if(key==44)SendIRdata(0x32);//
  94.       if(key==45)SendIRdata(0x33);//
  95.       if(key==46)SendIRdata(0x34);//
  96.   }while(1);
  97. }
  98. //定时器0中断处理
  99. void timeint(void) interrupt 1
  100. {
  101.   TH0=0xFF;
  102.   TL0=0xE6; //设定时值为38K 也就是每隔26us中断一次
  103.   count++;

  104. }


  105. void SendIRdata(char p_irdata)
  106. {
  107.   int i;
  108.   char irdata=p_irdata;

  109.   //发送9ms的起始码
  110.   endcount=223;
  111.   Flag=1;
  112.   count=0;
  113.   P3_4=0;
  114.   do{}while(count<endcount);

  115.   //发送4.5ms的结果码
  116.   endcount=117;
  117.   Flag=0;
  118.   count=0;
  119.   P3_4=1;
  120.   do{}while(count<endcount);

  121.   //发送十六位地址的前八位
  122.   irdata=iraddr1;
  123.   for(i=0;i<8;i++)
  124.   {

  125.      //先发送0.56ms的38KHZ红外波(即编码中0.56ms的低电平)
  126.      endcount=10;
  127.      Flag=1;
  128.      count=0;
  129.          P3_4=0;
  130.      do{}while(count<endcount);

  131.     //停止发送红外信号(即编码中的高电平)
  132.      if(irdata-(irdata/2)*2)  //判断二进制数个位为1还是0
  133.      {
  134.        endcount=15;  //1为宽的高电平
  135.      }
  136.     else
  137.      {
  138.      endcount=41;   //0为窄的高电平
  139.      }
  140.     Flag=0;
  141.     count=0;
  142.         P3_4=1;
  143.     do{}while(count<endcount);

  144.     irdata=irdata>>1;
  145.   }

  146.   //发送十六位地址的后八位
  147.   irdata=iraddr2;
  148.   for(i=0;i<8;i++)
  149.   {
  150.      endcount=10;
  151.      Flag=1;
  152.      count=0;
  153.          P3_4=0;
  154.      do{}while(count<endcount);

  155.      if(irdata-(irdata/2)*2)
  156.      {
  157.         endcount=15;
  158.      }
  159.      else
  160.      {
  161.        endcount=41;
  162.      }
  163.      Flag=0;
  164.      count=0;
  165.          P3_4=1;
  166.      do{}while(count<endcount);

  167.      irdata=irdata>>1;
  168.   }

  169.   //发送八位数据
  170.   irdata=~p_irdata;
  171.   for(i=0;i<8;i++)
  172.   {
  173.      endcount=10;
  174.      Flag=1;
  175.      count=0;
  176.          P3_4=0;
  177.      do{}while(count<endcount);

  178.      if(irdata-(irdata/2)*2)
  179.      {
  180.          endcount=15;
  181.      }
  182.      else
  183.      {
  184.        endcount=41;
  185.      }
  186.      Flag=0;
  187.      count=0;
  188.          P3_4=1;
  189.      do{}while(count<endcount);

  190.      irdata=irdata>>1;
  191.   }

  192.   //发送八位数据的反码
  193.   irdata=p_irdata;
  194.   for(i=0;i<8;i++)
  195.   {
  196.      endcount=10;
  197.      Flag=1;
  198.      count=0;
  199.          P3_4=0;
  200.      do{}while(count<endcount);

  201.      if(irdata-(irdata/2)*2)
  202.      {
  203.          endcount=15;
  204.      }
  205.      else
  206.      {
  207.        endcount=41;
  208.      }
  209. ……………………

  210. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
红外遥控模拟.rar (60.53 KB, 下载次数: 393)



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏3 分享分享 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
apple_01 发表于 2018-11-17 11:57 | 只看该作者
有点复杂
回复

使用道具 举报

板凳
zjyzjy 发表于 2019-1-20 21:04 | 只看该作者
发送和接收模块的代码都有吗
回复

使用道具 举报

地板
zjyzjy 发表于 2019-1-21 10:00 | 只看该作者

protues仿真用的是的IRLINK模块吗?
回复

使用道具 举报

5#
蒜毫炒肉 发表于 2019-3-30 11:54 | 只看该作者
老哥,发送代码里,那个发送9ms起始码,endcount为什么是223呀?不是每个中断的时间为26us吗? 26*223=5798us ,是这样算的吗?
回复

使用道具 举报

6#
kc乐乐 发表于 2019-9-19 15:41 | 只看该作者
非常好的东西,学习啦
回复

使用道具 举报

7#
WS15 发表于 2020-1-26 14:13 | 只看该作者
仿真图
回复

使用道具 举报

8#
xiushen999 发表于 2020-3-2 20:43 | 只看该作者
有其它遥控类分享么
回复

使用道具 举报

9#
ying007 发表于 2020-11-22 14:38 | 只看该作者
比较复杂。。。学习中
回复

使用道具 举报

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

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表