找回密码
 立即注册

QQ登录

只需一步,快速开始

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

如何把的程序加一个长按按键功能?

[复制链接]
跳转到指定楼层
楼主
ID:738970 发表于 2020-6-28 00:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
要求在原程序上增加 k1 按键的 长按功能。 长按一秒 led 和 led1  灯一起亮。

单片机源程序如下:
#include <AT89X52.H>
unsigned char n = 0;
sbit k1 = P1^0;
sbit led = P0^0;
sbit led1 = P0^1;
void delay()
{
    unsigned int  i, j;
    for(i = 0; i < 100; i++)   for(j = 0; j < 100; j++);
}
void readkey(void)
{
    unsigned char  i, j;
    if(!k1)  {
      for(i = 0; i < 10; i++)
        for(j = 0; j < 120; j++);  
      if(!k1)  {
        while(!k1);  
        n++;
        n %= 2;       //n = 0~0
      }
    }
}
main()
{
    while(1)  {
      switch(n)    {
      case 0: led = 1;led1 = 1; readkey(); break;      
      case 1: led1 = 0;  delay(); readkey(); led=~led;
      }
    }
}


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

使用道具 举报

沙发
ID:435708 发表于 2020-6-28 06:23 | 只看该作者
需要使用定时器,按键扫描程序可以拓展

#include <reg51.h>
unsigned char n = 0;
unsigned char flag1ms,flag10ms;
sbit k1 = P1^0;
sbit led = P0^0;
sbit led1 = P0^1;
void key_led(void);
void Timer0Init(void);     //初始化定时器


void main()
{   
    Timer0Init();
    while (1)
        {                  

        if(flag1ms)         //以1ms为时基
        {
            flag1ms=0;
            flag10ms++;
            switch(n)    {
        case 0: led = 1;led1 = 1;break;      
         case 1: led1 = 0;  led=~led;
      }
            if(flag10ms>=10) //每10ms进行一次按键扫描
            {
                flag10ms=0;
                key_led();
            }

        }
        }
}

void Timer0() interrupt 1
{
                    //重装载
    flag1ms=1;   
    TH0=0XFC;   
    TL0=0X18;

}

void key_led(void)
{
        static unsigned int key_press_time = 0;  // 记得标为静态变量
        
        if(k1==0)
        {
            if(++key_press_time <=0 )
             --key_press_time;                //计量按键时间,并避免数据溢出
            if(key_press_time==100)            //以10ms为时基 计数100相当于1s,为长按
                {
                     led=0;                    //添加事件
                  led1=0;
                }
        }
            else      //短按
        {
            if(2<=key_press_time && key_press_time <100) //按键时长大于20ms,小于1s
            {
                    n++;
                    n%=2;
            }
  key_press_time=0;


        }

}

void Timer0Init(void)   
{
    TMOD|=0X01;//选择为定时器0模式,工作方式1,仅用TR0打开启动。

    TH0=0XFC;    //给定时器赋初值,定时1ms
    TL0=0X18;   
    ET0=1;//打开定时器0中断允许
    EA=1;//打开总中断
    TR0=1;//打开定时器
    IT0=1;            
}

评分

参与人数 1黑币 +20 收起 理由
admin + 20 回帖助人的奖励!

查看全部评分

回复

使用道具 举报

板凳
ID:213173 发表于 2020-6-28 09:36 | 只看该作者
#include <REG51.H>

unsigned int n = 0;

sbit k1 = P1^0;
sbit led = P0^0;
sbit led1 = P0^1;

void readkey(void)
{
        if(!k1)  
        {
                if(n<25001)  
                        n++;
                if(n==25000)       //长按
                        led1=~led1;
        }       
        else       
          {
                if(n>2500&&n<25000)//短按
                        led=~led;       
                n=0;
        }
}
void main()
{
        while(1)  
        {
                readkey();
        }
}
回复

使用道具 举报

地板
ID:496636 发表于 2022-10-19 07:34 | 只看该作者
if(++key_press_time <=0 )
             --key_press_time;                //计量按键时间,并避免数据溢出
这里key_press_time被定义成unsigned int了,不会出现小于的情况吧,如果unsigned int是二字节的,那么当它等于0xffff时,再加1就会变成0,并溢出位on,产生溢出。这也没避免数据溢出吧。
是否要写成:
if(++key_press_time==0xffff)
          --key_press_time;
回复

使用道具 举报

5#
ID:491577 发表于 2022-10-19 10:13 | 只看该作者
楼主的程序是开发板上的程序只适合了解按键的原理,实际按键程序是用定时器来实现的。给你一个参考程序:http://www.51hei.com/bbs/dpj-208253-1.html
回复

使用道具 举报

6#
ID:161164 发表于 2022-10-19 15:02 | 只看该作者
  1. #include <REG52.H>

  2. unsigned char n = 0;
  3. sbit k1 = P1^0;
  4. sbit led = P0^0;
  5. sbit led1 = P0^1;
  6. void Delay1ms()                //@11.0592MHz
  7. {
  8.         unsigned char i, j;

  9.         i = 2;
  10.         j = 199;
  11.         do
  12.         {
  13.                 while (--j);
  14.         } while (--i);
  15. }

  16. void readkey(void)
  17. {
  18.         static unsigned int i=0;
  19.         if(!k1)
  20.         {
  21.                 if(i<0xFFFF)i++;
  22.                 if(i==1000)
  23.                 {
  24.                         n = 2;       //n = 0~0
  25.                 }
  26.         }else{
  27.                 if(i>20 && i<1000)n=++n%2;
  28.                 i=0;
  29.         }
  30. }
  31. main()
  32. {
  33.         while(1)
  34.         {
  35.                 readkey();
  36.                 switch(n)
  37.                 {
  38.                 case 0:
  39.                         led = 1;
  40.                         led1 = 1;
  41.                         break;
  42.                 case 1:
  43.                         led1 = 0;
  44.                         led=~led;
  45.                         break;
  46.                 case 2:
  47.                         led = 0;
  48.                         led1 = 0;
  49.                         break;
  50.                 }
  51.                 Delay1ms();
  52.         }
  53. }
复制代码


回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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