-
2021-05-23 01:40:34
//小菜出品---严禁抄袭,转载请注明出处
#include
#include
#define uchar unsigned char
#define uint unsigned int
uchar idata x,y;
uchar code disp_code[] =
{
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90,
// 0-9 0 1 2 3 4 5 6 7 8 9
0x88, 0x83, 0xc6, 0xa1, 0x86, 0x8e,
// 10-15 a b c d e f
0x7F, 0xBF, 0x9C, 0xFF
// 16-19 . - 。null
}; //数码管显示值列表
void delay(uchar c) //延时函数
{
char a,b;
for(a=c;a>0;a--)
for(b=110;b>0;b--);
}
uchar key_scan() //键盘扫描函数
{
uchar k;
uchar z;
x=0x00;
y=0x00;
P3=0xf0; //先给P3赋一个初值
if(P3!=0xf0) //判断P3不等于所赋初值,说明有健按下
{
delay(10); //消除键盘抖动 延时10ms
if(P3!=0xf0)
{
x=P3; /*这里稍作解释:起初我们已经给P3赋了一个0xf0的值,如果有键按下,P3便一定不再是0xf0 ,
如果我们这时查看P3的值我们就能知道是哪一列的键按下了(说明一下,我的开发板上P3.0-P3.3接的是列)
但这时我们先不看P3的值,这时我们先把P3的值赋给x,再给P3赋一个0x0f的值,由于这两条语句执行的速度是
很快的,是us级的,而我们按一个按键怎么也得几十到上百ms,尽管我们在前面已经做过一个10ms的延时,但是
在我们给P3重新赋值后,按键一定还是闭合的,所以P3被赋0xof后由于有按键闭合,故P3的值又变了,这时候我们
查看P3的值就可以判断出来是是哪一行的按键按下了.然后我们把这时的P3值赋给y,再用x或上y,把他们的值赋给z
然后判断z的值就可以知道是具体哪一个键被按下了!(行和列都确定了,具体是哪一个键自然就确定了) */
P3=0x0f;
y=P3;
z=x|y;
switch(z)
{
case 0xee: k=0; break;
case 0xed: k=1; break;
case 0xeb: k=2; break;
case 0xe7: k=3; break;
case 0xde: k=4; break;
case 0xdd: k=5; break;
case 0xdb: k=6; break;
case 0xd7: k=7; break;
case 0xbe: k=8; break;
case 0xbd: k=9; break;
case 0xbb: k=10;break;
case 0xb7: k=11;break;
case 0x7e: k=12;break;
case 0x7d: k=13;break;
case 0x7b: k=14;break;
case 0x77: k=15;break;
}
}
}
return(k);
}
void main()
{
uchar dat;
while(1)
{
P3=0xf0;
while(P3!=0xf0)
{
dat=key_scan();
P1=0;
P0=disp_code[dat];
}
}
}
我感觉一般初学者会有疑问的地方 已经做出了详细的解释
如果还有弄不明白的地方 可以回帖提问 我会尽量做出解答
以期共同进步
更多相关内容 -
简单了解矩阵键盘扫描的方法原理
2021-01-12 20:19:27键盘扫描方法是:行线P10~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时程序以此来去除按键... -
51单片机矩阵键盘扫描程序详解
2020-07-19 07:09:45本文为51单片机矩阵键盘扫描程序,希望对你的学习有所帮助。 -
矩阵键盘扫描Verilog代码
2019-09-01 17:51:244*4矩阵键盘扫描的Verilog代码。该代码中加入了按键去抖模块,性能十分稳定,在DEI开发板上验证通过。 verilog , 按键去抖 , 矩阵键盘扫描 -
51单片机矩阵键盘扫描-线反转法
2020-11-12 15:16:43本代码利用矩阵键盘行线和列线以及引脚上高低电平变化的规律以2进制来判断按键位置从而显示在数码管上, 其中运用到数字电路的逻辑运算。 线反转法扫描方式代码少,更便于理解和掌握。 所有代码加起来不超过40行。 -
【实验15】矩阵键盘扫描_childrenjwf_键盘扫描_
2021-09-30 07:31:414*4矩阵键盘扫描子程序,适用于51单片机 -
矩阵键盘扫描
2019-01-05 22:24:30适用于C语言相关专业的同学练习编程,并进行矩阵键盘扫描的仿真,能够直接代入单片机使用。 -
51单片机矩阵键盘扫描程序
2020-07-15 07:47:23本文为 51单片机矩阵键盘扫描程序,下面一起来学习一下 -
单片机4x4矩阵键盘扫描程序
2020-07-19 02:53:18本文为单片机4x4矩阵键盘扫描程序,希望对你的学习有所帮助。 -
基于CPLD 的矩阵键盘扫描模块设计
2020-07-14 00:54:18摘要: 为了在不增加CPU工作负担的前提下,实现标准键盘和矩阵键盘双键盘同时工作,提出了一种基于复杂可编逻辑器件(CPLD)的矩阵键盘扫描方案,实现了在矩阵键盘状态控制下CPLD 自动完成键盘扫描、编码、输出的... -
4*4矩阵键盘扫描数码管显示程序
2017-05-24 23:59:101.4*4矩阵键盘(返回键值) 2.数码管显示 3. 实现驱动分层隔离,提供函数接口调用 4.不支持多次按键的触发效果 5.SDCC +P89V51RB2 6.周立功实验板 -
矩阵键盘扫描 C语言
2017-07-12 08:24:19基于51单片机的一种矩阵键盘扫描程序 -
EDA/PLD中的基于CPLD 的矩阵键盘扫描模块设计
2020-11-04 02:58:58摘要: 为了在不增加CPU 工作负担的前提下,实现标准键盘和矩阵键盘双键盘同时工作,提出了一种基于复杂可编逻辑器件(CPLD)的矩阵键盘扫描方案,实现了在矩阵键盘状态控制下CPLD 自动完成键盘扫描、编码、输出的... -
51单片机矩阵键盘扫描及使用方法
2022-03-29 23:53:09本文详细介绍了矩阵键盘的使用方法,都是干货窝一、矩阵键盘简介
矩阵键盘,也称矩阵按键,是为了节约单片机IO口占用所引入的一种外设。
(图片截取至普中A2开发板原理图)
(图片截取至普中A2开发板实物图)
我们知道,一个独立按键需要1个IO口。但是如果我们需要大量的按键,则需要大量的IO口,但是单片机现有的IO口并不能很好的满足,所以引入矩阵键盘。
二、矩阵键盘扫描原理
从独立按键到矩阵按键
1.独立按键回顾
上图的矩阵键盘共16个按键(4行×4列),先回到原来的一个独立按键分析。
首先分析独立按键的原理图连接方式(如上图),以按键K1为例,按键K1一端连接到单片机的P3.1口,另一端接地(GND)。当按键K1被按下时,GND直接就连到P3.1。所以当K1被按下时,P3.1口为低电平。我们只需要判断P3.1口是否为低电平,即可判断K1是否被按下。
2.矩阵按键扫描思路
先分析矩阵按键的IO连线,有以下特征:
- P17~P14这四个IO口连接了每一行矩阵键盘
- P13~P10这四个IO口连接了每一列矩阵键盘
矩阵键盘扫描共有两种扫描方式:
- 逐行扫描
- 逐列扫描
先分析逐行扫描,根据键盘被按下时,IO口为低电平这个特性。我们可以这样检测第一行:
- 给除第一行之外的其他行给高电平,防止其影响我们接下来的低电平检测
- 给第一行送低电平0
- 依次检测每一列的IO口电平(P13~P10),当出现低电平时,说明第一行的这一列的这个按键就被按下。
结合下图很好理解:
要检测第一行,给其他行赋值高电平。假设S2被按下了,那么P17的低电平会顺着绿色路线通到S2的另一端IO口(P12),只要检测出P12为低电平,那么就可以得出结论:K2被按下
按照这个思路,继续依次检测其他行即可。
总结:
按行扫描 给第1到第4行要扫描的行置0,其余行置1。然后对每一列进行读取,读出低电平的列则可以判断该行该列的按键被按下。
IO口电平(P17~P14:每行对应IO的口) 检测的行 若第K列IO口测出低电平 0 1 1 1 一 第一行第K列被按下 1 0 1 1
二 第二行第K列被按下 1 1 0 1 三 第三行第K列被按下 1 1 1 0 四 第四行第K列被按下 按列扫描的结果类似:
IO口电平(P13~P10:每行对应IO的口) 检测的列 若第K行IO口测出低电平 0 1 1 1 一 第K行第一列被按下 1 0 1 1
二 第K行第二列被按下 1 1 0 1 三 第K行第三列被按下 1 1 1 0 四 第K行第四列被按下 三、编程验证
1、先给出一些引脚定义
#include <REGX52.H> #define uchar unsigned char #define uint unsigned int #define led P0 //IO口位选 sbit wei1=P2^2; sbit wei2=P2^3; sbit wei3=P2^4; //定义行引脚 sbit hang1=P1^7; sbit hang2=P1^6; sbit hang3=P1^5; sbit hang4=P1^4; //定义列引脚 sbit lie1=P1^3; sbit lie2=P1^2; sbit lie3=P1^1; sbit lie4=P1^0;
2、按行扫描代码:
//扫描第一行的各列 P1|=0xff;//IO口全部初始化为高电平 hang1=0;//第一行设置为低电平 if(lie1==0)//检测第一列是否为低电平(按键是否被按下) { Delay10ms();//延时消抖 if(lie1==0) { while(lie1==0); key=1;//确认被按下,保存键值 } } //下面依次扫描第二、三和第四列,方法类似 if(lie2==0) { Delay10ms(); if(lie2==0) { while(lie2==0); key=2; } } if(lie3==0) { Delay10ms(); if(lie3==0) { while(lie3==0); key=3; } } if(lie4==0) { Delay10ms(); if(lie4==0) { while(lie4==0); key=4; } }
第二行,第三行、第四行扫描的方法类似
只需把 if 判断改成对应的行,键值改为对应的键值即可
3.总代码
#include <REGX52.H> #include <math.h> #define uchar unsigned char #define uint unsigned int #define led P0 sbit wei1=P2^2; sbit wei2=P2^3; sbit wei3=P2^4; sbit hang1=P1^7; sbit hang2=P1^6; sbit hang3=P1^5; sbit hang4=P1^4; sbit lie1=P1^3; sbit lie2=P1^2; sbit lie3=P1^1; sbit lie4=P1^0; void play(int a); void Delay10ms(); int scan(); uchar code smg[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d, 0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71,0x00}; int key=0; int x; void main() { while(1) { play(scan()); } } void play(int a) { x=a; wei1=0; wei2=0; wei3=0; led=smg[x]; Delay10ms(); } int scan() { P1|=0xff; hang1=0; if(lie1==0) { Delay10ms(); if(lie1==0) { while(lie1==0); key=1; } } if(lie2==0) { Delay10ms(); if(lie2==0) { while(lie2==0); key=2; } } if(lie3==0) { Delay10ms(); if(lie3==0) { while(lie3==0); key=3; } } if(lie4==0) { Delay10ms(); if(lie4==0) { while(lie4==0); key=4; } } P1|=0xff; hang2=0; if(lie1==0) { Delay10ms(); if(lie1==0) { while(lie1==0); key=5; } } if(lie2==0) { Delay10ms(); if(lie2==0) { while(lie2==0); key=6; } } if(lie3==0) { Delay10ms(); if(lie3==0) { while(lie3==0); key=7; } } if(lie4==0) { Delay10ms(); if(lie4==0) { while(lie4==0); key=8; } } P1|=0xff; hang3=0; if(lie1==0) { Delay10ms(); if(lie1==0) { while(lie1==0); key=9; } } if(lie2==0) { Delay10ms(); if(lie2==0) { while(lie2==0); key=10; } } if(lie3==0) { Delay10ms(); if(lie3==0) { while(lie3==0); key=11; } } if(lie4==0) { Delay10ms(); if(lie4==0) { while(lie4==0); key=12; } } P1|=0xff; hang4=0; if(lie1==0) { Delay10ms(); if(lie1==0) { while(lie1==0); key=13; } } if(lie2==0) { Delay10ms(); if(lie2==0) { while(lie2==0); key=14; } } if(lie3==0) { Delay10ms(); if(lie3==0) { while(lie3==0); key=15; } } if(lie4==0) { Delay10ms(); if(lie4==0) { while(lie4==0); key=0; } } return key; } void Delay10ms() //@11.0592MHz { unsigned char i, j; i = 18; j = 235; do { while (--j); } while (--i); }
四、课后作业(矩阵键盘计算器)
题目:请你利用矩阵按键和数码管来设计一个计算器,能够实现简单的四则整数运算和清零操作
-
4*4矩阵键盘扫描C语言程序
2014-04-14 18:37:47通过调试,用C语言编写的矩阵键盘扫描程序,简单易懂,实用 -
基于Verilog的低功耗矩阵键盘扫描设计
2018-08-12 17:01:57基于Verilog的低功耗矩阵键盘扫描设计,电路处于低功耗模式,在检测到有按键按下时,开始正常工作并扫描按键,判断是哪个按键被按下,得出键值后再次进入低功耗模式。 -
关于矩阵键盘行列扫描的测试实验
2021-03-23 11:44:54矩阵键盘无非就是两种扫描方式,一为逐行扫描,二为行列一起扫描读取键值。先确定行后确定列的读取方法没有什么可讲的,我针对行列一起扫描来总结一下我常用的一些方法。 学习嵌入式或者说硬件一定是从硬件... -
矩阵键盘扫描及LED数码显示综合实验
2012-10-31 11:03:49一、实验要求 利用4×4键盘和一个LED数码管构成简单的输入显示系统,实现键盘输入和LED数码显示相应键值的功能。 二、实验目的 ...理解矩阵键盘扫描的原理; 2.掌握矩阵键盘与51单片机接口的编程方法。 -
基于CPLD的矩阵键盘扫描模块设计
2021-04-16 19:46:15为了在不增加CPU工作负担的前提下,实现标准键盘和矩阵键盘双键盘同时工作,提出了一种基于复杂可编逻辑器件(CPLD)的矩阵键盘扫描方案,实现了在矩阵键盘状态控制下CPLD自动完成键盘扫描、编码、输出的功能,CPU... -
STM32 矩阵键盘扫描
2017-07-27 03:49:45可以 任意管脚 数据结构实现 只需添加管脚无需其他修改 即可返回按键值 -
矩阵键盘扫描例程.rar
2020-03-06 09:36:41资源是51单片机进行矩阵键盘读取的例程,包括两个例程,一个是采用查询方式进行矩阵键盘读取的例程,另一个是采用中断方式进行读取的例程。 -
4乘4矩阵键盘扫描加数码管显示代码
2015-08-05 20:35:314乘4矩阵键盘扫描加数码管显示代码 -
实战训练39 矩阵键盘扫描_FPGA矩阵键盘_thoughzuv_fpga_FPGA矩阵键盘_矩阵键盘_
2021-10-02 16:14:50矩阵键盘扫描 -
矩阵键盘扫描方法
2021-05-08 18:57:53单片机行列式键盘扫描原理如下: 1、行线P10~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时...一、行列扫描法 (单片机为例)
单片机行列式键盘扫描原理如下:
1、行线P10~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P10~P13)全部输出低电平,列线通电阻上拉到VCC,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时程序以此来去除按键抖动。
2、延时完成后再判断是否有低电平,如果此时读入列线数据还是有低电平,则说明确实有键按下。最后一步确定键值。当判断确实有键按下之后,行线轮流输出低电平,根据读入列线的数据可以确定键值。
3、单片机将P10输出为低电平,其它P11~P13输出高电平,此时读取列线的数据全为高电平,说明没有在第一行有键按下;其次,单片机将P11输出低电平,其它P10、P12、P13仍为高电平。
4、此时再来读取列线数据,发现列线读到的数据有低电平,数值为1011(0x0B),如果我们的键盘布局已经确定,那么0x0B就代表S5的值了。转到S5键功能处理子程序就可以达到目的。
二、行列反转法(单片机为例)
这里我们规定 P1.0~P1.3为列,P1.7~P1.4 为行
第一步: 行线IO P1.7~P1.4置低电平,列线IO P1.0~P1.3置高电平 ,假设K1按下,那么P1.0=0 读P1口 P1=00001110
第二步: 行线IO P1.7~P1.4置高电平,列线IO P1.0~P1.3置低电平假设K1按下,那么P1.7=0 读P1口 P1=01110000
第三步 : 两个字节相加,得到新数据:01111110(第一行 第一列)每按一个键我们都得到不同的字节,比对我们的字节是什么就可以知道键值是什么了。
-
单片机矩阵键盘扫描的两种方式
2020-08-20 01:20:26文章主要介绍了单片机矩阵键盘扫描的两种方式 -
51单片机4x4矩阵键盘扫描+数码管显示
2021-08-30 13:12:2751单片机4x4矩阵键盘扫描+数码管显示 材料:AT89C52、2位数码管、74HC595、 Proteus仿真 实例代码 #include<reg52.h> #include "intrins.h" sbit ST=P2^0;//定义74HC595移位寄存器 sbit SH=P2^2; sbit DS=...51单片机4x4矩阵键盘扫描+数码管显示
个位闪烁感在这篇文章已经修复《51单片机4x4矩阵键盘扫描+数码管显示(二)(修bug篇)》
- 材料:
AT89C52
、2位数码管
、74HC595
、 - Proteus仿真
实例代码(先行后列扫描法)
#include<reg52.h> #include "
- 材料: