51单片机独立/矩阵键盘(学习笔记)

**4.1 关于独立键盘**

是第一天在这里记相应的学习笔记。日后一定依据学习的频率和时间随时更。

关于按键,51单片机里比较常见的是他的开关(自锁式小按键,弹性很好)以及常用的矩阵键盘上的弹性按键。这个按键当矩阵按键时是以输入口的方式使用的。且一般都会给键盘相接的I/O口以高电平。单片机需要检测的是I/O这路是否处于高电平状态。

     由图所示,当开关按下后,I/O接地,则为低电平。在这里规定开关导通低电平,断开高电平。

在这里插入图片描述
另外,在单片机开发中一般使用软件去抖的方法,即通过延时避开震荡的波形。
如果抖动是8ms的话 delay 10ms就够了。
在这里插入图片描述
独立键盘与8051芯片的连接图如下,可以发现在这里几个按键键盘的一端接到了一起并接地。
在这里插入图片描述
下来用一个实际程序来演示一下独立键盘的操作。
在这里插入图片描述
分析:
可以看到这是一个十分基本的键盘操作,其中:
1.变化范围0-59意味着要做循环,当有大于59数出现时要置零
2.开始显示是00说明是两位数码管,分为十位和个位,写出unchar code table[]的数组后,dula段选对应数组中的值,wela位选对应地址。
3.要用到定时器的中断功能,可用定时器0/1的第一方式。S5这里可以考虑对TR0取反,这样子可以实现工作状态的变化。
下面是代码部分,有详细的注释
4.50ms*20=1s 体现在(65536-45872)

#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;
sbit wela=P2^7;
//提示 如果主函数没有思路,可以先一步一步写好子函数,之后思路就清楚了
/*加延时的目的是因为单片机执行速度快,且是循环检测按键,
若不加延时可能会出现一个循环体中程序被执行好几次的情况*/
uchar code table[]= 
{0x3f,0x06,0x5b,0x4f,
 0x66,0x6d,0x7d,0x07,
 0x7f,0x6f,0x77,0x7c,
 0x39,0x5e,0x79,0x71
};//LED数码管显示,由1--F
void delayms(uint);//提前声明延时函数
uchar numt0,num;//定义无符号的两个变量,其中num应该是秒数

void display(uchar numdis)//显示子函数
{
		uchar shi,ge;
		shi=numdis/10;
		ge=numdis%10;
	
		dula=1;//段选(与数码管显示有关)
		P0=table[shi];//打开寄存器。让P0端口(接收到?)
		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 delayms(uint xms)//延时子程序
{
	uint i,j;
	for(i=xms;i>0;i--)
		for(j=110;j>0;j--);
}

void init()//初始化程序
{
	TMOD=0x01;//定时器0的方式一
	TH0=(65536-45872)/256;//20ms
	TL0=(65536-45872)%256;//这样子其实储存了20ms所包含的全部信息
	EA=1;//总使能--开总中断?
	ET0=1;//开定时器0的中断
}

void keyscan()//键盘扫描函数
{
	if(key1==0)//键盘1功能,按下一次加1
		delayms(10);//软件延时,防抖动
		if(key1==0)
		{
			num++;
			if(num==60)
			{
				num=0;
			}
			while(!key1);//给一个死循环
		}
	if(key2==0)//键盘2功能,按一次减一,到零自动到59(注意59和60之间的设置关系)
	{
		delayms(10);
		if(key2==0)
		{
			if(num==0)
				num=60;
			num--;
			while(!key2);
		}
	}
	
	if(key3==0)//直接置零
	{
		delayms(10);
		if(key3==0)
		{
			num=0;
			while(!key3);
		}
	}
	
	if(key4==0)//防抖+改变数码管的状态(计数/停止,这个就可以借助TR0)
	{
		delayms(10);
		if(key4==0)
		{
			while(!key4);
			{
				TR0=~TR0;
			}
		}
	}
}

void main()//主函数
{
	init();//初始化
	while(1)//构造循环体,其中包括键盘输入功能(低电平有效)以及显示功能
	{
		keyscan();
		display(num);//显示功能是通过寄存器dula和wela控制段选与位选
	}
}

void T0_tinme()interrupt 1//中断函数1
{
	TH0=(65536-45872)/256;
	TL0=(65536-45872)%256;
	numt0++;
	if(numt0==20)//代表1s到了
	{
		numt0=0;
		num++;
		if(num==60)//60秒到,一个周期结束
			num=0;
	}
}

4.2 矩阵键盘的检测
矩阵键盘就是在独立键盘基础上加了行列检测。
以常用的4*4为例,即先给一行(1-4行)高电平,再检测1-4列中有没有出现低电平,如果出现低电平就看好是哪个列出现如此问题,从而确定按键的位置(用坐标地址的形式表示)。
在这里插入图片描述
原理图与独立键盘的差别在于这里的行跟列接在了一起,形成了一个四行四列的便于检索的电路。当行给高电平后,检测对应列就可。
下面是一个例题。
在这里插入图片描述
分析:

  1. 是要按矩阵键盘上的16位依次操作显示出数码管上的0-15

  2. 函数display(),用来点亮数码管,这其中应有dula和wela两个寄存器的使能端

  3. 函数delayms()用于延时

  4. 函数matrixscan()用于矩阵键盘的检测,这其中分为四个大部分,分别为对1/4行操作后----对所有列(1-4)进行检索。

    直接上代码了


```c
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit dula=P2^6;
sbit wela=P2^
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值