蓝桥杯单片机记录_第四篇_独立按键(长短按)

独立按键

独立按键的原理图:

在这里插入图片描述

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

在这里插入图片描述

一 只有短按的代码:

key.h

#ifndef _KEY_H_
#define _KEY_H_


#include <STC15F2K60S2.H>


sbit k4=P3^3;
sbit k5=P3^2;
sbit k6=P3^1;
sbit 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 <key.h>

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 <STC15F2K60S2.H>
#include <timer.h>
#include <key.h>

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 <key.h>

#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 <STC15F2K60S2.H>

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 <STC15F2K60S2.H>
#include <timer.h>
#include <key.h>

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;
  }

}


独立按键长短按的例子:
独立按键长短按

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值