找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机按键程序 按一下开,再按一下关,怎么写?

  [复制链接]
跳转到指定楼层
楼主
学了几天了,今天想写个开关,结果下载后不是想要的,有没有哪位大神指导下,看看哪里出了问题,初学小白,勿喷呀!
#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;

     }



    }
}

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏1 分享淘帖 顶1 踩
回复

使用道具 举报

沙发
ID:752974 发表于 2021-4-8 08:31 | 只看该作者
判断按键,如果是有效按键,输出取反即可。
回复

使用道具 举报

板凳
ID:883167 发表于 2021-4-8 09:14 | 只看该作者
你这个没有加入 松键检测哦,
例如: while(!key);
把这个加进去,这样会检测到你手松
另外还可以加一个取反的代码,比如  i=~i;
回复

使用道具 举报

地板
ID:853896 发表于 2021-4-8 09:52 | 只看该作者
功能简单,在线仿真一下便可让你得出原因,同时,也会给你以后分析复杂程序带来经验
回复

使用道具 举报

5#
ID:899171 发表于 2021-4-8 10:36 | 只看该作者
ccnnzz315 发表于 2021-4-8 09:52
功能简单,在线仿真一下便可让你得出原因,同时,也会给你以后分析复杂程序带来经验

问个初学者问题?在线仿真怎么弄,有推荐的软件吗?
回复

使用道具 举报

6#
ID:894154 发表于 2021-4-8 12:52 | 只看该作者
1 i 先赋初值 unsigned char i=0;
2 key1=i;这行注释掉不要
3 第二个if(key1==0)内加松手检测 while(key1==0);
回复

使用道具 举报

7#
ID:263701 发表于 2021-4-8 12:56 | 只看该作者
key1=i 这个i是哪来的,p0口有上拉电阻么,还有程序运行很快,你想按键一直按下,i会一直变化,万用表量不出来高低电平了。
if(key1==0)
        {
       P1=0x00;
        }else
      {
       P1=0xfe;
      }
回复

使用道具 举报

8#
ID:883031 发表于 2021-4-8 15:35 | 只看该作者
按一次取一次反,
回复

使用道具 举报

9#
ID:668885 发表于 2021-4-9 11:59 | 只看该作者
要加防抖延时
回复

使用道具 举报

10#
ID:207421 发表于 2021-4-9 13:22 | 只看该作者
  • if(key1==0)
  • {
  •     delayms(20);
  •     if(key1==0)
  •     {
  •         i=~i;//用!或者~取反即可,此时i的值只有0和1
  •         while(key1==0);//等待松开按键
  •     }
  • }




回复

使用道具 举报

11#
ID:588399 发表于 2021-4-9 13:40 | 只看该作者
你这个很简单,用一个if判断取奇数偶数的模就可以实现
回复

使用道具 举报

12#
ID:451629 发表于 2021-4-9 18:43 | 只看该作者
用一个变量标志位。flag=~flag;取反就可以
回复

使用道具 举报

13#
ID:147710 发表于 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, 下载次数: 32)

LED

LED
回复

使用道具 举报

14#
ID:817354 发表于 2021-4-10 09:29 | 只看该作者
可以设置两个不同标志位,每次按键动作后,标志位做变化,然后进行按键处理
回复

使用道具 举报

15#
ID:808223 发表于 2021-4-10 14:40 | 只看该作者
可以在全局设定一个检测bit i=0,按键函数内设定每按一次,i取反一次,然后在主函数内进行判断,就不用计数按下次数,还有你程序缺少松手检测:while(!key1);导致你每次按下,除非你按下速度超过按键扫描的速度,不然结果就很随机,可能是点亮,可能是熄灭。
回复

使用道具 举报

16#
ID:607312 发表于 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();
        }
}
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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