标题: 单片机按键程序 按一下开,再按一下关,怎么写? [打印本页]

作者: a78476667    时间: 2021-4-7 12:38
标题: 单片机按键程序 按一下开,再按一下关,怎么写?
学了几天了,今天想写个开关,结果下载后不是想要的,有没有哪位大神指导下,看看哪里出了问题,初学小白,勿喷呀!
#include<reg52.h>
sbit key1=P3^2;

unsigned char i;
void delayms(unsigned int z)
{  

    unsigned int k,j;
    for(k=z;k>0;k--)
    for(j=110;j>0;j--);


}



    void key()
{
         
    if(key1==0)
    {
        delayms(20);
        if(key1==0)
        {
       key1=i;
       i++;
        }
      if(i>=2)
      {
        i=0;
      }


    }  
}
void main()
{
while(1)
{

    key();
    if(i==0)
    {
        P0=0x00;

    }  
     if(i==1)
     {
         P0=0xfe;

     }



    }
}


作者: munuc_w    时间: 2021-4-8 08:31
判断按键,如果是有效按键,输出取反即可。
作者: 林大侠    时间: 2021-4-8 09:14
你这个没有加入 松键检测哦,
例如: while(!key);
把这个加进去,这样会检测到你手松
另外还可以加一个取反的代码,比如  i=~i;
作者: ccnnzz315    时间: 2021-4-8 09:52
功能简单,在线仿真一下便可让你得出原因,同时,也会给你以后分析复杂程序带来经验
作者: hollo08    时间: 2021-4-8 10:36
ccnnzz315 发表于 2021-4-8 09:52
功能简单,在线仿真一下便可让你得出原因,同时,也会给你以后分析复杂程序带来经验

问个初学者问题?在线仿真怎么弄,有推荐的软件吗?
作者: ANT1987    时间: 2021-4-8 12:52
1 i 先赋初值 unsigned char i=0;
2 key1=i;这行注释掉不要
3 第二个if(key1==0)内加松手检测 while(key1==0);
作者: a26409310    时间: 2021-4-8 12:56
key1=i 这个i是哪来的,p0口有上拉电阻么,还有程序运行很快,你想按键一直按下,i会一直变化,万用表量不出来高低电平了。
if(key1==0)
        {
       P1=0x00;
        }else
      {
       P1=0xfe;
      }
作者: cn_zhx    时间: 2021-4-8 15:35
按一次取一次反,
作者: oblivionqqqqq    时间: 2021-4-9 11:59
要加防抖延时
作者: lwh999995    时间: 2021-4-9 13:22





作者: 13702010390    时间: 2021-4-9 13:40
你这个很简单,用一个if判断取奇数偶数的模就可以实现
作者: 时间苍白了誓言    时间: 2021-4-9 18:43
用一个变量标志位。flag=~flag;取反就可以
作者: XTXB    时间: 2021-4-9 19:38
尽量不要用阻塞延时去抖,下面这个更具实用价值,供你参考:
#include<reg52.h>
sbit key1=P3^2;
sbit LED=P0^7;
unsigned char ucKeySec=0;//键值
void key()
{
        static unsigned int uiKeyTimeCnt1 = 0; //按键去抖动,累加去抖定时器
        static bit ucKeyLock1=0;        //按键自锁标志
        if (key1== 1) //IO是高电平,说明按键没有被按下,清零标志位
        {
                ucKeyLock1 = 0; //按键自锁标志清零
                uiKeyTimeCnt1 = 0; //按键去抖动延时计数器清零
        }else if (ucKeyLock1 == 0) { //有按键按下,且是第一次被按下
              uiKeyTimeCnt1++; //累加去抖
              if (uiKeyTimeCnt1 > 2000) {
                    uiKeyTimeCnt1 = 0;
                    ucKeyLock1 = 1; //自锁按键置位,避免一直触发
                    ucKeySec = 1; //触发1号键
              }
        }
}
//

void main()
{
        while(1)
        {
           key();
           if(ucKeySec==1)
            {
                ucKeySec=0;  //键值复位
                 LED=!LED;
             }

       }
}
//


51hei截图20210409193539806.jpg (48.26 KB, 下载次数: 77)

LED

LED

作者: linruijie758    时间: 2021-4-10 09:29
可以设置两个不同标志位,每次按键动作后,标志位做变化,然后进行按键处理
作者: Secret丶    时间: 2021-4-10 14:40
可以在全局设定一个检测bit i=0,按键函数内设定每按一次,i取反一次,然后在主函数内进行判断,就不用计数按下次数,还有你程序缺少松手检测:while(!key1);导致你每次按下,除非你按下速度超过按键扫描的速度,不然结果就很随机,可能是点亮,可能是熄灭。
作者: cdiyy    时间: 2021-4-10 16:38
#include<reg52.h>
sbit key1=P3^2;
sbit Led=P2^0;

void delayms(unsigned int z)
{  
    unsigned int k,j;
   
            for(k=z;k>0;k--)
            for(j=110;j>0;j--);
}

void key()                //按键处理
{
        key1 = 1;
        if(!key1)
        {
                delayms(10);
                if(!key1)
                {
                        Led ^= Led;
                }
        }
}


void main()                //主函数
{
        while(1)
        {
                key();
        }
}




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