模吧

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

20738查看 | 72回复

[单片机课堂] 第九课:看不见的信使——红外线

  [复制链接]
发表于 2016-10-28 05:16:41 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

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

x
本帖最后由 我爱萝丽爱萝丽 于 2016-10-29 04:57 编辑

从这一课开始学习第二个项目:红外遥控器。遥控器无论是搞智能家居还是搞DIY都是不可缺少的东西,远距离遥控加上单片机智能处理,让你轻轻抬一抬手指就能实现以往不可想象的事情。


通过练习第一个项目,你已经跨过了单片机的“门槛”,但是还没有真正入门,想要真正走进单片机的大堂,你还需要很多努力。


本课主要内容是构建一套简易的遥控器、接收机。

第九课:看不见的信使——红外线 遥控器 作者:我爱萝丽爱萝丽 7066

评分

参与人数 1牛币 +10 收起 理由
爱上模型DIY + 10 很给力!

查看全部评分

 楼主| 发表于 2016-10-29 05:24:03 | 显示全部楼层
1.1 还记得程序怎么写吗

第一个项目之后,不知道你有没有自己做练习?三日不做而手生,如果忘记怎么新建工程了,赶紧回去复习吧。


电路焊接好以后先做什么?要先写一个小程序试试你的电路工作了没。
红外接收头在收到信号时会输出低电平,没有信号时会输出高电平。这个电平人眼不能看到,所以你需要用一个LED发光来指示是否收到信号。


你需要新建一个项目文件夹、新建一个工程,新写一个程序:

可以先拿现成的空调、电视遥控器来测试下,按下按键时LED会闪,说明我们的接收机已经成功收到信号了!

第九课:看不见的信使——红外线 遥控器 作者:我爱萝丽爱萝丽 1288

回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-10-30 05:24:48 | 显示全部楼层
1.2 发射38kHz红外信号


什么是红外线?红外线也是光的一种,只是人眼看不见而已。所有的物体都会发射红外线,电灯也会发射红外线,为什么开了灯红外接收机的灯不亮,只有按下电视遥控器灯才会亮?
这是因为在红外接收头里,已经秘密做了协议,只有收到闪烁频率为38KHz的红外线,才会认为有正确信号。
也就是说,如果你能把一个手电筒一秒内开关3万8千次,就可以被红外接收机识别。


人没有那么快,但是神奇的单片机可以啊,一秒开关一百万次都轻松,你需要动脑筋想想怎么去写程序实现?


很简单,算一下38KHz的周期大概是26微秒,让遥控器发射13微秒红外线,再关闭13微秒,循环发射即可。


按下按键就能让接收机有反应的程序:
第九课:看不见的信使——红外线 遥控器 作者:我爱萝丽爱萝丽 7244
回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-10-30 18:14:27 | 显示全部楼层
本帖最后由 我爱萝丽爱萝丽 于 2016-11-1 00:55 编辑

1.3 引脚推挽输出模式

做完1.2,你应该会发现我们的遥控器距离没有电视的遥控器距离远,几米外就没反应了。为什么?


复习知识点(11),这是因为现在单片机的高电平输出电流只有不到1ma,发射的红外线太小。
除了像第一个项目一样用三极管放大电流,只驱动一个LED的话,还可以直接使用单片机20ma电流的推挽输出模式。


知识点(38) 声明特殊寄存器 sfr P3M0=0xb2;

sfr 是声明寄存器的关键词;
P3M0 是设置P3口输出模式的寄存器;
0xb2 是P3M0这个寄存器的地址。
就跟sbit声明单片机引脚一样,声明之后程序里就可以使用。


知识点(39) <reg51.h>里装了什么
有足够好奇心的话你可以右键reg51、open打开看一看。其实里面都是寄存器声明哦,以后学习会逐个用到。
至于P3M0寄存器,是新型STC单片机新加入的,所以你要自己声明。


知识点(40) P3M0寄存器是什么
什么是寄存器?你可以想象为一个寄存器里有8个小房间,每个房间控制一个引脚,可以装1或者0,1代表打开推挽模式,0代表关。
第九课:看不见的信使——红外线 遥控器 作者:我爱萝丽爱萝丽 5258


知识点(41) 设置寄存器
怎么设置?直接写P3M0=0010 0000吗?
当然不是,我们人类用的是10进制,计算机用的是二进制,需要先换算才能正确写。
我知道很多人一想到进制之间的换算就会头晕,所以我推荐你使用电脑自带的强大工具“计算器”
打开Windows计算器工具,选择程序员选项:
第九课:看不见的信使——红外线 遥控器 作者:我爱萝丽爱萝丽 3214
点击BIN二进制选项,输入0010 0000,(最前面的0不起作用)
你会看到DEC十进制选项里已经自动转换成10进制32,所以正确的设置应该是P3M0=32;
同时HEX十六进制选项里也显示了20,写成P3M0=0x20;也是可以的,加上0x代表16进制。 第九课:看不见的信使——红外线 遥控器 作者:我爱萝丽爱萝丽 9335



改了程序以后遥控距离瞬间提高十米:
  1. #include<reg51.h>

  2. sfr P3M0=0xb2;     //声明寄存器

  3. sbit IR_LED=P3^5;  //定义红外LED引脚
  4. sbit Key1=P3^0;    //定义按键1

  5. void Delay13us()                //@12.000MHz
  6. {
  7.         unsigned char i;

  8.         i = 36;   
  9.         while (--i);
  10. }

  11. main()
  12. {
  13.         P3M0=32;      //设置P3.5引脚为大电流模式

  14.         while(1)
  15.         {
  16.                 if(Key1==0)        //按键按下变成低电平
  17.                 {
  18.                         IR_LED=1;        //发射38KHz方波红外信号
  19.                         Delay13us();
  20.                         IR_LED=0;
  21.                         Delay13us();
  22.                 }
  23.                 else
  24.                 {
  25.                         IR_LED=0;
  26.                 }
  27.         }
  28. }
复制代码



回复 支持 1 反对 0

使用道具 举报

 楼主| 发表于 2016-11-1 03:58:32 | 显示全部楼层
本帖最后由 我爱萝丽爱萝丽 于 2016-11-1 04:18 编辑

1.4 制定一个简单的通信协议


实验到这里,还有一个很不爽的问题需要解决:别的遥控器也能控制我们的接收机!
怎样让电视的遥控器只能控制电视,我们的遥控器只控制我们的呢?


这就跟二战时的电台谍战一样了,我们的电台可以收到敌人的信息,敌人的电台也能收到我们的,当时是怎么保密的呢?
欲保密,先加密。
制定一套跟别人不同的通信协议,就能让别的遥控器对你失灵了!


电视遥控器的通信协议很复杂,我们不必学他,给自己添烦恼,而是另辟蹊径,自己定义自己的协议。
这里先举个例子,定义一个超简单的协议:
发射20ms红外信号,代表按键1;
发射30ms红外信号,代表按键2;
发射40ms红外信号,代表按键3……
是不是特别简单(∩_∩)


在上一小节,我们发射红外的程序,发射一次是26微秒,发射100次才2.6ms,20ms需要769次。
用程序控制循环的时间,是不是跟以前的学的delay_n_ms()类似?如果忘记可以回去复习一下知识点(18)。
void TX_IR(unsigned int n)//发射N个红外信号 时间是26us*N
{
        while(n)
        {
                IR_LED=1;        //发射一个38KHz方波红外信号
                Delay13us();
                IR_LED=0;
                Delay13us();
               
                n=n-1;  
        }
}





遥控器用旧知识可以搞定,接收机要测量时间需要新技能:
知识点(42) 用while测量低电平时间
while(IR_IN==0)  //如果引脚一直为低电平,一直循环
{
    Delay1ms();
    time=time+1;  //每循环一次,就记录了1ms时间
}
循环程序不仅可以用来延时,还可以用来计时。当引脚变成高电平1时,IR_IN==0就不是“真”的了,
循环自动结束,这时看time的值就知道时间过去多少毫秒了。


当遥控器发射了20ms,由于环境的干扰,接收机可能收到20ms,也可能只收到18ms,有没有办法判断一个范围呢?
知识点(43) && “并且”运算符
if(time>15 && time<25)
两个&&代表“并且”的意思,time大于15,并且小于25,两个都正确才行。
用这样的方式,可以同时判断两个条件。


接收机参考程序,遥控器可以控制接收机的亮灭,更多功能就要看大家自己的练习了。甚至可以和第一个项目结合起来,遥控控制七色光芒。大家可以把自己的程序上传上来相互交流。
  1. #include<reg51.h>

  2. sbit LED=P3^5;    //定义指示灯
  3. sbit IR_IN=P3^4;  //定义红外接收头引脚


  4. unsigned char time;    //定义一个数据,记录时间


  5. void Delay1ms()                //@12.000MHz
  6. {
  7.         unsigned char i, j;

  8.         i = 12;
  9.         j = 169;
  10.         do
  11.         {
  12.                 while (--j);
  13.         } while (--i);
  14. }


  15. main()
  16. {
  17.         
  18.         while(1)
  19.         {
  20.                
  21.                 if(IR_IN==0)        //收到红外数据引脚变成低电平,开始测量
  22.                 {
  23.                         time=0;  //先把时间清零
  24.                         while(IR_IN==0)  //如果引脚一直为低电平,一直循环
  25.                         {
  26.                                 Delay1ms();
  27.                                 time=time+1;  //每循环一次,就记录了1ms时间
  28.                         }
  29.                         //引脚变成高电平,循环结束
  30.                         
  31.                         if(time>15&&time<25)//16ms~24ms低电平,按键1按下
  32.                         {
  33.                                 LED=1;
  34.                         }        
  35.                         
  36.                         if(time>25&&time<35)//26ms~34ms低电平,按键2按下
  37.                         {
  38.                                 LED=0;
  39.                         }                                
  40.                 }
  41.                
  42.         }
  43. }
复制代码


遥控器参考程序:
  1. #include<reg51.h>

  2. sfr P3M0=0xb2;     //声明寄存器

  3. sbit IR_LED=P3^5;  //定义红外LED引脚
  4. sbit Key1=P3^0;    //定义按键1
  5. sbit Key2=P3^1;    //定义按键2


  6. unsigned char Key1_old;    //定义一个数据,记录Key1过去出现低电平
  7. unsigned char Key1_action; //定义一个数据,传递Key1是否动作的消息
  8. unsigned char Key2_old;    //定义一个数据,记录Key2过去出现低电平
  9. unsigned char Key2_action; //定义一个数据,传递Key2是否动作的消息


  10. void Delay1ms()                //@12.000MHz
  11. {
  12.         unsigned char i, j;

  13.         i = 12;
  14.         j = 169;
  15.         do
  16.         {
  17.                 while (--j);
  18.         } while (--i);
  19. }

  20. void delay_n_ms(unsigned int n) //自己定义的延时n毫秒函数
  21. {
  22.         while(n)         
  23.         {
  24.                 Delay1ms();
  25.                 n=n-1;//每循环一次n减小1
  26.         }   
  27. }


  28. void Delay13us()                //@12.000MHz
  29. {
  30.         unsigned char i;

  31.         i = 36;   
  32.         while (--i);
  33. }

  34. void TX_IR(unsigned int n)//发射N个红外信号 时间是26us*N
  35. {
  36.         while(n)
  37.         {
  38.                 IR_LED=1;        //发射一个38KHz方波红外信号
  39.                 Delay13us();
  40.                 IR_LED=0;
  41.                 Delay13us();
  42.                            
  43.                 n=n-1;  
  44.         }
  45. }


  46. main()
  47. {
  48.         IR_LED=0;//关闭红外LED
  49.         P3M0=32;      //设置P3.5引脚为大电流模式
  50.         
  51.         Key1_old=1;   //进入循环前,先初始化标志位。按键还没按下,old是高电平
  52.         Key2_old=1;
  53.         
  54.         while(1)   
  55.         {

  56.                 delay_n_ms(10);   //系统周期,每循环一次10ms
  57.                                     
  58.                         
  59.                 if(Key1==1)
  60.                 {
  61.                         if(Key1_old==0) //如果本次是高电平,上次是低电平,检测到按键
  62.                         {
  63.                                 Key1_action=1;                                                                        
  64.                         }
  65.                 }
  66.                
  67.                 Key1_old=Key1;     //保存高低电平


  68.                 if(Key2==1)
  69.                 {
  70.                         if(Key2_old==0) //如果本次是高电平,上次是低电平,检测到按键
  71.                         {
  72.                                 Key2_action=1;                                                                        
  73.                         }
  74.                 }
  75.                
  76.                 Key2_old=Key2;     //保存高低电平
  77.                
  78.                                 
  79.                 //上面是完全模块化的按键检测程序,只传递出两个action消息
  80.                 ////////////////////////////////////////////
  81.                
  82.                 if(Key1_action==1)  //有按键消息,处理按键功能
  83.                 {
  84.                         Key1_action=0;   //处理过按键后要清0
  85.                         
  86.                         TX_IR(769);  //按键1发射20ms红外
  87.                 }
  88.                
  89.                 if(Key2_action==1)  //有按键消息,处理按键功能
  90.                 {
  91.                         Key2_action=0;   //处理过按键后要清0
  92.                         
  93.                         TX_IR(1153);  //按键2发射30ms红外
  94.                 }
  95.                
  96.                
  97.         }
  98. }
复制代码



回复 支持 3 反对 0

使用道具 举报

发表于 2022-4-7 14:16:44 | 显示全部楼层
本节课圆满结束
回复 支持 1 反对 0

使用道具 举报

发表于 2022-4-6 15:10:36 | 显示全部楼层
深入浅出,通俗易懂
回复 支持 0 反对 1

使用道具 举报

发表于 2020-7-23 16:58:41 | 显示全部楼层
xuexi学习学习了厉害厉害
回复 支持 0 反对 1

使用道具 举报

发表于 2019-4-23 00:01:50 | 显示全部楼层
厉害厉害,我来领牛币
回复 支持 1 反对 0

使用道具 举报

发表于 2019-1-10 08:50:20 | 显示全部楼层
学习到了,给楼主赞个
回复 支持 1 反对 0

使用道具 举报

发表于 2018-11-12 10:57:32 | 显示全部楼层
学习了
回复 支持 1 反对 0

使用道具 举报

发表于 2018-11-11 10:04:13 | 显示全部楼层
谢谢老师,通俗易懂!第九课:看不见的信使——红外线 遥控器 作者:独行者 5785
回复 支持 1 反对 0

使用道具 举报

发表于 2018-10-25 22:35:09 | 显示全部楼层
谢谢老师 在学习中
回复 支持 0 反对 1

使用道具 举报

发表于 2018-2-5 22:25:45 | 显示全部楼层
咦,红外的程序这么简单吗,我以前用的外部中断
回复 支持 1 反对 0

使用道具 举报

发表于 2016-10-28 06:21:08 | 显示全部楼层
是沙发吗
发表于 2016-10-28 06:22:55 | 显示全部楼层
顶顶
发表于 2016-10-28 06:59:22 | 显示全部楼层
顶顶顶
发表于 2016-10-28 07:22:12 | 显示全部楼层
就讲的这么简单
发表于 2016-10-28 08:02:41 | 显示全部楼层
认真学习,持续关注
发表于 2016-10-28 09:23:52 | 显示全部楼层
萝莉回归了吗
发表于 2016-10-28 10:24:50 | 显示全部楼层
慢慢等更
发表于 2016-10-28 12:17:23 | 显示全部楼层
大神快更新,苦等了一周了,哈哈,希望大神在发射和接受程序上多一些注释,这样学起来会更容一些易。,那个红外发射的按键接线有点看不清,是把开关一端全部接地,另一端分别接5个io口不?

点评

是的  详情 回复 发表于 2016-10-29 04:56
发表于 2016-10-28 12:25:45 | 显示全部楼层
顶顶顶
回复 支持 1 反对 0

使用道具 举报

发表于 2016-10-28 15:41:54 | 显示全部楼层
学习了,
发表于 2016-10-28 15:56:27 | 显示全部楼层
暖贴暖贴暖贴暖贴
发表于 2016-10-28 16:39:42 来自手机 | 显示全部楼层
顶         顶         顶
发表于 2016-10-29 00:08:34 | 显示全部楼层
收藏了,谢谢!
发表于 2016-10-29 00:11:02 | 显示全部楼层
支持萝莉,辛苦了。
 楼主| 发表于 2016-10-29 04:56:54 | 显示全部楼层
我是天才 发表于 2016-10-28 12:17
大神快更新,苦等了一周了,哈哈,希望大神在发射和接受程序上多一些注释,这样学起来会更容一些易。,那个 ...

是的
发表于 2016-10-29 10:51:17 | 显示全部楼层
学习
发表于 2016-10-29 14:14:20 | 显示全部楼层


哈哈,终于刷到更新了,发射和接受都做完了,接受用的电视遥控器,成功点亮,心里那个高兴啊,哈哈,期待发射程序
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|关于模吧|APP下载|广告报价|小黑屋|手机版|企业会员|商城入驻|联系我们|模吧 ( 冀公网安备13080502000084号 )

© 2013-2020 Moz8.com 模吧,玩出精彩!