单片机 键盘
键盘分类: (1)编码键盘 键盘上闭合键的识别由专门的硬件编码器实现,并产生键编码号或键值的称为编码键盘,如计算 机键盘。
(2)非编码键盘 靠软件编程来识别的键盘称为非编码键盘,在单片机上运用较多的是非编码键盘,非编码键盘 又分为独立键盘和行列式键盘(矩阵式)键盘。
独立键盘的检测 : 键盘的一端接地,另一端接单片机的I/O口。开始时给I/O口赋一高电平,当键盘闭合时,I/O口通过键盘与 地相连,变成低电平,程序一旦检测到I/O口变成低电平则说明按键被按下。
TX-1C实验板上独立键盘(最下面的一排)与单片机的 P3^4 ~ P3^7 口相连。
矩阵键盘的检测 :
检测时,我们先送一列为低电平,其余几列为高电平(此时我们确定了列数),然后我们立即轮流检测一次各行是否有低电平,若检测到某一行为低电平(确定了行数),则我们可以确定当前哪一行哪一列的键被按下。
// 用数码管的前两位显示仪个十进制数,变化范围是 00~59, 开始时显示00,每按下S2键,数值加1?
//每按下S3键数值减1,每按下S4键,数值归零,每按下S5键,利用定时器功能使数值开始自动每秒加1,
//再次按下S5键,数值停止自动加1,保持显示不变
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit key1=P3^4;
sbit key2=P3^5;
sbit key3=P3^6;
sbit key4=P3^7;
sbit dula=P2^6; // 申明U1锁存器的锁存端, (段选)
sbit wela=P2^7; // 申明U2锁存器的锁存端, (位选)
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x77,0x7c,
0x39,0x5e,0x79,0x71
};
uchar numt0,num;
void keyscan();
void delayms( uint );
void display( uchar ); //显示子函数
void init(); //初始化函数
void main()
{
init(); //初始化函数
while(1)
{
keyscan();
display(num);
}
}
void keyscan()
{
if( key1==0 )
{
delayms(10);
if( key1==0 )
{
num++;
if( num==60 ) //当到60时重新归0
num=0;
while( !key1 ); // 等待按键释放
}
}
if( key2==0 )
{
delayms(10);
if( key2==0 )
{
if( num==0 ) // 当到0时重新归60
num=60;
num--;
while( !key2 );
}
}
if( key3==0 )
{
delayms(10);
if( key3==0 )
{
num=0; //清零
while( !key3 );
}
}
if( key4==0 )
{
delayms(10);
if( key4==0 )
{
while( !key4 );
TR0=~TR0; //启动或停止定时器0
}
}
}
void delayms( uint xms )
{
uint i,j;
for( i=xms; i>0; i--)
for( j=110; j>0; j--);
}
void display( uchar numdis ) //显示子函数
{
uchar shi,ge; // 分离两个要显示的数
shi = numdis/10;
ge = numdis%10;
dula=1;
P0=table[shi]; // 送入十位段选信号
dula=0;
P0=0xff; // 消影语句
wela=1;
P0=0xfe;
wela=0;
delayms(5);
dula=1;
P0=table[ge]; //送入个位段选信号
dula=0;
P0=0xff;
wela=1;
P0=0xfd;
wela=0;
delayms(5);
}
void init() // 初始化函数
{
TMOD = 0x01; // 设定定时器0为工作方式1(0000 0001)
TH0=( 65536-45872)/256; //装初值50ms一次中断
TL0=( 65536-45872)%256;
EA=1; // 开总中断
ET0=1; // 开定时器0中断
}
void T0_time() interrupt 1
{
TH0=( 65536-45872 )/256; //重装初值
TL0=( 65536-45872 )%256;
numt0++;
if( numt0==20 ) //如果到了20次,说明1秒时间到了
{
numt0=0; // 把num清零重新再计20次
if( num==60 )
num=0;
}
}