找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2477|回复: 26
打印 上一主题 下一主题
收起左侧

51单片机C语言与按键操作的相关问题

[复制链接]
跳转到指定楼层
楼主
ID:792404 发表于 2020-11-3 21:08 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
用哪条语句可以实现按键按住不放 执行一个操作,松开执行另一个操作?用 if....else...或者if.....while()....这样的语句都实现不了,大佬们有何高见可以指点一下!
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:339654 发表于 2020-11-4 00:12 来自手机 | 只看该作者
if(key==1)填语句;else 填语句;
回复

使用道具 举报

板凳
ID:792404 发表于 2020-11-4 07:26 | 只看该作者
weijoyer 发表于 2020-11-4 00:12
if(key==1)填语句;else 填语句;

这个试过了,像这样子的  if(!key){....} else{.....}    直接这样不行。后面用while(!key) {.....} 是可以的,但是只能操作一次,第二次就没用了,也就是执行一次,每次都要断电在通电才可以。
                                                                                                                                
回复

使用道具 举报

地板
ID:739545 发表于 2020-11-4 08:58 | 只看该作者
key的设别标志出问题了,一个按着不放的情况用while,脱手的时候要去掉while,或者在while内部再做判断。
回复

使用道具 举报

5#
ID:654028 发表于 2020-11-4 09:13 | 只看该作者
要加计数,丢定时器中断里面检测按键
if(按键按下){
  计数加;
  if(计数到了长按){
    执行长按语句
   }
}
else{
    if(计数到了长按){
      计数清0
   }
     if(计数到了短按){
      计数清0
      执行短按语句
   }
}

回复

使用道具 举报

6#
ID:792404 发表于 2020-11-4 10:03 | 只看该作者
lovezjf234 发表于 2020-11-4 08:58
key的设别标志出问题了,一个按着不放的情况用while,脱手的时候要去掉while,或者在while内部再做判断。

在while内部判断可以了,但是初始状态就开始检测了,这个不对的,就是上电后按键是松开状态,不要检测,等到按下不放时检测一种状态,松开后在检测松开后的状态。
回复

使用道具 举报

7#
ID:792404 发表于 2020-11-4 10:04 | 只看该作者
心有浮生 发表于 2020-11-4 09:13
要加计数,丢定时器中断里面检测按键
if(按键按下){
  计数加;

谢谢指导!现在是在while内部判断可以了,但是初始状态就开始检测了,这个不对的,就是上电后按键是松开状态,不要检测,等到按下不放时检测一种状态,松开后在检测松开后的状态。
回复

使用道具 举报

8#
ID:654028 发表于 2020-11-4 10:27 | 只看该作者
YUANYUXING 发表于 2020-11-4 10:04
谢谢指导!现在是在while内部判断可以了,但是初始状态就开始检测了,这个不对的,就是上电后按键是松开 ...

加个标志位。
回复

使用道具 举报

9#
ID:213173 发表于 2020-11-4 10:49 | 只看该作者
给你一个示例程序,完全能够解决你的问题。核心是要学会使用标志位。
#include <reg51.H>

sbit key=P3^4;//按实际电路自行定义

unsigned int count;//消抖计数变量
bit key_sign;        //按键操作状态标志

void main()
{
        while(1)
        {
                if(!key)//按下
                {
                        if(++count>=1500 && key_sign==0)//约10ms消抖
                        {
                                key_sign=1;//记忆操作状态
                                P1=0xaa;        //任务1
                        }
                }
                else   //松手
                {
                        count=0;                //计数清0
                        if(key_sign==1) //判断是先按下后松手
                        {
                                key_sign=0; //状态标志复位
                                P1=0x55;        //任务2
                        }
                }
        }
}
回复

使用道具 举报

10#
ID:792404 发表于 2020-11-4 10:56 | 只看该作者

好的,我在试一下,谢谢
回复

使用道具 举报

11#
ID:792404 发表于 2020-11-4 11:01 | 只看该作者
wulin 发表于 2020-11-4 10:49
给你一个示例程序,完全能够解决你的问题。核心是要学会使用标志位。
#include

感谢总工指导,我试一下
回复

使用道具 举报

12#
ID:792404 发表于 2020-11-4 13:01 | 只看该作者
YUANYUXING 发表于 2020-11-4 11:01
感谢总工指导,我试一下

现在可以了,的确是要加个标志位,感谢!
回复

使用道具 举报

13#
ID:792404 发表于 2020-11-4 13:02 | 只看该作者

现在可以了,加个标志位就正常了,感谢指点!
回复

使用道具 举报

14#
ID:654028 发表于 2020-11-4 13:04 | 只看该作者
YUANYUXING 发表于 2020-11-4 13:02
现在可以了,加个标志位就正常了,感谢指点!

我自己的程序一开始也是有问题,后来加了标志位搞定的
回复

使用道具 举报

15#
ID:89217 发表于 2020-11-4 13:21 | 只看该作者
直接P11=P10也可以啊
回复

使用道具 举报

16#
ID:137736 发表于 2020-11-4 17:27 | 只看该作者
设置标志位,不要让程序老盯住按键处理。
回复

使用道具 举报

17#
ID:137736 发表于 2020-11-4 17:28 | 只看该作者
学习学习状态机,论坛有大佬写的详细教程。
回复

使用道具 举报

18#
ID:792404 发表于 2020-11-4 19:34 | 只看该作者
zmc419 发表于 2020-11-4 17:27
设置标志位,不要让程序老盯住按键处理。

现在正常了,加了标志位一切OK,感谢指点
回复

使用道具 举报

19#
ID:792404 发表于 2020-11-4 19:37 | 只看该作者
zmc419 发表于 2020-11-4 17:28
学习学习状态机,论坛有大佬写的详细教程。

现在搞定了,谢谢
回复

使用道具 举报

20#
ID:838969 发表于 2020-11-4 20:06 | 只看该作者
按键时间加一个延时之类的防抖措施看看
回复

使用道具 举报

21#
ID:738987 发表于 2020-11-4 21:18 | 只看该作者
判断循环语句都可,也可以用中断
回复

使用道具 举报

22#
ID:738987 发表于 2020-11-4 21:19 | 只看该作者
判断循环语句都可以,也可以用中断
回复

使用道具 举报

23#
ID:738987 发表于 2020-11-4 21:20 | 只看该作者
判断循环选择语句都可以,也可以用中断
回复

使用道具 举报

24#
ID:792404 发表于 2020-11-5 18:42 | 只看该作者
tooto 发表于 2020-11-4 20:06
按键时间加一个延时之类的防抖措施看看

谢谢,已经搞定了
回复

使用道具 举报

25#
ID:792404 发表于 2020-11-5 18:43 | 只看该作者
comeon刘 发表于 2020-11-4 21:20
判断循环选择语句都可以,也可以用中断

谢谢,已经找到方法了,加个标志位就好了
回复

使用道具 举报

26#
ID:851329 发表于 2020-12-17 21:29 | 只看该作者
# include "reg52.h"

sbit GK1=P3^0;
sbit GK2=P3^1;
sbit GK3=P3^2;
sbit GK4=P3^3;

static unsigned char keyvalue = 0xFF;
static unsigned char keystatus = 0;

void delay(unsigned int i)
{
  while(i--);
}

void keyScan(void)
{  
        static unsigned char counter = 0;
        static unsigned char keytmp  = 0;

        switch(keystatus)
        {
                case 0:
                        if((GK1 == 0) || (GK2 == 0) || (GK3 == 0) || (GK4 == 0))
                        {
                                keystatus = 1;
                        }
                        break;
                case 1:
                        if(GK1 == 0)
                        {
                                keytmp = 1;
                                keystatus = 2;                               
                        }
                        else if(GK2 == 0){
                                keytmp = 2;
                                keystatus = 2;
                        }
                        else if(GK3 == 0){
                                keytmp = 3;
                                keystatus = 2;
                        }
                        else if(GK4 == 0){
                                keytmp = 4;
                                keystatus = 2;
                        }
                        else
                        {
                                keystatus = 0;       
                        }
                        break;
                case 2:
                        if((GK1 == 1) && (GK2 == 1) && (GK3 == 1) && (GK4 == 1))
                        {

                                if(counter < 40)
                                {
                                        counter = 0;
                                        keystatus = 0;
                                        keyvalue = keytmp;
                                }
                                else
                                {
                                        counter = 0;
                                        keystatus = 0;
                                        keyvalue = 4 + keytmp ;        // keyval 5-8
                                }
                        }
                        else
                        {
                                if(counter < 40)
                                {
                                        ++counter;
                                }
                        }
                        break;

        }
}
void taskProcessKey(void)
{
        unsigned char value = keyvalue;

        if(value != 255)
        {
                switch(keyvalue)
                {
                        case 1:P2=0x00; break;
                        case 5:P2=0xab; break;
                        default:break;
                }
        }
}

int main(void)
{
  while(1)
  {
     keyScan();
     delay(2000);
     taskProcessKey();
  }
}
这个是我控制单片机上长按和短按的一个程序,希望对你有用。
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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