标题: 关于独立按键程序,有点不理解? [打印本页]

作者: king@    时间: 2016-10-11 12:02
标题: 关于独立按键程序,有点不理解?
void main(void)
{
        while(1)
        {
                if(0 == KEY1)                                   // 检测按键是否按下
                {
                        DelayMS(5);                                 // 延时去抖
                        if(0 == KEY1)                          // 再次检测
                        {
                                LED1 = 0;                   // 点亮LED灯
                                while(!KEY1);                // 等待按键弹起
                        }
                }
                if(!KEY2)
                {
                        DelayMS(5);
                        if(!KEY2)
                        {
                                LED1 = 1;
                                while(!KEY2);
                        }
                }
        }
}



1.为什么0赋给KYE1来判断是否按键有输入信号,而不是1的时候?
2.!KEY2按照解释不应该是弹起,当延时确认是弹起才会控制LED1灭。

QQ截图20161011115402.png (120.71 KB, 下载次数: 61)

QQ截图20161011115402.png

QQ截图20161011115431.png (42.09 KB, 下载次数: 55)

QQ截图20161011115431.png

作者: zl2168    时间: 2016-10-11 18:40
程序不完整,你都没有定义KEY1、KEY2,叫人家怎么解答你的问题?本网站不会提问的人太多!
作者: king@    时间: 2016-10-11 20:47
#include <reg52.h>
/* ***************************************************** */
// 为已知类型起别名
/* ***************************************************** */
typedef unsigned int uInt16;
/* ***************************************************** */
// 位定义
/* ***************************************************** */
sbit LED1 = P2^0;
sbit KEY1 = P3^4;
sbit KEY2 = P3^5;
/* ***************************************************** */
// 函数名称:DelyaMS()
// 函数功能:毫秒延时
// 入口参数:延时毫秒数
// 出口参数:无
/* ***************************************************** */
void DelayMS(uInt16 ValMS)
{
        uInt16 uiVal,ujVal;
        for(uiVal = 0; uiVal < ValMS; uiVal++)
                for(ujVal = 0; ujVal < 113; ujVal++);
}
/* ***************************************************** */
// 函数名称:main()
// 函数功能:扫描按键并做出相应LED灯亮灭动作
// 入口参数:无
// 出口参数:无
/* ***************************************************** */
void main(void)
{
        while(1)
        {
                if(0 == KEY1)                                   // 检测按键是否按下
                {
                        DelayMS(5);                                 // 延时去抖
                        if(0 == KEY1)                          // 再次检测
                        {
                                LED1 = 0;                   // 点亮LED灯
                                while(!KEY1);                // 等待按键弹起
                        }
                }
                if(!KEY2)
                {
                        DelayMS(5);
                        if(!KEY2)
                        {
                                LED1 = 1;
                                while(!KEY2);
                        }
                }
        }
}
作者: king@    时间: 2016-10-11 21:09
zl2168 发表于 2016-10-11 18:40
程序不完整,你都没有定义KEY1、KEY2,叫人家怎么解答你的问题?本网站不会提问的人太多!

#include <reg52.h>
/* ***************************************************** */
// 为已知类型起别名
/* ***************************************************** */
typedef unsigned int uInt16;
/* ***************************************************** */
// 位定义
/* ***************************************************** */
sbit LED1 = P2^0;
sbit KEY1 = P3^4;
sbit KEY2 = P3^5;
/* ***************************************************** */
// 函数名称:DelyaMS()
// 函数功能:毫秒延时
// 入口参数:延时毫秒数
// 出口参数:无
/* ***************************************************** */
void DelayMS(uInt16 ValMS)
{
        uInt16 uiVal,ujVal;
        for(uiVal = 0; uiVal < ValMS; uiVal++)
                for(ujVal = 0; ujVal < 113; ujVal++);
}
/* ***************************************************** */
// 函数名称:main()
// 函数功能:扫描按键并做出相应LED灯亮灭动作
// 入口参数:无
// 出口参数:无
/* ***************************************************** */
void main(void)
{
        while(1)
        {
                if(0 == KEY1)                                   // 检测按键是否按下
                {
                        DelayMS(5);                                 // 延时去抖
                        if(0 == KEY1)                          // 再次检测
                        {
                                LED1 = 0;                   // 点亮LED灯
                                while(!KEY1);                // 等待按键弹起
                        }
                }
                if(!KEY2)
                {
                        DelayMS(5);
                        if(!KEY2)
                        {
                                LED1 = 1;
                                while(!KEY2);
                        }
                }
        }
}
作者: zl2168    时间: 2016-10-11 21:20
本帖最后由 zl2168 于 2016-10-11 21:27 编辑

问题1.为什么0赋给KYE1来判断是否按键有输入信号,而不是1的时候?
if(0 == KEY1)  不是赋值语句,而是条件判断。但一般不这样写,而是写成: if(KEY1 ==0 )
KYE1按下时,P3.4端(即定义为KYE1)为0,这是电路连接的结果,请看你自己的连接电路。


作者: zl2168    时间: 2016-10-11 21:29
本帖最后由 zl2168 于 2016-10-11 21:47 编辑

问题2.!KEY2按照解释不应该是弹起,当延时确认是弹起才会控制LED1灭。

if(!KEY2)与 if(KEY2==0)作用相同。KEY2未按下时,KEY2=1,!KEY2=0,则不会进入后面的程序,直至KEY2按下,才会进入后面的程序。

后面的 if(!KEY2)隶属于前面的 if(!KEY2),此时已KEY2=0,!KEY2=1。延时去抖后,控制LED1灭,不需要KEY2弹起。

while(!KEY1)是等待KEY1再次按下。



作者: zl2168    时间: 2016-10-11 21:48
本帖最后由 zl2168 于 2016-10-11 21:53 编辑

实例5  4种不同方式键控信号灯


按键按能否锁定可分为有锁按键和无锁按键。有锁按键是按下即能锁定闭合状态,只有再次按一下才能解除闭合状态,回归断开状态。无锁按键不能锁定闭合状态,除非按住键不予释放,典型的例子就是电脑键盘上的按键。


单片机应用系统中,根据按键闭合和释放状态,有多种不同的键控方式,可编写不同的程序予以实现。本例要求按以下4种不同方式分别键控VD0~ VD3



电路设计
P1.0~P1.3分别接VD0~VD3发光二极管,输出低电平时亮,输出高电平时暗。R0~R3为限流电阻,取330Ω。S0~S3为无锁按键,键信号输入端分别为P1.4~P1.7,按键闭合时输入0,按键断开时输入1。R4~R7为上拉电阻,取10kΩ,接+5V,如图3-7所示。




① 无锁按键:S0按下,VD0亮;S0释放,VD0暗;


② 无锁按键(前沿有效):S1按下,VD1亮;S1释放,VD1延时2s后暗。


③ 无锁按键(后沿有效):S2按下,VD2不亮;S2释放,VD2亮,并延时2s后暗。


模拟有锁按键:S3按第一次,VD3亮,并继续保持;按第二次,VD3才暗。




Proteus仿真一下,确认有效。
实例5 不同方式键控灯.rar (31.72 KB, 下载次数: 9)


以上摘自张志良编著《80C51单片机仿真设计实例教程——基于Keil CProteus》清华大学出版社ISBN 978-7-302-41682-1




书中电路和程序设计有详细说明,程序语句条条有注解。



作者: king@    时间: 2016-10-11 22:25
zl2168 发表于 2016-10-11 21:20
问题1.为什么0赋给KYE1来判断是否按键有输入信号,而不是1的时候?
if(0 == KEY1)  不是赋值语句,而是条 ...

嗯,这个明白。
作者: LEON-HUA    时间: 2016-10-12 10:24
if(0 == KEY1)  不是赋值语句,而是条件判断。但一般不这样写,而是写成: if(KEY1 ==0 )
KYE1按下时,P3.4端(即定义为KYE1)为0,这是电路连接的结果
作者: luoluoluo136    时间: 2016-10-12 14:37
zl2168 发表于 2016-10-11 21:20
问题1.为什么0赋给KYE1来判断是否按键有输入信号,而不是1的时候?
if(0 == KEY1)  不是赋值语句,而是条 ...

if(0 == KEY1) 这种写法优于if(KEY1 ==0 ) ,因为后面这种会有可能写成if(KEY1 =0 )

作者: zl2168    时间: 2016-10-12 15:14
luoluoluo136 发表于 2016-10-12 14:37
if(0 == KEY1) 这种写法优于if(KEY1 ==0 ) ,因为后面这种会有可能写成if(KEY1 =0 )

这是优点吗?好像没有因果关系。
作者: luoluoluo136    时间: 2016-10-14 08:55
zl2168 发表于 2016-10-12 15:14
这是优点吗?好像没有因果关系。

这个程序我没看~我只是提出对这个写法的意见~写一个比较的时候,常量放在前,变量放在后,这样可以防止出现if(a==0)写成if(a=0)这样的情况~
作者: zl2168    时间: 2016-10-14 15:47
理由呢?是谁教你的?




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1