单片机AT89C51--7.按键(独立按键,矩阵按键)

本文详细介绍了单片机中常见的两种非编码键盘——独立键盘和矩阵键盘。独立键盘通过上拉电阻实现,按下按键时电压变化;矩阵键盘则涉及行列扫描的编程实现。内容包括按键特性和对应的编程方法,例如使用switch语句进行状态判断,并给出了具体的扫描流程解释。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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);		
	}
}



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值