单片机学习小组
直播中

飞毛腿452

8年用户 900经验值
擅长:电源/新能源
私信 关注

独立按键长短按的代码分享

独立按键长短按的代码分享

回帖(1)

张玉兰

2022-1-20 11:17:55
独立按键

独立按键的原理图:

其中,S4,S5,S6,S7是独立按键,需要用跳线帽接右边:


一 只有短按的代码:
key.h


#ifndef _KEY_H_
#define _KEY_H_




#include




***it k4=P3^3;
***it k5=P3^2;
***it k6=P3^1;
***it k7=P3^0;




extern unsigned char k4_press;
extern unsigned char k5_press;
extern unsigned char k6_press;
extern unsigned char k7_press;




void key_read(void);
void key_control(void);




#endif


key.c


/*独立按键采用了定时器扫描法*/
/*代码写的比较复杂,但是比较好看懂吧*/




#include


unsigned char k4_press,k5_press,k6_press,k7_press;
unsigned char key_sum;


void key_read(void)
{
  static unsigned char k4_time=0,k5_time=0,k6_time=0,k7_time=0; //一定要是static
  key_sum=0;
  
  /**********K4**********/
  if(k4==0)   //如果K4按下
  {
   k4_time++;    //k4_time用来判断按了多久
   if(k4_time==1)  //如果是一次的话
   {
     key_sum=4;   //得到key_sum为4,到key_control();函数中生成对应的press
   }  
   else if(k4_time==20) //在定时器中断中30ms扫描一次,大概是按下0.6秒后
   {
     k4_time=1;       //只有短按,然他执行k4_time=1时候的操作
     key_sum=0;      //并且此时没有sum值
   }
  }
  else
   k4_time=0;       //没有按下按键则对应的time为0




  if(k5==0)
  {
    k5_time++;
   if(k5_time==1)
   {
     key_sum=5;
   }  
   else if(k5_time==20)
   {
     k5_time=1;
     key_sum=0;
   }
  }
  else
   k5_time=0;




  if(k6==0)
  {
    k6_time++;
   if(k6_time==1)
   {
     key_sum=6;
   }
   else if(k6_time==20)
   {
     k6_time=1;
    key_sum=0;
   }
  }
  else
   k6_time=0;




  if(k7==0)
  {
    k7_time++;
   if(k7_time==1)
   {
     key_sum=7;
   }
   else if(k7_time==20)
   {
     k7_time=1;
    key_sum=0;
   }
  }
  else
   k7_time=0;
}


//得到对应的press供主函数用
void key_control(void)
{
if(key_sum==4) k4_press=1;
if(key_sum==5) k5_press=1;
if(key_sum==6) k6_press=1;
if(key_sum==7) k7_press=1;
}


main.c:


#include
#include
#include


unsigned char flag_key;


void all_init(void)
{
P2=(P2&0X1F)|0XA0;
P0=0X00;
P2&=0X1F;

P2=(P2&0X1F)|0X80;
P0=0XFF;
P2&=0X1F;
}


void main(void)
{
all_init();
  while(1)
  {
    if(flag_key)  //如果flag为1
    {
      flag_key=0;  //清零
      key_read();   //执行这两个函数,扫描按键
      key_control();
    }


   //对应执行按键
    if(k4_press)
    {
      k4_press=0;
      k4按下执行的任务
    }
    if(k5_press)
    {
      k5_press=0;
      k5按下执行的任务
    }
   
    if(k6_press)
    {
      k6_press=0;
      k6按下执行的任务
    }
   
    if(k7_press)
    {
      k7_press=0;
      k7按下执行的任务
    }
  }
}


void timer0_isr(void) interrupt 1
{
  static unsigned char flag_key_time=0;
  
  if(++flag_key_time==30)  //每隔30ms扫描一次
  {
    flag_key_time=0;      //清零
    flag_key=1;          //每隔30ms flag=1
  }
}


二 长短按结合的代码:
上面那些代码在下面这里,如果k4_time=20时你可以另外算他一个sum值,再加一个press值,能实现长按,但是,这样的话,再判断出长按前,短按就被判断为真事件了,就会有影响:


   if(k4_time==20)
   {   
     key_sum=;
   }


那么下面这个就改进了:


key.c:


#include


#define S7 0X0E //按下s7拉低P30,下面同理
#define S6 0X0D
#define S5 0X0B
#define S4 0X07


//4~7为短按  //8~11是对应了4~7的长按
unsigned char key_sum=0,k4_press,k5_press,k6_press,k7_press,k8_press,k9_press,k10_press,k11_press;
//用了这三个变量实现了长短按的逻辑
unsigned char flag_one=0,key_one=0,key_long=0;


void key_read(void)
{
  static unsigned char key_time=0;
  
  key_sum=0;
  P3=0X0F;  //先让P30~P33拉高
  
  if(P3!=0X0F)  //如果不是这个值了就说明有按键按下
  {
    key_time++;  
   if(key_time==1)  //按键按下很短时间,判断为初步判断为短按
   {
     flag_one=1;   //设立的按短按的flag变为1
     if(P3==S7) key_sum=7;
     if(P3==S6) key_sum=6;
     if(P3==S5) key_sum=5;
     if(P3==S4) key_sum=4;
   }
   
   else if(key_time>33)
   {
     flag_one=0;   //如果长时间按下,这里33X30大该是1秒,那么flag_one就变为0
     key_long=1;  //对应的长按就变为1
     if(P3==S4) key_sum=8;
    else if(P3==S5) key_sum=9;
    else if(P3==S6) key_sum=10;
    else if(P3==S7) key_sum=11;
   }
}
else
{
   key_time=0;  //如果没按下,time为0
   
   if(flag_one)  //如果松开的时候flag_one是1,那么就说明为短按
   {
    flag_one=0;  //清零
    key_one=1;   //最终得到一个变量说明为短按,以便于主函数用
   }
   key_long=0;  //如果松开,长按就变为0
}
}
void key_control(void)  //通过sum值,给出press
{
if(key_sum==4) k4_press=1;
else if(key_sum==5) k5_press=1;
else if(key_sum==6) k6_press=1;
else if(key_sum==7) k7_press=1;
else if(key_sum==8) k8_press=1;
else if(key_sum==9) k9_press=1;
else if(key_sum==10) k10_press=1;
else if(key_sum==11) k11_press=1;
}


key.h:


#ifndef _KEY_H_
#define _KEY_H_


#include


extern unsigned char k4_press;
extern unsigned char k5_press;
extern unsigned char k6_press;
extern unsigned char k7_press;
extern unsigned char k8_press;
extern unsigned char k9_press;
extern unsigned char k10_press;
extern unsigned char k11_press;
extern unsigned char key_one;
extern unsigned char key_long;


void key_read(void);
void key_control(void);


#endif


main.c


#include
#include
#include


void all_init(void)
{
P2=(P2&0X1F)|0XA0;
P0=0X00;
P2&=0X1F;

P2=(P2&0X1F)|0X80;
P0=0XFF;
P2&=0X1F;
}


void main(void)
{
Timer0Init();
all_init();
  while(1)
{
  if(flag_key)
  {
   flag_key=0;
   key_read();
   key_control();
  }
  
  if(key_one)
  {
    key_one=0;
   if(k4_press)
   {
     k4_press=0;
     //短按k4的操作
   }
    if(k5_press)
   {
     k5_press=0;
     //短按k5的操作
   }
   
    if(k6_press)
   {
     k6_press=0;
     //短按k6的操作
   }
   
   if(k7_press)
   {
     k7_press=0;
     //短按k7的操作
   }
   
  }




  if(key_long)
  {
   key_long=0;
   if(k8_press)
   {
    k8_press=0;
     //长按k4的操作
   }
   
   if(k9_press)
   {
     k9_press=0;
     //长按k5的操作
   }   
   
   if(k10_press)
   {
     k10_press=0;
     //长按k6的操作
   }
      
    if(k11_press)
   {
     k11_press=0;
     //长按k7的操作
   }
      
  }
  else
   k8_press=k9_press=k10_press=k11_press=0;
}
}




void timer0_isr(void) interrupt1
{
  static unsigned char flag_key_time=0;
  
  if(++flag_key_time==30)
  {
    flag_key_time=0;
    flag_key=1;
  }


}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分