单片机AT89C51--7.按键(独立按键,矩阵按键)
1.键盘类型
1.1 编码键盘
通过硬件电路产生被按按键的键值码,程序简单但是硬件电路复杂
如计算机键盘
1.2 非编码键盘
软件编程来识别的称为非编码键盘,非编码键盘硬件电路简单,单片机中最常是非编码键盘
2.独立键盘和矩阵键盘
非编码键盘分为独立键盘和矩阵键盘
2.1 独立键盘
一开始线寄存器默认都是高电平,G为0V,G,S不导通。管脚为5V
这就是上拉电阻。
按下按键,管脚和地导通,电压变为0V
未按下按键,管脚和Vcc连接,电压为5V
2.2 矩阵键盘
3. 按键特性
4. 编程
4.1 独立键盘
按下S2按钮,数字加1,按下S3数字减1,最高不超过9,最低不低于0.高于9变为0.小于0还是为0
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DUAN = P2^6;
sbit WEI = P2^7;
sbit KEY_S2 = P3^0;
sbit KEY_S3 = P3^1;
char num=0;//注意这个带符号num,否则后面num--;
0-1=-1,如果设为uchar的话,
后面会出现未知数据显示
//显示数据 0123456789
uchar table[] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,};
//延时函数
void delay(uint i)
{
uint j, k;
for(j=i; j>0; j--)
for(k=114; k>0; k--);
}
//显示函数
void show(uchar i, uchar j, uint k)
{
P0 = 0XFF;//消除残影
WEI = 1;
P0 = i;
WEI = 0;
DUAN = 1;
P0 = table[j];
DUAN = 0;
delay(k);//短暂停留
}
void add()
{
if(KEY_S2 == 0)
{
delay(20);//软件消抖
if(KEY_S2 == 0)
{
num++;
if(num == 10)
num = 0;
}
while(!KEY_S2);
}
show(0XFE, num, 5);
}
void sub()
{
if(KEY_S3 == 0)
{
delay(20);//软件消抖
if(KEY_S3 == 0)
{
num--;
if(num < 0)
num = 0;
}
while(!KEY_S3);
}
show(0XFE, num, 5);
}
void main()
{
while(1)
{
add();
sub();
}
}
4.2 矩阵键盘
开关语句:
switch(表达式)
{
case 常量表达式1:语句1;
break;
case 常量表达式2:语句2;
break;
}
编程思路
进行 列与行的扫描
如:先列扫描
P3 = 0XF0
按下S6,P3^4变为低电平.
相当于P3.0和P3.4连接,变为低电平,就像电源接电阻接地.在电阻末端和地电平都是0V
再行扫描
P3 = 0X0F
同理
P3.0变为低电平
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[] = {
0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,
0x77,0x7C,0x39,0x5E,0x79,0x71,0x76,0x38,0x40,0xFF,
};
sbit WEI = P2^7;
sbit DUAN = P2^6;
uchar KeyVal;
uchar Key;
void Delay(uint i)
{
uint j, k;
for(j=i; j>0; j--)
for(k=114; k>0; k--);
}
void Show(uchar i, uchar j, uchar k)
{
P0 = 0XFF;
WEI = 1;
P0 = i;
WEI = 0;
DUAN = 1;
P0 = table[j];
DUAN = 0;
Delay(k);
}
void KeyScan()
{
// 先列后行
P3 = 0XF0;
if(P3!=0XF0)
{
Delay(10);
if(P3!=0XF0)
{
switch (P3)
{
case 0xe0: KeyVal = 0; //1列
break;
case 0xd0: KeyVal = 1; //2列
break;
case 0xb0: KeyVal = 2; //3列
break;
case 0x70: KeyVal = 3; //4列
break;
}
}
// 确定行
P3 = 0X0F;
if(P3 != 0X0F)
{
Delay(10);
if(P3!=0X0F)
{
switch(P3)
{
case 0x0e: Key = KeyVal;
break;
case 0x0d: Key = KeyVal + 4;
break;
case 0x0b: Key = KeyVal + 8;
break;
case 0x07: Key = KeyVal + 12;
break;
}
}
}
}
// 独立矩阵
P3 = 0XFF;
if(P3 != 0XFF)
{
Delay(10);
if(P3!=0XFF)
{
switch(P3)
{
case 0xFE: Key = 16;
break;
case 0xFD: Key = 17;
break;
case 0xFB: Key = 18;
break;
case 0xF7: Key = 19;
break;
}
}
}
}
void main()
{
while(1)
{
KeyScan();
Show(0xFE, Key, 10);
}
}