微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 51单片机长按键测试程序

51单片机长按键测试程序

时间:11-18 来源:互联网 点击:
#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;

}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top