找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 6315|回复: 10
收起左侧

51单片机红外线接收系统设计文档(原理详解+源程序)

  [复制链接]
ID:664394 发表于 2019-12-15 16:21 | 显示全部楼层 |阅读模式
希望对有需要的人有所帮助

红外线接收系统,是基于51单片机的普通红外线接收器,

图1 红外线接收器原理图
2.1.首先我们先解释一下红外线:

                            人的眼睛能看到的可见光按波长从长到短排列,依次为红、橙、黄、绿、青、蓝、紫。其中红光的波长范围为0.62~0.76μm;紫光的波长范围为0.38~0.46μm。比紫光波长还短的光叫紫外线,比红光波长还长的光叫红外线.红外线遥控就是利用波长为0.76~1.5μm之间的近红外线来传送控制信号的。

2.2 对于红外接收器而言  

红外接收设备是由红外接收电路、红外解码、电源和应用电路组成。红外遥控接收器的主要作用是将遥控发射器发来的红外光信好转换成电信号,再放大、限幅、检波、整形,形成遥控指令脉冲,输出至遥控微处理器。近几年不论是业余制作还是正式产品,大多都采用成品红外接收头。成品红外接收头的封装大致有两种:一种采用铁皮屏蔽;一种是塑料封装。均有三只引脚,即电源正(VDD)、电源负(GND)和数据输出(VOUT)。在使用时注意成品红外接收头的载波频率,另外在遥控编码芯片输出的波形与接收头端收到的波形。

2.3我们此次的红外线接收系统主要是对于遥控器所发出的红外线,对她进行接收和解码从而发送到数码管、小灯、蜂鸣器等等让其做出相应的反应。

①发送:通常的红外遥控通常为了提高抗干扰性能和降低电源消耗,红外遥控器常用载波的方式传送二进制编码,常用的载波频率为38kHz,这是由发射端所使用的455kHz晶振来决定的。在发射端要对晶振进行整数分频,分频系数一般取12,所以455kHz÷12≈37.9kHz≈38kHz。也有一些遥控系统采用36kHz、40 kHz、56 kHz等,一般由发射端晶振的振荡频率来决定。所以,通常的红外遥控器是将遥控信号(二进制脉冲码)调制在38KHz的载波上,经缓冲放大后送至红外发光二极管,转化为红外信号发射出去的。

②接收:二进制脉冲码的形式有多种,其中最为常用的是PWM码(脉冲宽度调制码)和PPM码(脉冲位置调制码,脉冲串之间的时间间隔来实现信号调制)。如果要开发红外接收设备,一定要知道红外遥控器的编码方式和载波频率,我们才可以选取一体化红外接收头和制定解码方案。

发送端接收端
图2.红外原理图

我们通过对发送端进行编码进行合理控制从而发出数据让接收端收到一定的波形图送到数码管因为接收之后解码出来是ASC||码所以我们需要进行一定的转换。

2.4单片机只能识别二进制数字所以我们对于数据的发送的传输以及接受需要很谨慎。接收和发送的数据码格式一共分为四组:原码、原码的反码、数据码、数据反码。
图3.时序图

在起始码之前我们需要先给一定的延时(大约七到八毫秒)判断是否已经开始接收到真正的信号然后定义一个延时子函数让他自加如果大约十毫秒左右没有反应说明发送出了问题,如果接收到真正的信号同时之前的延时子函数也没有到达十毫秒就开始之后的起始码让其等待九毫秒的低电平然后再等待之后的四点五毫秒的高电平开始接受之后的字符串存入我们定义好的数组中。对于单片机的延时误差可能会很多我们在此考虑的是对于每一次的延时我们的下一都进行判断直到精确接受到为止。

3.硬件电路设计:
图4.单片机元器件分布

因为基于单片机的操作所以以51单片机为主,其中的硬件电路连接。

图5单片机原理图

本次设计我们主要用到的模块有以下几个:

图6.51单片机最小系统

这是我们所使用的51单片机的最小系统的原理图,我们通过编码对它的I/O口进行高低电平的控制,从而控制他的一些外设模块初始化完成一系列的操作十分方便,但是51单片机的处理速度较慢以及较少的I/O口和少的模块控制、内存问题只能处理一些简单一些的问题。

图7.蜂鸣器

蜂鸣器风味有源蜂鸣器和无源蜂鸣器,因为有源和无源的操作以及工作方式是不一样的,市面上以及单片机上配置蜂鸣器以无源蜂鸣器为主必须用交流电高低电平的来回转换控制它的发声,有源蜂鸣器是直流电源即可,大部分都是用来警报和音乐播放,其中我们用来报警。

图8数码管               图9.译码器

用的51单片机本身配置为七段数码管能显示数字和极个别文字分别为a,b,c,d,e,f,g,dp这八段dp为小数点位,给与高电平则亮同时八段也符合16进制来取值,控制显示。译码器则为三八线译码器,用P2.2,P2.3,P2.4来控制数码管的选择一共八位数码管从000-111来控制位选,则P0口用来控制段选。



  1. #include "reg52.h"                                         
  2. typedef unsigned int u16;               
  3. typedef unsigned char u8;
  4. sbit beep=P1^5;
  5. sbit k4=P3^3;
  6. sbit LSA=P2^2;
  7. sbit LSB=P2^3;
  8. sbit LSC=P2^4;
  9. sbit led1=P2^0;
  10. sbit IRIN=P3^2;
  11. //#define led P2
  12. u8 IrValue[6];
  13. u8 Time;
  14. u8 m;
  15. u8 DisplayData[8];
  16. u8 code smgduan[17]={
  17. 0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
  18. 0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0X76};
  19. void delay(u16 i)
  20. {
  21.               while(i--);                  //10us                                                                                      延时函数
  22. }
  23. void DigDisplay()
  24. {
  25.               u8 i;
  26.               for(i=0;i<3;i++)
  27.               {
  28.                             switch(i)            
  29.                             {
  30.                                           case(0):
  31.                                                         LSA=0;LSB=0;LSC=0; break;
  32.                                           case(1):                                                                                                                                            数码管
  33.                                                         LSA=1;LSB=0;LSC=0; break;                                             的选择
  34.                                           case(2):
  35.                                                         LSA=0;LSB=1;LSC=0; break;            
  36.                             }
  37.                             P0=DisplayData[2-i];//发送数据
  38.                             delay(100); //间隔一段时间扫描            
  39.                             P0=0x00;//消隐
  40.               }                           
  41. }
  42. /*void DigDisplay()
  43. {
  44.               P1=0;
  45.               P0=0x01;                                                                                                        适合于老
  46.               P1=m;                                                                                                                                   师的程序
  47.               delay(1);
  48. } */  //shi yong yu lao shi ban zi


  49. void IrInit()
  50. {
  51.               IT0=1;//下降沿触发
  52.               EX0=1;//打开中断0允许
  53.               IT1=1;//跳变沿出发方式(下降沿)                                          红外线
  54.               EX1=1;//打开INT1的中断允许。                                                        传输打
  55.               EA=1;              //打开总中断              开初始
  56.               IRIN=1;//初始化端口              化函数
  57. }
  58. void main()
  59. {            
  60.     unsigned int temp;
  61.               IrInit();
  62.               //zhongduan();
  63.               while(1)
  64.               {            
  65.                             DisplayData[0] = smgduan[m];                            数码管
  66.                             DisplayData[1] = smgduan[m];                            送位
  67.                             DisplayData[2] = smgduan[m];
  68.                   DigDisplay();
  69.                             temp++;
  70.                             delay(100);
  71.                  if(m==1)
  72.                   {
  73.                     beep=~beep;
  74.                   }
  75.                   if(temp>10)                                                                                    完成一系
  76.                             {                                                                                                                              列的动作
  77.                             if(m==2)
  78.                             {
  79.                                 led1=~led1;
  80.                                           temp=0;
  81.                             }                                                      
  82.                             }
  83.               }
  84. }
  85. void ReadIr() interrupt 0
  86. {
  87.               u8 j,k;
  88.               u16 err;
  89.               Time=0;                                                                     
  90.               delay(700);              //7ms
  91.               if(IRIN==0)                            //确认是否真的接收到正确的信号
  92.               {            
  93.                            
  94.                             err=1000;                                                        //1000*10us=10ms,超过说明接收到错误的信号            
  95.                             while((IRIN==0)&&(err>0))              //等待前面9ms的低电平过去                             
  96.                             {                                         
  97.                                           delay(1);
  98.                                           err--;
  99.                             }
  100.                             if(IRIN==1)                                          //如果正确等到9ms低电平
  101.                             {
  102.                                           err=500;
  103.                                           while((IRIN==1)&&(err>0))                            //等待4.5ms的起始高电平过去
  104.                                           {
  105.                                                         delay(1);
  106.                                                         err--;
  107.                                           }
  108.                                           for(k=0;k<4;k++)                            //共有4组数据
  109.                                           {                                                      
  110.                                                         for(j=0;j<8;j++)              //接收一组数据
  111.                                                         {

  112.                                                                       err=60;                           
  113.                                                                       while((IRIN==0)&&(err>0))//等待信号前面的560us低电平过去
  114.                                                                       {
  115.                                                                                     delay(1);
  116.                                                                                     err--;
  117.                                                                       }
  118.                                                                       err=500;
  119.                                                                       while((IRIN==1)&&(err>0))              //计算高电平的时间长度。
  120.                                                                       {
  121.                                                                                     delay(10);              //0.1ms
  122.                                                                                     Time++;
  123.                                                                                     err--;
  124.                                                                                     if(Time>30)
  125.                                                                                     {
  126.                                                                                                   return;
  127.                                                                                     }
  128.                                                                       }
  129.                                                                       IrValue[k]>>=1;              //k表示第几组数据
  130.                                                                       if(Time>=8)                                          //如果高电平出现大于565us,那么是1
  131.                                                                       {
  132.                                                                                     IrValue[k]|=0x80;
  133.                                                                       }
  134.                                                                       Time=0;                            //用完时间要重新赋值                                                                                                
  135.                                                         }
  136.                                           }
  137.                             }
  138.                             if(IrValue[2]!=~IrValue[3])
  139.                             {
  140.                                           return;
  141.                             }
  142.                                           if(IrValue[2]==0x16)
  143.                             {
  144.                                           m=0;
  145.                             }
  146.                             if(IrValue[2]==0x0c)
  147.                             {
  148.                                           m=1;
  149.                             }
  150.                                           if(IrValue[2]==0x18)
  151.                             {
  152.                                           m=2;
  153.                             }
  154.                                           if(IrValue[2]==0x5e)
  155.                             {
  156.                                           m=3;
  157.                             }
  158.                                           if(IrValue[2]==0x08)
  159.                             {
  160.                                           m=4;
  161.                             }
  162.                                           if(IrValue[2]==0x1c)
  163.                             {
  164.                                           m=5;
  165.                             }
  166.                                           if(IrValue[2]==0x5a)
  167.                             {
  168.                                           m=6;
  169.                             }
  170.                                           if(IrValue[2]==0x42)
  171.                             {
  172.                                           m=7;
  173.                             }
  174.                                           if(IrValue[2]==0x52)
  175.                             {
  176.                                           m=8;
  177.                             }
  178.                                           if(IrValue[2]==0x4a)
  179.                             {
  180.                                           m=9;
  181.                             }
  182.                                           if(IrValue[2]==0x40)
  183.                             {
  184.                                           m--;
  185.                             }
  186.                                           if(IrValue[2]==0x43)
  187.                             {
  188.                                           m++;
  189.                             }
  190.                                           if(IrValue[2]==0x46)
  191.                             {
  192.                                          
  193.                             }
  194.               }                                         
  195. }
复制代码

5.功能仿真与调试


完整的Word格式文档51黑下载地址:
文档.doc (7.55 MB, 下载次数: 65)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:666819 发表于 2019-12-17 23:31 | 显示全部楼层
使用了,确实能运行,谢谢楼主
回复

使用道具 举报

ID:110278 发表于 2020-3-5 11:06 | 显示全部楼层
很详细
回复

使用道具 举报

ID:663843 发表于 2020-3-5 23:35 | 显示全部楼层
看看,没币,下不了,暂时也不用。留个标记
回复

使用道具 举报

ID:693628 发表于 2020-3-6 07:22 来自手机 | 显示全部楼层
谢谢楼主分享了 收下了
回复

使用道具 举报

ID:686739 发表于 2020-3-16 16:45 来自手机 | 显示全部楼层
学习一下
回复

使用道具 举报

ID:738543 发表于 2020-4-26 15:11 | 显示全部楼层
我在protues里没有找到这个元件,怎么弄?
回复

使用道具 举报

ID:896273 发表于 2021-3-27 09:42 | 显示全部楼层
原理大概明白了,但程序执行却怎么都没有结果
回复

使用道具 举报

ID:954538 发表于 2021-7-23 08:33 | 显示全部楼层
后面应该会用到的,楼主牛逼
回复

使用道具 举报

ID:66328 发表于 2021-8-9 15:38 | 显示全部楼层
确实能运行,谢谢楼主
回复

使用道具 举报

ID:585365 发表于 2021-8-10 16:58 | 显示全部楼层
没有搞明白。还要继续看
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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