51单片机控制键盘

这篇具有很好参考价值的文章主要介绍了51单片机控制键盘。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一.键盘

1.键盘

键盘是电子系统中人机对话的重要组成部分,是人向机器发出指令、输入信息的必须设备
键盘在单片机应用系统中是使用最广泛的一种数据输入设备。键盘是由多个按键组成的。

2.按键

按键通常是一种常开型开关,常态下按键的两个触点处于断开状态,按下按键时它们才闭合。
通常键盘有编码键盘和非编码键盘两种。编码键盘通过硬件电路产生被按按键的键值码,这种键盘使用方便,所需程序简单,但硬件电路复杂,
如计算机的键盘,单片机则通常不采用编码键盘。而软件编程来识别的称为非编码键盘,非编码键盘硬件电路简单。在单片机组成的各种系统中,最常用的是非编码键盘。

3.独立键盘与矩阵键盘

非编码键盘分为独立键盘矩阵键盘

  • 独立键盘:每个按键占用一个IO口,当按键数量较多时,lO口利用效率不高,但程序简单,适用于所需按键较少的场合。
  • 矩阵键盘:电路连按复杂,但提高了IO口利用率,软件编程较复杂。适用于使用大量按键的场合。
    51单片机控制键盘,硬件,# 51单片机,51单片机,计算机外设,mongodb

二.独立键盘

1.抖动

了解了独立键盘的原理图之后,我们知道如果键盘按下,那么线路导通IO口会接触到GND从而电压为0,所以我们可以通过IO口电压的变换来判断独立按键是否被按下。
结合上一篇控制单片机数码管的显示,我们很自然的想到如果按键按下实现数字加1显示的实验,为了好实验这里选择数码管的静态显示实验。
那么,有初始的源代码:

#include <reg52.h> //51头文件

#define uchar unsigned char	//宏定义
#define uint  unsigned int	//宏定义

sbit we = P2^7;	//位定义数码管位选锁存器接口
sbit du = P2^6;	//位定义数码管段选锁存器接口
sbit key_s2 = P3^0; //定义独立键盘S2的IO口
uchar num = 0;

//数码管段选表
uchar code leddata[]={ 
 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
 
                         };


void main()
{
		we = 1;//打开位选
		P0 = 0xfe;//左边第一位数码管显示
		we = 0;	//关闭位选

		
		while(1)
		{
			if(key_s2 == 0){
				num++;
				if(num == 10)
					num == 0
			}
		du = 1;	//打开段选
		P0 = leddata[num]; //显示num
		du = 0;	//关闭段选
		};
}

执行上面的代码后,你会发现单片机并没有按照我们想要的结果去运行,每当你按下时,数码管显示的结果并不是上一个加1,这是因为按键本身按下或释放存在抖动的原因,要想取得正确的结果,必须消除抖动。
51单片机控制键盘,硬件,# 51单片机,51单片机,计算机外设,mongodb
结合实际的波形,我们可以知道按下的过程中,下降沿的波形并不出现一次,自然而然的我们就必须把它变成理想的波形,方法就是采用延时函数。

2.松手检测

消除抖动的常见方法是使用延时函数,延时函数一般选择延时20ms左右即可完成。

#include <reg52.h> //51头文件

#define uchar unsigned char	//宏定义
#define uint  unsigned int	//宏定义

sbit we = P2^7;	//位定义数码管位选锁存器接口
sbit du = P2^6;	//位定义数码管段选锁存器接口
sbit key_s2 = P3^0; //定义独立键盘S2的IO口
uchar num = 0;

//数码管段选表
uchar code leddata[]={ 
 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
 
                         };
                      
//毫秒级延时函数
void delay(uint z)
{
	uint x,y;
	for(x = z; x > 0; x--)
		for(y = 114; y > 0 ; y--);
}

void main()
{
		we = 1;//打开位选
		P0 = 0xfe;//左边第一位数码管显示
		we = 0;	//关闭位选

		
		while(1)
		{
			delay(20);//消除抖动
			if(key_s2 == 0){
				num++;
				if(num == 10)
					num == 0
			}
		du = 1;	//打开段选
		P0 = leddata[num]; //显示num
		du = 0;	//关闭段选
		};
}

消除抖动你以为就完成了吗,继续运行,实际过程中,你会发现随着按下的时间,它还是并不是加1的运行,仔细思考你的代码,按键按下,num++一直在运行,显示的值也就不断变换,所以我们还需要进行松手检测,让每次按下只实现加1。
最后的代码为:

#include <reg52.h> //51头文件

#define uchar unsigned char	//宏定义
#define uint  unsigned int	//宏定义

sbit we = P2^7;	//位定义数码管位选锁存器接口
sbit du = P2^6;	//位定义数码管段选锁存器接口
sbit key_s2 = P3^0; //定义独立键盘S2的IO口
uchar num = 0;

//数码管段选表
uchar code leddata[]={ 
 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
 
                         };
                      
//毫秒级延时函数
void delay(uint z)
{
	uint x,y;
	for(x = z; x > 0; x--)
		for(y = 114; y > 0 ; y--);
}

void main()
{
		we = 1;//打开位选
		P0 = 0xfe;//左边第一位数码管显示
		we = 0;	//关闭位选

		
		while(1)
		{
			delay(20);//消除抖动
			if(key_s2 == 0){
				num++;
				while(!key_s2);//松手检测
			}
		if(num == 10)
			num=0;
		du = 1;	//打开段选
		P0 = leddata[num]; //显示num
		du = 0;	//关闭段选
		};
}

3.拓展

在原来只有按键s2的基础上,我们再增加一个s3,使其实现自减操作:
拓展代码:

#include <reg52.h> //51头文件

#define uchar unsigned char	//宏定义
#define uint  unsigned int	//宏定义

sbit we = P2^7;	//位定义数码管位选锁存器接口
sbit du = P2^6;	//位定义数码管段选锁存器接口
sbit key_s2 = P3^0; //定义独立键盘S2的IO口
sbit key_s3 = P3^1; //定义独立键盘S2的IO口
uchar num = 0;

//数码管段选表
uchar code leddata[]={ 
 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
 
                         };
                      
//毫秒级延时函数
void delay(uint z)
{
	uint x,y;
	for(x = z; x > 0; x--)
		for(y = 114; y > 0 ; y--);
}

void main()
{
		we = 1;//打开位选
		P0 = 0xfe;//左边第一位数码管显示
		we = 0;	//关闭位选

		
		while(1)
		{
			delay(20);//消除抖动
			if(key_s2 == 0){
				num++;
				while(!key_s2);//松手检测
			}
			if(key_s3 == 0){
				if(num > 0)
				num--;
				while(!key_s3);
				}
		if(num == 10)
			num=0;
		du = 1;	//打开段选
		P0 = leddata[num]; //显示num
		du = 0;	//关闭段选
		};
}

三.矩阵键盘

1.识别方法

矩阵键盘识别相对于独立键盘要复杂一些。右图矩阵键盘一共有4行和4列一共16个按键组成。
确定矩阵键盘上哪一个按键被按下可以采用列扫描行扫描。列扫描时先把接在列上面的所有IO口拉高接在行上的所有IO置低。当其中有一列内任何一个按键按下那么整条列线都会被拉低。同理,行扫描时先把接在行上面的所有IO口拉高,接在列上的所有IO置低。当其中有一行内任何一个按键按下那么整条列线都会被拉低。

这是一个数学问题,总共16个按键分为四行四列,我们只需要知道哪一列和哪一行就知道了哪个按键。所以列扫描就是确定列,行扫描就是确定行。

2.程序编写

知道矩阵键盘的识别方法后,当按下不同的按键,数码管显示不同的值:

#include <reg52.h> //51头文件

#define uchar unsigned char	//宏定义
#define uint  unsigned int	//宏定义

sbit we = P2^7;	//位定义数码管位选锁存器接口
sbit du = P2^6;	//位定义数码管段选锁存器接口
uchar keyvalue = 20;   //按键的值

//数码管段选表
uchar code leddata[]={ 
 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
 
                         };
                      
//毫秒级延时函数
void delay(uint z)
{
	uint x,y;
	for(x = z; x > 0; x--)
		for(y = 114; y > 0 ; y--);
}

//扫描函数
void keyscanf(){
	P3 = 0xF0;        //列扫描
	if(P3!=0xF0){     //判断按键是否被按下
		delay(10);      //延时消除抖动
		if(P3!=0xF0)
		{
			switch(P3)
			{
				case 0xe0: keyvalue=0;break;
				case 0xd0: keyvalue=1;break;
				case 0xb0: keyvalue=2;break;
				case 0x70: keyvalue=3;break;
			}
			P3=0x0f;         //行扫描
			switch(P3)
			{
				case 0x0e: keyvalue=keyvalue;break;
				case 0x0d: keyvalue=keyvalue+4;break;
				case 0x0b: keyvalue=keyvalue+8;break;
				case 0x07: keyvalue=keyvalue+12;break;
			}
			while(P3!=0x0f);          //松手检测
		}
		
	}
	
}

void main()
{
		we = 1;//打开位选
		P0 = 0xfe;//左边第一位数码管显示
		we = 0;	//锁存位选数据
	
		while(1)
		{
			keyscanf();  //不停检查键盘
			du = 1;//打开段选
			P0 = leddata[keyvalue];
			du = 0;//锁存段选数据
		}
}

3.联合编写

学习了独立按键和矩阵键盘后,有一个问题,如果在一个程序中既用到独立按键又用到矩阵键盘的时候,该怎么办?我们的单片机原理图中,独立按键和矩阵键盘使用的都是P3端口。文章来源地址https://www.toymoban.com/news/detail-783125.html

#include <reg52.h> //51头文件

#define uchar unsigned char	//宏定义
#define uint  unsigned int	//宏定义

sbit we = P2^7;	//位定义数码管位选锁存器接口
sbit du = P2^6;	//位定义数码管段选锁存器接口
uchar keyvalue = 22;   //按键的值

//数码管段选表
uchar code leddata[]={ 
 
                0x3F,  //"0"
                0x06,  //"1"
                0x5B,  //"2"
                0x4F,  //"3"
                0x66,  //"4"
                0x6D,  //"5"
                0x7D,  //"6"
                0x07,  //"7"
                0x7F,  //"8"
                0x6F,  //"9"
                0x77,  //"A"
                0x7C,  //"B"
                0x39,  //"C"
                0x5E,  //"D"
                0x79,  //"E"
                0x71,  //"F"
                0x76,  //"H"
                0x38,  //"L"
                0x37,  //"n"
                0x3E,  //"u"
                0x73,  //"P"
                0x5C,  //"o"
                0x40,  //"-"
                0x00,  //熄灭
                0x00  //自定义
 
                         };
                      
//毫秒级延时函数
void delay(uint z)
{
	uint x,y;
	for(x = z; x > 0; x--)
		for(y = 114; y > 0 ; y--);
}

//扫描函数
void keyscanf(){
	//4*4矩阵键盘扫描函数
	P3 = 0xF0;        //列扫描
	if(P3!=0xF0){     //判断按键是否被按下
		delay(10);      //延时消除抖动
		if(P3!=0xF0)
		{
			switch(P3)
			{
				case 0xe0: keyvalue=0;break;
				case 0xd0: keyvalue=1;break;
				case 0xb0: keyvalue=2;break;
				case 0x70: keyvalue=3;break;
			}
			P3=0x0f;         //行扫描
			switch(P3)
			{
				case 0x0e: keyvalue=keyvalue;break;
				case 0x0d: keyvalue=keyvalue+4;break;
				case 0x0b: keyvalue=keyvalue+8;break;
				case 0x07: keyvalue=keyvalue+12;break;
			}
			while(P3!=0x0f);          //松手检测
		}
		
	}
	
	//独立键盘扫描函数
	P3 = 0xff;
	if(P3!=0xff)
	{
		delay(10);//软件消抖
		if(P3!=0xff)
		{
			switch(P3)
			{
				case 0xfe: keyvalue=16;break;//S2
				case 0xfd: keyvalue=17;break;//S3
				case 0xfb: keyvalue=18;break;//S4
				case 0xf7: keyvalue=19;break;//S5
			}
			while(P3!=0xff);  //松手检测
		}
	}
	
}

void main()
{
		we = 1;//打开位选
		P0 = 0xfe;//左边第一位数码管显示
		we = 0;	//锁存位选数据
	
		while(1)
		{
			keyscanf();  //不停检查键盘
			du = 1;//打开段选
			P0 = leddata[keyvalue];
			du = 0;//锁存段选数据
		}
}

到了这里,关于51单片机控制键盘的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 51单片机(一)软硬件环境和单片机介绍

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月11日
    浏览(50)
  • 51单片机矩阵键盘

    目录 前言 一、矩阵键盘扫描 二、LCD1602显示矩阵键盘键值 三、趣味小项目——密码锁 总结          矩阵键盘的原理很浅显易懂,不涉及任何寄存器,就是纯线路连接。         矩阵键盘的内部接线图如下:         不难看出其组成就是多个独立按键彼此相连形成,在

    2024年02月08日
    浏览(64)
  • 51单片机--矩阵键盘

    一、接线(4×4) 将16个键盘排成4行4列,第一行将每个按键的一端连接在一起构成行线,第一列将每个按键的另一端连接在一起构成列线,所以共有4行4列8根线,连接到单片机的GPIO口。 二、原理 总体来说检测该键对应IO口是否为低电平。 1、检测时,先将一行设为低电平,其

    2024年02月11日
    浏览(42)
  • 51单片机入门——矩阵键盘(附51代码)

    硬件如图非常简单,将一个4*4的矩阵键盘的8个管脚引到端子上,在连接到8个I/O口上,ARRAY_H代表着行,ARRAY_L代表着列,当行与列的电平都置低的时候,就选中的相应的矩阵按键,比如当s1按下时,ARRAY_H1会置低,其他ARRAY_H给高电平,那么选中的就是第一行,然后到列,ARRAY_

    2024年02月11日
    浏览(43)
  • 单片机/嵌入式小白教程—硬件(三)51单片机最小系统

    目录 简介 51单片机器件原理图 复位电路 供电电路 晶振电路 下载电路 最小系统原理图  更加方便的51单片机 传统51单片机最小系统包含:复位电路、供电电路、晶振电路、下载电路   其中, 第9脚(RST)为复位引脚, 第40脚(VCC)第20脚(GND)为供电引脚, 第19脚(XTAL1)第

    2024年02月08日
    浏览(75)
  • MCS-51单片机的硬件结构

    按功能可分为8个部件,通过片内单一总线连接起来 控制方式:SFR对各功能部件集中控制 1、微处理器:CPU运算部件 控制部件 2、数据存储器:RAM 数据存储就是暂存一些在系统运行的过程当中所生成的一些临时性的数据,采集数据时临时采集到的一些数据和一些运算的中间结

    2024年02月03日
    浏览(40)
  • 6.51单片机之矩阵键盘

    👻 1.矩阵键盘的介绍 在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。 采用逐行或逐列的“扫描”,就可以读出任何位置按键的状态。 结构:在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。在矩阵式键盘中,每条

    2024年02月07日
    浏览(44)
  • 51单片机学习笔记-4矩阵键盘

    [toc] 注:笔记主要参考B站江科大自化协教学视频“51单片机入门教程-2020版 程序全程纯手打 从零开始入门”。 注:工程及代码文件放在了本人的Github仓库。 在键盘中按键数量较多时,为了减少I/O口的占用,通常将按键排列成矩阵形式。采用逐行或逐列的“扫描”,就可以读

    2024年02月06日
    浏览(56)
  • 51单片机(六)矩阵键盘和矩阵键盘密码锁

    ❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要从零基础开始学习入门单片机,且有一定C语言基础的的童鞋

    2024年02月04日
    浏览(53)
  • 51单片机点灯实验(含程序+仿真+硬件实验)

    一、实验原理 LED发光二极管核心为PN结,单向导电,有阴极和阳极,两极均可以控制,需要亮起来,电流不能过大和过小,过大,烧坏二极管,过小,电光效应弱,发光不明显,引入“限流电路”。为减少I/O引脚的消耗,一般控制一极,有阳极控制法和阴极控制法。阳极控制

    2024年02月04日
    浏览(53)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包