我爱萝丽爱萝丽 发表于 2016-12-15 03:58:18

第十六课:扩展课!万能的电子开关

航模用的电子开关主要用途就是检测接收机的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高电平信号都可以打开开关


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

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

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

unsigned int time;    //记录时间

void Delay10us()                //@12.000MHz
{
        unsigned char i;
       
        _nop_();//使用《舵机测试仪》课程中调整过的延时程序
        _nop_();
        i = 24;
        while (--i);
}

main()
{
        OUT=0;        //先关闭输出
        P3M0=8;    //P3.3引脚大电流模式
       
        while(1)
        {
       
                if(IN==1)        //收到PWM高电平,开始测量
                {
                        time=0;//先把时间清零
                        while(IN==1)//如果引脚一直为高电平,一直循环
                        {
                                Delay10us();
                                time=time+1;//每循环一次,就记录了10us时间
                        }
                        //引脚变成低电平,循环结束
                       
                        if(time>90&&time<120)//0.9ms~1.2ms高电平
                        {
                                OUT=0;//关闭开关
                        }       
                       
                        if(time>180&&time<210)//1.8ms~2.1ms高电平
                        {
                                OUT=1;//打开开关
                        }                               
                }
               
               
        }
}




我爱萝丽爱萝丽 发表于 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--;”


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

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

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

u16 time;    //记录时间
u16 delay_time;   //记录时间

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

u8 mode;   //模式
u8 step;   //步骤

void Delay10us()                //@12.000MHz
{
        unsigned char i;
       
        _nop_();//使用《舵机测试仪》课程中调整过的延时程序
        _nop_();
        i = 24;
        while (--i);
}


main()
{
        OUT=0;        //先关闭输出
        P3M0=8;    //P3.3引脚大电流模式
        Key1_old=1;
       
        while(1)
        {
                Delay10us();//系统周期10us
                //模式处理与《七色光芒》几乎相同
                if(mode==0)//模式0,关闭
                {
                        OUT=0;
                }
               
                if(mode==1)//模式1,打开
                {
                        OUT=1;
                }
               
                if(mode==2)//模式2,闪烁
                {
                        delay_time++;
                        if(delay_time>20000)//每过0.2秒
                        {
                                delay_time=0;
                               
                                if(OUT==1)OUT=0;//变化一次
                                else OUT=1;
                        }
                }
               
                if(mode==3)//模式3,双闪
                {
                        delay_time++;
                        if(delay_time>20000)//每过0.2秒
                        {
                                delay_time=0;
                                step++;
                                if(step>5)step=0;//双闪变化较多,分为6个步骤
                        }
                       
                        if(step==0)//步骤0,亮
                        {
                                OUT=1;
                        }
                        if(step==1)//步骤1,灭
                        {
                                OUT=0;
                        }
                        if(step==2)//步骤2,亮
                        {
                                OUT=1;
                        }
                        if(step==3)//步骤3,灭
                        {
                                OUT=0;
                        }
                        if(step==4)//步骤4,灭
                        {
                                OUT=0;
                        }
                        if(step==5)//步骤5,灭
                        {
                                OUT=0;
                        }
                }
               
                if(IN==1)        //收到PWM高电平,开始测量
                {
                        time=0;//先把时间清零
                        while(IN==1)//如果引脚一直为高电平,一直循环
                        {
                                Delay10us();
                                time=time+1;//每循环一次,就记录了10us时间
                        }
                        //引脚变成低电平,循环结束
                       
                        if(time>90&&time<120)//0.9ms~1.2ms高电平
                        {
                                Key1=1;//相当于按键还没按下
                        }       
                       
                        if(time>180&&time<210)//1.8ms~2.1ms高电平
                        {
                                Key1=0;//相当于按键按下
                        }               

                        if(Key1==1&&Key1_old==0)//如果本次是1并且上次是0,检测到0~1的变化
                        {
                                mode++;
                                if(mode>3)mode=0;//检测到信号的变化,切换模式
                        }
                        Key1_old=Key1;   //保存
                       
                       
                }
               
               
        }
}




davidxu 发表于 2017-6-14 15:38:21

谢谢分享,学习了

ggssccmyzb 发表于 2022-4-6 15:18:06

好东西,能分享,这是境界啊!

2940135603 发表于 2021-7-16 02:52:08

{:1_9:}{:1_9:}{:1_9:}{:1_9:}{:1_9:}{:1_9:}

龙飞凤 发表于 2021-4-9 18:16:20


楼主,辛苦了。

大海201079 发表于 2020-7-8 17:23:52

学习了谢谢分享

duan8896383 发表于 2020-2-15 23:38:19

体育日体育 与人突然如

chengx-i 发表于 2020-2-15 23:20:31

学习了,谢谢大佬分享

13164317466 发表于 2019-10-12 18:07:33

现在才知道萝莉大神有这么多教程,我看我是离不开萝莉了{:1_12:}{:1_12:}

xffd68 发表于 2019-10-4 00:40:09

真好。开源后有很多玩法。谢谢了

塞巴斯第安 发表于 2018-12-8 01:20:14

正在慢慢的学代码门外汉吃力啊

sjzzhsx 发表于 2016-12-15 04:45:52

路过,

Soar 发表于 2016-12-15 06:45:44

赞赞赞,强势围观

21wMZSZzjg 发表于 2016-12-15 06:58:15

怎么不出视频教程

小冰 发表于 2016-12-15 07:42:19

看程序还是有点懵啊!

Myth 发表于 2016-12-15 08:23:04

本帖最后由 Myth 于 2016-12-15 08:35 编辑

我觉得萝莉老师可以出个收费视频教程。
写这么清楚的教程还不满足,收点智商税也不为过。

RNjY8hXV2D 发表于 2016-12-15 08:27:00

嗯嗯,好好学习下……

Dk. 发表于 2016-12-15 08:33:26

Myth 发表于 2016-12-15 08:23 static/image/common/back.gif
我觉得泡泡老师可以出个收费视频教程。
写这么清楚的教程还不满足,收点智商税也不为过。 ...

你跑错地方了吧?

Myth 发表于 2016-12-15 08:34:36

Dk. 发表于 2016-12-15 08:33
你跑错地方了吧?
看到五楼的回复有感而发。。。好吧确实说错人了。。。

Dk. 发表于 2016-12-15 08:36:26

Myth 发表于 2016-12-15 08:34 static/image/common/back.gif
看到五楼的回复有感而发。。。好吧确实说错人了。。。

好吧,如果收费的话搞不起来的

blackcake 发表于 2016-12-15 10:32:13

强寺顶贴

0ks4lz2skN 发表于 2016-12-15 12:27:30

厉害了

江南小丸子 发表于 2016-12-15 16:01:59

厉害,学习一下

wurenji 发表于 2016-12-15 16:28:28

路过,,收藏了,感谢楼主的无私分享

3300178839 发表于 2016-12-15 20:13:00

在学习,等待更新。。。。。。。。。。。。。。

ldy7474 发表于 2016-12-15 23:09:00

我爱萝丽爱萝丽 发表于 2016-12-15 04:55
1.1 测量PWM信号




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

我爱萝丽爱萝丽 发表于 2016-12-16 00:47:09

ldy7474 发表于 2016-12-15 23:09
祝贺萝莉大神又开新帖
感谢大神解惑成功点亮jlx12864
我一直想做一个简易的高脉宽测试仪


是的

ldy7474 发表于 2016-12-16 10:04:55

我爱萝丽爱萝丽 发表于 2016-12-16 00:47
是的

好很好非常好这样就不用外部中断了真好我一直在头痛用15w204外部中断被数码管占用这短短的几行代码完全解决问题哈哈…
页: [1] 2 3
查看完整版本: 第十六课:扩展课!万能的电子开关