51单片机长按键测试程序
#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; }
51单片机长按 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)