51单片机识别四个独立按键是短按还是长按

发布者:sjp5035022最新更新时间:2014-01-13 来源: dqjsw关键字:51单片机  独立按键  TICK数 手机看文章 扫描二维码
随时随地手机看文章
这是一个可以识别四个独立按键是短按还是长按的参考程序,此程序已编译通过,初学者可以移植到51单片机上试试.
/********************************************/
//FileName:识别四个独立按键是短按还是长按
//Function: 不同按键 短按或长按分别显示不同的LED
//author:liu yong
//QQ:545018331
//Date:2013/03/13
/********************************************/        
#include
__CONFIG(0X3B31);
#define uint8 unsigned char
unsigned int time_10ms_ok=0;
uint8 KeyValue;
bit KeyShortpressFlag,KeyLongpressFlag;
//=========定义长按键断口的TICK数及连发间隔的TICK数=======//
#define KEY_LONG_PERIOD  200
//=========定义按键断口=======//
#define io_key_1  RB0
#define io_key_2  RB1
#define io_key_3  RB2
#define io_key_4  RB3
//=========定义按键键值=======//
#define KEY_VALUE_1 0X0e
#define KEY_VALUE_2 0X0d
#define KEY_VALUE_3 0X0b
#define KEY_VALUE_4 0X07
#define KEY_NULL    0X0f

//=========定义按键返回值状态(按下,长按,连发,释放)=======//
#define KEY_SHORT    0X80
#define KEY_LONG     0X40

//=========定义按键状态=======//
#define KEY_STATE_INIT       0
#define KEY_STATE_WOBBLE     1
#define KEY_STATE_PRESS      2
#define KEY_STATE_LONG       3
#define KEY_STATE_RELEASE    4

void initial(void)
{
      TRISB=0xff;
      TRISC=0;
      PORTC=0XFF;
      RBPU=0;
      T1CON=0X01;//1:1
      TMR1H=-(10000 >> 8);
      TMR1L=-(10000 & 0XFF);
      TMR1IF=0;
      TMR1IE=1;
      INTCON=0XC0;
}
void interrupt  timer1_isr(void)       // 定时器10ms中断服务
{
       if(TMR1IF)
        {
           TMR1H=-(10000 >> 8);
           TMR1L=-(10000 & 0XFF);
           time_10ms_ok = 1;
           TMR1IF=0;
        }
}

void KeyInit(void)
{
     io_key_1 = 1;
     io_key_2 = 1;
     io_key_3 = 1;
     io_key_4 = 1;
}
uint8 KeyScan(void)
{
      if(io_key_1 == 0)return KEY_VALUE_1;
      if(io_key_2 == 0)return KEY_VALUE_2;
      if(io_key_3 == 0)return KEY_VALUE_3;
      if(io_key_4 == 0)return KEY_VALUE_4;
      return KEY_NULL;
}
uint8 GetKey(void)
{
      static uint8 s_u8KeyState = KEY_STATE_INIT ;
      static uint8 s_u8KeyTimeCount = 0;
      uint8 i ;
      uint8 KeyTemp=KEY_NULL;
      KeyTemp = KeyScan();//0x0e 0f
      switch(s_u8KeyState)
      {
        case KEY_STATE_INIT:
              {
                if(KEY_NULL != KeyTemp)
                 {
                   s_u8KeyState = KEY_STATE_WOBBLE ;
                 }
              }
        break;
 
        case KEY_STATE_WOBBLE:
              {
                 s_u8KeyState = KEY_STATE_PRESS ;
              }
        break;
        case KEY_STATE_PRESS://识别哪个键
              {
                if(KEY_NULL != KeyTemp) // KeyTemp=0x0e  short press
                 {
                   s_u8KeyState = KEY_STATE_LONG ;
                   i=KeyTemp;//0x0e
                 }
                else
                 {
                   s_u8KeyState = KEY_STATE_INIT;
                 }
              }
        break;
        case KEY_STATE_LONG:  //判断按键是短按还是长按
              {
                if(KEY_NULL != KeyTemp)
                 {
                   if(++s_u8KeyTimeCount > KEY_LONG_PERIOD)
                    {
                      s_u8KeyTimeCount = 0;
                      KeyLongpressFlag=1;
                      KeyShortpressFlag=0; 
                      s_u8KeyState = KEY_STATE_RELEASE;
                    }
                 }
                else
                 { 
                      s_u8KeyTimeCount = 0; 
                      KeyShortpressFlag=1;
                      KeyLongpressFlag=0;
                      s_u8KeyState = KEY_STATE_RELEASE;
                 }
              }
        break;
       case KEY_STATE_RELEASE://按键释放去抖
              {
                if(KEY_NULL == KeyTemp)  //此语句必须加上去不然程序不稳定
                {
                 if(KeyShortpressFlag)
                 {
                     KeyShortpressFlag=0;
                     i=i | KEY_SHORT;//0x0e | 0x80=0x8e
                     s_u8KeyState = KEY_STATE_INIT;
                 }
                if(KeyLongpressFlag)
                 {
                     KeyLongpressFlag=0;
                     i=i | KEY_LONG;
                     s_u8KeyState = KEY_STATE_INIT;
                 }
               }
             }
        break;
        default:break;
      }
     return i; 
}

void main(void)
{
     initial();
     KeyInit();
     while(1)
     {
      if (time_10ms_ok)            //每10ms执行一次, 
        { 
             time_10ms_ok =0;
             KeyValue=GetKey();
             if(KeyValue == (KEY_VALUE_1 | KEY_SHORT))     PORTC = ~1;
             if(KeyValue == (KEY_VALUE_1 | KEY_LONG))       PORTC = ~3;
             if(KeyValue == (KEY_VALUE_2 | KEY_SHORT))     PORTC = ~7;
             if(KeyValue == (KEY_VALUE_2 | KEY_LONG))       PORTC = ~0X0F;
             if(KeyValue == (KEY_VALUE_3 | KEY_SHORT))     PORTC = ~0X1F;
             if(KeyValue == (KEY_VALUE_3 | KEY_LONG))      PORTC = ~0X3F;
             if(KeyValue == (KEY_VALUE_4 | KEY_SHORT))     PORTC = ~0X7F;
             if(KeyValue == (KEY_VALUE_4 | KEY_LONG))      PORTC = ~0XFF;  
        }
     }
}
关键字:51单片机  独立按键  TICK数 引用地址:51单片机识别四个独立按键是短按还是长按

上一篇:基于以太网的医院病人体温远程自动检测系统设计
下一篇:51单片机的外部中断触发方式

推荐阅读最新更新时间:2024-03-16 13:33

51单片机定时/计数器的功能实现
8051单片机内部有两个16位的定时/计数器:T0和T1 定时器用途:延时和脉宽测量 读取方式:软件读取和中断 公式: T(初值)=2^N-定时时间/机器周期时间 机器周期时间=12/fosc N:代表几位定时器,有13 16 8位定时器 定时时间:希望设定时间,例如希望设定时间是65.535,初值就是0 fosc:晶振频率,一般用的多的晶振频率是12 四种工作方式,在TMOD中设置: M1 M0=0X00,方式0,13位计数器 M1 M0=0X01,方式1,16位计数器,用的最多 M1 M0=0X10,方式2,8位计数器 M1 M0=0X11,方式3,8位计数器 例如: 如果我们希望定时0.2ms,定时单位用的u
[单片机]
<font color='red'>51单片机</font>定时/计数器的功能实现
51单片机【五】LED点阵屏
关于显示器的分辨率,像素,清晰度这些概念不再赘述 讲一下pitch这个比较陌生的概念:指的是两个像素点的圆心之间的距离,通常默认单位是毫米 例如:p10指的是间距10毫米的led点阵 LED的P00-P07是直接接在处理器上但是因为处理器针脚有限所以需要下面的74HC595(处理器使用3个引脚经过这个芯片产生8个并行的信号等效于使用了8个引脚) J13如果跳线OE和GND HC595将无法工作也为没有电压 而跳线OE和VCC才可以工作 74HC595是一个移位寄存器74HC595是将串行信号转为并行信号 其中P34是处理器输入串行信号 P36是串行时钟 P35是工作时钟 然后经过这个芯片处理生成8个并行的信号 接在
[单片机]
<font color='red'>51单片机</font>【五】LED点阵屏
51单片机键盘扫描程序解析
/****************************************键盘_不采用定时器_不延时特点:按键在松手后有效,灵敏度高,消耗资源少,运行效率高独立键盘为:K01=P2^4;K02=P2^5;K03=P2^6;K04=P2^7;矩阵键盘为:行(上到下)_P2.3_P2.2_P2. /**************************************** 键盘_不采用定时器_不延时 特点: 按键在松手后有效,灵敏度高,消耗资源少,运行效率高 独立键盘为:K01=P2^4;K02=P2^5;K03=P2^6;K04=P2^7; 矩阵键盘为:行(上到下)_P2.3_P2.2_P
[单片机]
<font color='red'>51单片机</font>键盘扫描程序解析
51单片机霍尔自行车里程测速仪设计升级版
说明 1、单片机是通用的无论51还是52、无论stc还是at都一样,引脚功能都一样。 程序也是一样的。 2、原理图中的.ddb、.Bkp等格式是要用protelse打开的,没有软件的不要紧, 我已帮您转换成word格式和pdf格式的了。 3、程序中的.c文件可以用记事本(文本文档)打开,就是程序了。其他的是写程序是自动生成的,没什么用的。 4、可以按照正面布局,不要按照实物的背面焊接,要按照原理图焊接。 数码管脚位排布说明: 正面朝自己,秒点在下,左下为1脚,逆时针排布,左上为最后一个脚!请坛友焊接前弄清脚位排布再焊接!祝你们成功! 废话不多说,直接上实物图: 说明 1、单片机是通用的无论51还是52、无论stc还是a
[单片机]
<font color='red'>51单片机</font>霍尔自行车里程测速仪设计升级版
51单片机 小车 L298N pwm调速 串口控制 按键控制
难点:1、串口定时器T1,和T0定时器优先级 2、pwm频率与占空比的设置 按键控制 按键1——前进 按键2——后退 按键3——加速 按键4——减速 (板子上只有四个按键) 串口控制 ‘1’——前进 ‘2’——后退 ‘3’——加速 ‘4’——减速 ‘5’——左转 ‘6’——右转 源码: #include reg52.h typedef unsigned char u8; typedef unsigned int u16; //L298N引脚定义 sbit ena = P0^0; sbit in1 = P0^1; sbit in2 = P0^2; sbit in3 = P0^3; sbit in4 = P0^4; sb
[单片机]
基于51单片机的自行车测速系统
一.系统概述 系统使用的模块有AT89C51单片机+LCD1602显示屏+霍尔测速模块。 本设计采用51单片机为核心控制,使用LCD1602显示采集到的速度,霍尔测速模块进行测速,测速的原理是通过磁感应原理检测开关变化量,通过检测两个开关量的时间间隔来计算速度。在实际应用中会将霍尔测速模块放置在轮胎上,就能完成自行车速度的检测。 二.仿真概述 1.通过LCD1602显示实时车速。 2.通过霍尔测速模块进行速度检测。 3.通过在霍尔模块处模拟开关量的变化,变化速度越快则显示的车速越快。 三.程序设计 使用Keil 51进行程序设计,打开Proteus时程序是默认烧录的状态,如果没有烧录点击AT89C51单片机并将程序
[单片机]
基于<font color='red'>51单片机</font>的自行车测速系统
12-基于51单片机的防火防盗GSM上报智能家居系统
具体实现功能: (1)以STC89c51单片机作为控制中心,由LCD1602液晶显示屏实时显示温度值与烟雾值; (2)利用单片机设计中主流的DS18B20 温度传感器对易发生火灾区域进行实时温度监测,MQ-2烟雾传感器可以检测到空气中的烟雾浓度异常,并利用 ADC0832实现模数转换; (3)在系统中专门设计了可以设置温度阈值及烟雾浓度阈值的按键,在有可能发生火灾的情况下,只要测得的数值超过设定好的报警阈值,就可以实现火灾报警(声光报警);另外,通过按键实现手动报警及手动取消; (4)当红外检测模块开始工作时,若有人进入,则会进行入侵报警; (5)利用GSM模块将测得的温度值与烟雾浓度实时发送到用户手机上,实现
[单片机]
12-基于<font color='red'>51单片机</font>的防火防盗GSM上报智能家居系统
AT89C51单片机在无线数据传输中的应用
摘要: 介绍无线数据传输系统的组成、AT89C51单片机串行口的工作方式及其与无线数字电台接口的软硬件设计与实现方法。 一般的数字采集系统,是通过传感器将捕捉的现场信号转换为电信号,经模/数转换器ADC采样、量化、编码后,为成数字信号,存入数据存储器,或送给微处理器,或通过无线方式将数据发送给接收端进行处理。无线数据传输系统就是 样一套利用无线手段,将采集的数据由测量站发送到主控站的设备。 1 系统组成 系统组成如图1、图2所示。 系统由测量站和主控站两部分组成。测量站主要完成对现场信号的采集、存储,接收遥控指令并发送数据。主控站的主要工作是发送遥控指令、接收数据信息、进行数据处理和数据管理、随机显示打印等。 2 A
[单片机]
AT89C<font color='red'>51单片机</font>在无线数据传输中的应用
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved