模吧

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

22014查看 | 53回复

[单片机课堂] 第十六课:扩展课!万能的电子开关

  [复制链接]
发表于 2016-12-15 03:58:18 | 显示全部楼层 |阅读模式

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

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

x
航模用的电子开关主要用途就是检测接收机的PWM信号,控制其他设备的供电。因此,它的用途实际上非常广泛:控制灯带、控制点火器、控制喇叭……
而实际上,它的程序非常简单!
马上你就会恍然大悟,原来只需要几行代码,就可以实现曾经遥不可及的功能。




随着你们学习的越来越多,其实现在已经有能力去独立做一些简单的小东西了。
本次课程完全没有涉及到任何新知识,都是过去知识点的组合。
本课的主要内容:自主发挥,项目练手



 楼主| 发表于 2016-12-15 04:55:02 | 显示全部楼层
1.1 测量PWM信号


前面学到,舵机测试仪控制舵机的信号,是用PWM高电平时间的长度,1ms~2ms;航模接收机的输出信号,也是一样的。
电子开关的原理,就是把自己“伪装”成一个“舵机”,如果收到1ms的高电平信号,就关闭开关;如果收到2ms的高电平信号,就打开开关。
现在如果还没有航模接收机,可以先用舵机测试仪代替。


如何测量高电平的时间?你是不是有些似曾相识。对的,在《红外接收机》课程中,已经学过了检测低电平时间。
只需要把红外接收的程序稍微修改下,就是一个万能的电子开关!


检测高电平时间:
while(IN==1)  //如果引脚一直为高电平,一直循环
{
    Delay10us();
    time=time+1;  //每循环一次,就记录了10us时间
}



判断高电平时间:
if(time>90&&time<120)OUT=0;//允许一定的误差,0.9ms~1.2ms高电平信号都可以关闭开关
if(time>180&&time<210)OUT=1;//允许一定的误差,1.8ms~2.1ms高电平信号都可以打开开关


简单例程:
  1. #include<reg51.h>
  2. #include<intrins.h>

  3. sfr P3M0=0xb2;     //声明 引脚输出模式寄存器

  4. sbit IN=P3^4;     //定义PWM输入引脚
  5. sbit OUT=P3^3;    //定义输出引脚

  6. unsigned int time;    //记录时间

  7. void Delay10us()                //@12.000MHz
  8. {
  9.         unsigned char i;
  10.        
  11.         _nop_();//使用《舵机测试仪》课程中调整过的延时程序
  12.         _nop_();
  13.         i = 24;
  14.         while (--i);
  15. }

  16. main()
  17. {
  18.         OUT=0;        //先关闭输出
  19.         P3M0=8;    //P3.3引脚大电流模式
  20.        
  21.         while(1)
  22.         {
  23.        
  24.                 if(IN==1)        //收到PWM高电平,开始测量
  25.                 {
  26.                         time=0;  //先把时间清零
  27.                         while(IN==1)  //如果引脚一直为高电平,一直循环
  28.                         {
  29.                                 Delay10us();
  30.                                 time=time+1;  //每循环一次,就记录了10us时间
  31.                         }
  32.                         //引脚变成低电平,循环结束
  33.                        
  34.                         if(time>90&&time<120)//0.9ms~1.2ms高电平
  35.                         {
  36.                                 OUT=0;  //关闭开关
  37.                         }       
  38.                        
  39.                         if(time>180&&time<210)//1.8ms~2.1ms高电平
  40.                         {
  41.                                 OUT=1;  //打开开关
  42.                         }                               
  43.                 }
  44.                
  45.                
  46.         }
  47. }
复制代码





 楼主| 发表于 2016-12-17 05:51:58 | 显示全部楼层
1.2 项目扩展


电子开关的强大就在于它灵活的扩展性:
扩展方向1:夜航灯控
    不仅能控制灯带的亮灭,通过编程,还能够实现多种模式:开关变化一次,灯带切换一个模式,如常亮、爆闪、双闪……等;
扩展方向2:点火器
    开关动作后,点火两秒钟自动关闭;
扩展方向3:左右转向灯
    1.5ms高电平舵机在中间,小于1.4说明左转弯亮左灯,大于1.6说明右转弯亮右灯;
扩展方向4:多路开关
    控制四路,开关变化一次切换一路开关;
5:……………………………………
6:……………………………………


各种各样电子开关能实现的功能,只有你想不到,没有做不到。学会单片机,有什么需求直接自己动手实现!


在这里,给出一个实现一路灯控的例程,更多的功能,就要靠你自己的发挥练习了:


顺便学点小知识
知识点(53) #define 声明替换
写程序中我们经常遇到要写“unsigned char”这么一长串英文,有没有什么办法能够更简便点?在C程序中,还提供了一种替换机制:
#define A B  //如果声明了这句话,那么以后在程序中写A,编译时会自动被系统替换成B。
利用这个机制,可以简写,比如:
#define u8 unsigned char  //“unsigned char”是0~255的8位二进制数,我们以后可以简写为“u8”
#define u16 unsigned int  //“unsigned int”是0~65535的16位二进制数,我们以后可以简写为“u16”



知识点(54) n++;自己加一
同样是为了简写程序,以后遇到“n=n+1;”这样自己增加1的,可以用两个加号代替:“n++;”
同样的,“n=n-1;”也可以简写为“n--;”


  1. #include<reg51.h>
  2. #include<intrins.h> //使用Nop()需要先声明
  3. #define u8 unsigned char  //“unsigned char”是0~255的8位二进制数,我们以后可以简写为“u8”
  4. #define u16 unsigned int  //“unsigned int”是0~65535的16位二进制数,我们以后可以简写为“u16”

  5. sfr P3M0=0xb2;     //声明 引脚输出模式寄存器

  6. sbit IN=P3^4;     //定义PWM输入引脚
  7. sbit OUT=P3^3;    //定义输出引脚

  8. u16 time;    //记录时间
  9. u16 delay_time;   //记录时间

  10. u8 Key1;        //把高电平时间变化当做学过的按键处理
  11. u8 Key1_old;    //记录Key1过去出现低电平

  12. u8 mode;     //模式
  13. u8 step;     //步骤

  14. void Delay10us()                //@12.000MHz
  15. {
  16.         unsigned char i;
  17.        
  18.         _nop_();//使用《舵机测试仪》课程中调整过的延时程序
  19.         _nop_();
  20.         i = 24;
  21.         while (--i);
  22. }


  23. main()
  24. {
  25.         OUT=0;        //先关闭输出
  26.         P3M0=8;    //P3.3引脚大电流模式
  27.         Key1_old=1;
  28.        
  29.         while(1)
  30.         {
  31.                 Delay10us();//系统周期10us
  32.                 //模式处理与《七色光芒》几乎相同
  33.                 if(mode==0)//模式0,关闭
  34.                 {
  35.                         OUT=0;
  36.                 }
  37.                
  38.                 if(mode==1)//模式1,打开
  39.                 {
  40.                         OUT=1;
  41.                 }
  42.                
  43.                 if(mode==2)//模式2,闪烁
  44.                 {
  45.                         delay_time++;
  46.                         if(delay_time>20000)//每过0.2秒
  47.                         {
  48.                                 delay_time=0;
  49.                                
  50.                                 if(OUT==1)OUT=0;//变化一次
  51.                                 else OUT=1;
  52.                         }
  53.                 }
  54.                
  55.                 if(mode==3)//模式3,双闪
  56.                 {
  57.                         delay_time++;
  58.                         if(delay_time>20000)//每过0.2秒
  59.                         {
  60.                                 delay_time=0;
  61.                                 step++;
  62.                                 if(step>5)step=0;//双闪变化较多,分为6个步骤
  63.                         }
  64.                        
  65.                         if(step==0)//步骤0,亮
  66.                         {
  67.                                 OUT=1;
  68.                         }
  69.                         if(step==1)//步骤1,灭
  70.                         {
  71.                                 OUT=0;
  72.                         }
  73.                         if(step==2)//步骤2,亮
  74.                         {
  75.                                 OUT=1;
  76.                         }
  77.                         if(step==3)//步骤3,灭
  78.                         {
  79.                                 OUT=0;
  80.                         }
  81.                         if(step==4)//步骤4,灭
  82.                         {
  83.                                 OUT=0;
  84.                         }
  85.                         if(step==5)//步骤5,灭
  86.                         {
  87.                                 OUT=0;
  88.                         }
  89.                 }
  90.                
  91.                 if(IN==1)        //收到PWM高电平,开始测量
  92.                 {
  93.                         time=0;  //先把时间清零
  94.                         while(IN==1)  //如果引脚一直为高电平,一直循环
  95.                         {
  96.                                 Delay10us();
  97.                                 time=time+1;  //每循环一次,就记录了10us时间
  98.                         }
  99.                         //引脚变成低电平,循环结束
  100.                        
  101.                         if(time>90&&time<120)//0.9ms~1.2ms高电平
  102.                         {
  103.                                 Key1=1;  //相当于按键还没按下
  104.                         }       
  105.                        
  106.                         if(time>180&&time<210)//1.8ms~2.1ms高电平
  107.                         {
  108.                                 Key1=0;  //相当于按键按下
  109.                         }               

  110.                         if(Key1==1&&Key1_old==0)//如果本次是1并且上次是0,检测到0~1的变化
  111.                         {
  112.                                 mode++;
  113.                                 if(mode>3)mode=0;//检测到信号的变化,切换模式
  114.                         }
  115.                         Key1_old=Key1;     //保存
  116.                        
  117.                        
  118.                 }
  119.                
  120.                
  121.         }
  122. }
复制代码





发表于 2017-6-14 15:38:21 | 显示全部楼层
谢谢分享,学习了
回复 支持 1 反对 1

使用道具 举报

发表于 2022-4-6 15:18:06 | 显示全部楼层
好东西,能分享,这是境界啊!
回复 支持 0 反对 1

使用道具 举报

发表于 2021-7-16 02:52:08 | 显示全部楼层
第十六课:扩展课!万能的电子开关 接收机 作者:2940135603 3233 第十六课:扩展课!万能的电子开关 接收机 作者:2940135603 4879 第十六课:扩展课!万能的电子开关 接收机 作者:2940135603 4083 {:1_9:}{:1_9:}{:1_9:}
回复 支持 1 反对 0

使用道具 举报

发表于 2021-4-9 18:16:20 | 显示全部楼层

楼主,辛苦了。
回复 支持 0 反对 1

使用道具 举报

发表于 2020-7-8 17:23:52 来自手机 | 显示全部楼层
学习了谢谢分享
回复 支持 1 反对 0

使用道具 举报

发表于 2020-2-15 23:38:19 | 显示全部楼层
体育日体育 与人突然如
回复 支持 0 反对 1

使用道具 举报

发表于 2020-2-15 23:20:31 | 显示全部楼层
学习了,谢谢大佬分享
回复 支持 0 反对 1

使用道具 举报

发表于 2019-10-12 18:07:33 | 显示全部楼层
现在才知道萝莉大神有这么多教程,我看我是离不开萝莉了第十六课:扩展课!万能的电子开关 接收机 作者:13164317466 9011 第十六课:扩展课!万能的电子开关 接收机 作者:13164317466 4499
回复 支持 1 反对 0

使用道具 举报

发表于 2019-10-4 00:40:09 | 显示全部楼层
真好。开源后有很多玩法。谢谢了
回复 支持 0 反对 1

使用道具 举报

发表于 2018-12-8 01:20:14 | 显示全部楼层
正在慢慢的学代码门外汉吃力啊
回复 支持 0 反对 1

使用道具 举报

发表于 2016-12-15 04:45:52 | 显示全部楼层
路过,
发表于 2016-12-15 06:45:44 | 显示全部楼层
赞赞赞,强势围观
发表于 2016-12-15 06:58:15 | 显示全部楼层
怎么不出视频教程
发表于 2016-12-15 07:42:19 | 显示全部楼层
看程序还是有点懵啊!
发表于 2016-12-15 08:23:04 | 显示全部楼层
本帖最后由 Myth 于 2016-12-15 08:35 编辑

我觉得萝莉老师可以出个收费视频教程。
写这么清楚的教程还不满足,收点智商税也不为过。
发表于 2016-12-15 08:27:00 | 显示全部楼层
嗯嗯,好好学习下……
发表于 2016-12-15 08:33:26 | 显示全部楼层
Myth 发表于 2016-12-15 08:23 第十六课:扩展课!万能的电子开关 接收机 作者:Dk. 9010
我觉得泡泡老师可以出个收费视频教程。
写这么清楚的教程还不满足,收点智商税也不为过。 ...

你跑错地方了吧?
发表于 2016-12-15 08:34:36 | 显示全部楼层
Dk. 发表于 2016-12-15 08:33
你跑错地方了吧?

看到五楼的回复有感而发。。。好吧确实说错人了。。。
发表于 2016-12-15 08:36:26 | 显示全部楼层
Myth 发表于 2016-12-15 08:34 第十六课:扩展课!万能的电子开关 接收机 作者:Dk. 4624
看到五楼的回复有感而发。。。好吧确实说错人了。。。

好吧,如果收费的话搞不起来的
发表于 2016-12-15 10:32:13 | 显示全部楼层
强寺顶贴
发表于 2016-12-15 12:27:30 | 显示全部楼层
厉害了
发表于 2016-12-15 16:01:59 | 显示全部楼层
厉害,学习一下
发表于 2016-12-15 16:28:28 | 显示全部楼层
路过,,收藏了,感谢楼主的无私分享
发表于 2016-12-15 20:13:00 | 显示全部楼层
在学习,等待更新。。。。。。。。。。。。。。
发表于 2016-12-15 23:09:00 | 显示全部楼层

祝贺萝莉大神又开新帖
感谢大神解惑成功点亮jlx12864
我一直想做一个简易的高脉宽测试仪
看了老师的新帖感觉有点眉目了
如果利用电子开关的核心程序
来测接收机输出的高脉宽并用数码管
显示出来是否只要把time拆成个十百千位显示出来就可以

点评

是的  详情 回复 发表于 2016-12-16 00:47
 楼主| 发表于 2016-12-16 00:47:09 | 显示全部楼层
ldy7474 发表于 2016-12-15 23:09
祝贺萝莉大神又开新帖
感谢大神解惑成功点亮jlx12864
我一直想做一个简易的高脉宽测试仪

是的
发表于 2016-12-16 10:04:55 | 显示全部楼层

好很好非常好这样就不用外部中断了真好  我一直在头痛用15w204外部中断被数码管占用  这短短的几行代码完全解决问题哈哈…
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

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