51单片机长按键测试程序

发布者:心境恬淡最新更新时间:2016-09-08 来源: eefocus关键字:51单片机  长按键 手机看文章 扫描二维码
随时随地手机看文章
#include
#include
/*
程序功能:  本程序用于测试4X4矩阵键盘; 且具有长按测能力.
            当按下按键后,在LCD1602上显示出按下的键号如:K1 K2.... K16;
            当按下一个按键 超过1S时间时,每250MS就返回一个键值;实现长按键的功能;
            同时把键值通过串口发送到口上显示; 
程序说明:这是一种传通的采用延时来进行按键扫描按键驱动与测试程序;这种方法在
          实际项目编程中是不使用的。 用在教学中 ,学生刚开始学习单片机时。
注意:在此程序中只显示了K4长按凳时情况。若要想对其它铵键长按处理,只需要增加
      相关的处理即可。
*/
/*
矩阵键盘引脚定义
*/
sbit keyin4 = P2^7;
sbit keyin3 = P2^6;
sbit keyin2 = P2^5;
sbit keyin1 = P2^4;
sbit keyout1 = P2^3;
sbit keyout2 = P2^2;
sbit keyout3 = P2^1;
sbit keyout4 = P2^0;
 
//宏定义
#define TH0_NUM 1000     //便于程序的移植;
#define TL0_NUM 1000
 
bit Flag1s,Flag250Ms,Flag2Ms;  //时间到位标志
 
//lcd1602显示数组
unsigned char  keynum[]="keynum:k   ";
unsigned char  keycount[3]="000";
 
//键值查询数组
                         //k1,k2,k3,k4,k5,k6,k7,k8,
unsigned char code keytabel[]={0xe7,0xd7,0xb7,0x77,0xeb,0xdb,0xbb,0x7b,
                         //k9,k10,k11,k12,k13,k14,k15,k16,
                          0xed,0xdd,0xbd,0x7d,0xee,0xde,0xbe,0x7e};
/*
外部函数声明
*/
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
void ConfigUART(unsigned int baud); 
void DelayMs(unsigned int ms);
unsigned char  keyscan();
 
void InitTimer0();
 
/*
主程序
*/
void main()
{
 unsigned char i,j,keytemp=0;
 InitTimer0();
 ConfigUART(9600);
InitLcd1602();
LcdShowStr(0,0,keynum);
while(1)
    {
     keytemp=keyscan();
     if(keytemp!=0)  //判断是否有按键按下; 
      {       
       for(i=0;i<16;i++)       //当有按键按下时,查表获取键值; 
       {
        if(keytemp==keytabel[i])
        break;
       }
         
       keynum[8]=(i+1)/10+0x30;
       keynum[9]=(i+1)%10+0x30;
       TI=1;
       SBUF=keytemp;
       while(TI!=1);
       TI=0;
       LcdShowStr(0,0,keynum);
       if(keytemp==0x77)          //用于检测长按向上键K4时,在LCD1602第二行显示
           {                      //每250MS加1;
           j++; 
           if(j>254)
           j=0;
           keycount[0] = j/100%10+0x30;
           keycount[1] = j/10%10+0x30;
           keycount[2] = j%10+0x30; 
          
           TI=1;               //用于串口也每隔250MS打印加1;
           printf("key is long pushing %s \n",keycount); 
           while(TI!=1);
            TI=0; 
           }
        LcdShowStr(0,1,keycount);
 
      }
    }
}
/*
函数功能:N毫秒延时
*/
void DelayMs(unsigned int ms)
{
unsigned int i,j;
for(i=0;i
for(j=0;j<113;j++);
 
}
/*
函数功能:矩阵键盘扫描(带长按键检测功能)
*/
unsigned char  keyscan()
{
static unsigned char num1,temp;
    P2 = 0xf0;
    num1=P2;
    if(num1!=0xf0)
      {
      DelayMs(50);
      num1=P2; 
      if(num1!=0xf0)
           {
            TR0=1;   //打开定时器
            temp=num1;//
            P2 =   0x0f;
            DelayMs(1);
            num1=P2;    
            temp =temp|num1;
            do
             {
                P2 = 0xf0;
                num1=P2;
                if(Flag1s == 1) //判断按下的键是否1S没松手; 
             {
                    if(Flag250Ms==1)  //若1S没松手,说明长按了某键 ;则每250MS返回
 
                        {               //一次键值;这样就实现了长按某键的功能
                         Flag250Ms=0;
                        return temp;
                 }
             }
             }
            while(num1!=0xf0);      
         }
        else
        {
         TR0=0;           //若没有按下,则关闭定时器
         Flag1s=0;
         Flag250Ms=0;
         temp=0;
         }      
      }
    else
       {     
        TR0=0;
        Flag1s=0;
        Flag250Ms=0;
        temp = 0;
        }
    TR0=0;         //松手时,也要关闭定时器,并且清0几个标志位  ; 
    Flag1s=0;
    Flag250Ms=0;
    return temp;      
}
    
    
    /*
    函数功能:定时器0初始化,设定每1MS中断一次
    */
    
    void InitTimer0()
    {
        TMOD &=0xf0;     //这种操作模式,不会破坏寄存器的其它设置;
        TMOD |=0x01;       //方式1,16位定时器
        TH0/=(65536-TH0_NUM)/256;
        TL0=(65536-TL0_NUM)%256;
        EA=1;
        ET0=1;
        TR0=0; 
    }
    /*
    函数功能:定时器0中断服务程序
    */
    void Timer0_Interrupt()  interrupt 1
    {
        static unsigned char i,j,k;
        TH0=(65536-TH0_NUM)/256;
        TL0=(65536-TL0_NUM)%256;
        i++;j++;
        if(i>2)
         {
            i=0;
            Flag2Ms=1;
         }
        if(j==250)
         {
            j=0;
            Flag250Ms=1;
            k++;
            if(k==4)
             {
                k=0;
                Flag1s=1;
             }
         }
}
关键字:51单片机  长按键 引用地址:51单片机长按键测试程序

上一篇:采用多单片机的液位监控仪设计与实现
下一篇:51单片机4X4矩阵键盘驱动与应用程序(C语言)

推荐阅读最新更新时间:2024-03-16 15:08

51单片机C编程(四、定时器秒表数码管显示)
这个程序实现了通过定时器定时的秒表,并通过两位的数码管显示 #include reg51.h #define uchar unsigned char #define uint unsingned int #define LED P0 uchar tab ={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};//共阳数码管数字码 uchar num,t,shi,ge; //----------------子函数初始化-------------------- void init(); void timer0(); void display(); void delay(uch
[单片机]
51单片机学习笔记【0】——基础知识
一.单片机三大资源 1.Flash—-程序存储空间 相当于计算机的硬盘,可实现断电后数据不丢失。 2.RAM—-数据存储空间 相当于计算机的内存,用来存储程序运行过程中产生和需要的数据,断电后数据丢失,优点是读取速度快,可无限次写入。 3.SFR—-特殊功能寄存器 单片机每个功能都对应一个 多个SFR,用户通过对SFR的读写来实现单片机的功能。 二.单片机的最小系统 1.电源 主流单片机采用5V和3.3V的电压,供电电路40引脚接+5V,通常也成为VCC或VDD,代表电源正极;20引脚接GND,代表电源的负极,也是接地的意思。 2.晶振 晶体振荡器,作用是为单片机系统提供基准时钟信号,一直不停振荡,接有电容,作用是
[单片机]
<font color='red'>51单片机</font>学习笔记【0】——基础知识
手把手教你学51单片机:变量进阶与点阵LED
一、变量的作用域 作用域:变量的有效范围。分为:局部变量和全局变量。 1.1局部变量 在函数内部声明的变量,只在本函数内部可以使用。 1.2全局变量 在函数外声明的变量就是全局变量。 二、变量的存储类别 变量的存储类别分为自动、静态、寄存器和外部四种。 局部变量如果不加static修饰都属于自动变量。关键词为auto,可以省略。 全局变量均为静态变量。 局部变量加 static 关键字也为静态局部变量。特点是,只赋一次初值,在之后使用中,可以保存前次的执行结果。 eg: static unsigned char i=0; i 为静态局部变量,初始化 i=0 只执行一次。 三、点阵的初步认识 8*
[单片机]
51单片机—8255A详细介绍(全!)—04
这个学期学的微机原理~~ ,课件很是给力啊~~呵呵 8255A的原程序设计什么的网上很多~~也有好多Proteus仿真的,但是这里面的大多数都是简单的几行搞定的~~我晕咧,里面的好多东西其实都没有用到~~ ,呵呵,其实我也就是做个小小的实验,先把原理贴出来,供以后用,其中Proteus仿真真的不给力啊~~浪费了我好多时间,定时计数器竟然一会快,一会慢~~shit,让我白白调了半天~~这么简单的程序 看看我的仿真的程序~~(c语言程序在最后~~) 其中有两个可以控制移位方向的,就是为了验证那个Proteus仿真51的时候定时器不准确的 然后就是详细介绍了 8255A的详细介绍 1、引脚图: 2、内部结构和引脚
[单片机]
<font color='red'>51单片机</font>—8255A详细介绍(全!)—04
51单片机红外解码库文件
遥控器就是下面图上的那种 完整的程序源码下载地址:http://www.51hei.com/bbs/dpj-20623-1.html 红外解码文件 ir.h/*--------------------------------------------------- 名称:红外驱动 编写:YuMin_Dong 时间:2012.11.26 ---------------------------------------------------*/ #ifndef _IR_H_ #define _IR_H_ uint8 irtime; uint8 irdata /*,irprodata */; bit irreceive_ok,irpro_
[单片机]
<font color='red'>51单片机</font>红外解码库文件
AT89C51单片机快热式热水器程序设计
快热式热水器程序MCU AT89C51 XAL 12MHz //#pragmaSRC #include #include #include voiddelay(unsignedint);//延时函数 voiddisplay(void);//显示函数 unsignedcharkeysCAN(void);//按键扫描处理函数 voidheatCTRl(void);//加热控制函数 voidtemptest(void);//测温函数 sbitswkey=P1^0;//开关键 sbitupkey=P1^1;//加热档位“+”键 sbitdownkey=P1^2;//加热档位“-”键 sbitbuzz=P1^05;//蜂鸣器输出端 sbit
[单片机]
AT89C<font color='red'>51单片机</font>快热式热水器程序设计
Keil与Proteus实现51单片机完美联调
之前我们介绍过Proteus单片机的程序仿真调试,但是对于绝大部分单片机爱好者来说,最熟悉的开发软件还是Keil,我们再来详细介绍下Proteus怎么结合Keil软件搭建强大的51单片机联合调试环境。 我们先来看下联合调试仿真效果 Keil C51软件版本:V9.54 Proteus软件版本:8.9 怎么搭建这种联合调试环境,我们接下来一步一步实现 我们这里需要用到一个“VDM51.dll”的文件 下载地址: VDM51.dll 163.8K · 百度网盘 第一步:将文件复制到Keil C51的安装目录下 我这里的Keil C51目录是在 D:Keil_v5C51BIN 这里需要修改 TOOLS 这个文件
[单片机]
Keil与Proteus实现<font color='red'>51单片机</font>完美联调
MCS-51单片机与CPLD/FPGA接口逻辑设计
在功能上,单片机与大规模CPLD有很强的互补性。单片机具有性能价格比高、功能灵活、易于人机对话、良好的数据处理能力潍点;CPLD/FPGA则具有高速、高可靠以及开发便捷、规范等优点。以此两类器件相结合的电路结构在许多高性能仪器仪表和电子产品中仍将被广泛应用。本文就单片机与CPLD/FPGA的接口方式作一简单介绍,希望对从事单片机和CPLD/FPGA研发的朋友能有所启发。 单片机与CPLD/FPGA的接口方式一般有两种,即总线方式与独立方式,分别说明如下: 一、总线方式 单片机以总线方式与CPLD/FPGA进行数据与控制信息通信有许多优点。 (1)速度快。如图一所示,其通信工作时序是纯硬件行为,对于MCS-51单片机,只需一条单字节
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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