独立按键与矩阵键盘
键盘扫描程序实验报告

一、实验目的1. 理解键盘扫描的基本原理。
2. 掌握使用C语言进行键盘扫描程序设计。
3. 学习键盘矩阵扫描的编程方法。
4. 提高单片机应用系统的编程能力。
二、实验原理键盘扫描是指通过检测键盘矩阵的行列状态,判断按键是否被按下,并获取按键的值。
常见的键盘扫描方法有独立键盘扫描和矩阵键盘扫描。
独立键盘扫描是将每个按键连接到单片机的独立引脚上,通过读取引脚状态来判断按键是否被按下。
矩阵键盘扫描是将多个按键排列成矩阵形式,通过扫描行列线来判断按键是否被按下。
这种方法可以大大减少引脚数量,降低成本。
本实验采用矩阵键盘扫描方法,使用单片机的并行口进行行列扫描。
三、实验设备1. 单片机开发板(如51单片机开发板)2. 键盘(4x4矩阵键盘)3. 连接线4. 调试软件(如Keil)四、实验步骤1. 连接键盘和单片机:将键盘的行列线分别连接到单片机的并行口引脚上。
2. 编写键盘扫描程序:(1)初始化并行口:将并行口设置为输入模式。
(2)编写行列扫描函数:逐行扫描行列线,判断按键是否被按下。
(3)获取按键值:根据行列状态,确定按键值。
(4)主函数:调用行列扫描函数,读取按键值,并根据按键值执行相应的操作。
3. 调试程序:将程序下载到单片机,观察键盘扫描效果。
五、实验程序```c#include <reg51.h>#define ROW P2#define COL P3void delay(unsigned int ms) {unsigned int i, j;for (i = 0; i < ms; i++)for (j = 0; j < 123; j++);}void scan_key() {unsigned char key_val = 0xFF;ROW = 0xFF; // 初始化行delay(1); // 延时消抖key_val = ROW & COL; // 获取按键值ROW = 0x00; // 初始化行delay(1); // 延时消抖key_val = ROW & COL; // 获取按键值ROW = 0x00; // 初始化行delay(1); // 延时消抖key_val = ROW & COL; // 获取按键值ROW = 0x00; // 初始化行delay(1); // 延时消抖key_val = ROW & COL; // 获取按键值}void main() {while (1) {scan_key();if (key_val != 0xFF) {// 执行按键对应的操作}}}```六、实验结果与分析1. 实验结果:程序下载到单片机后,按键按下时,单片机能够正确读取按键值。
矩阵键盘的原理及应用

矩阵键盘的原理及应用1. 矩阵键盘的原理矩阵键盘是一种常见的输入设备,由多个按键组成,可以同时检测多个按键的状态。
它采用了行列交叉的按键排列方式,通过按键的组合来实现多个输入选项。
其原理主要包括以下几个方面:1.1. 电路结构矩阵键盘的电路结构也称为“行列式键盘”,主要由行线(Row)和列线(Column)组成。
行线和列线通过导线互相交叉连接形成一个矩阵,每个按键都对应矩阵中的一个交叉点。
按键按下时,会导通对应的行线和列线,从而实现按键的状态检测。
1.2. 矩阵扫描矩阵键盘的工作原理是通过矩阵扫描来检测按键状态。
扫描过程由控制器完成,控制器通过逐行扫描的方式检测按键状态。
具体流程如下:1.所有行线置为高电平,所有列线设置为输入模式。
2.逐行将某一行设置为低电平,同时读取列线上的状态。
3.根据读取到的列线状态,确定按下的按键。
4.更新按键的状态,并记录下来。
5.重复以上步骤,直到扫描结束。
1.3. 按键编码矩阵键盘检测到按键状态后,需要进行按键编码,将按键状态转化为数字或字符。
常见的按键编码方式有两种:•行列编码:将矩阵键盘的行和列对应关系转化为一个唯一的值,通常使用二进制编码来表示。
•状态编码:通过按键的状态(按下或释放)来表示,通常使用两个状态位来编码。
2. 矩阵键盘的应用矩阵键盘由于其结构简单、使用方便等特点,在多个领域都得到了广泛的应用。
以下是矩阵键盘的一些常见应用场景:2.1. 电子产品矩阵键盘在电子产品中被广泛应用,比如手机、电视遥控器、计算器等。
它可以提供多个输入选项,方便用户进行操作。
矩阵键盘的结构紧凑,可与其他电路板集成,节省空间,适用于小型电子产品。
2.2. 工业控制矩阵键盘在工业控制领域也有重要应用。
比如工控终端设备、仪表仪器等,可以利用矩阵键盘实现数据输入和操作控制。
由于矩阵键盘可以同时检测多个按键的状态,因此非常适合于工业环境中需要同时输入多个信号的场合。
2.3. 家用电器矩阵键盘在家用电器中也有广泛应用,如洗衣机、微波炉、冰箱等。
独立按键

软件消抖
if(k1==0) //检测按键K1是否按下 { delay(1000); //消除抖动 一般大约10ms if(k1==0) //再次判断按键是否按下 { 语句; }
软件编程
下载程序后按下K1按键可以对D1小灯状态取反。 #include "reg52.h" typedef unsigned int u16; typedef unsigned char u8; sbit k1=P3^1; //定义P31口是k1 sbit led=P2^0; //定义P20口是led void delay(u16 i) { while(i--); }
按键处理函数 void keypros() { if(k1==0) //检测按键K1是否按下 { delay(1000); //消除抖动 一般大约10ms if(k1==0) //再次判断按键是否按下 { led=~led; //led状态取反 } while(!k1); //检测按键是否松开 } }
独立按键原理
(2)矩阵按键
为了减少I/O口的占用,通常将按键排列成矩阵 形式,即每条水平和垂直直线在交叉处不直接连通, 而是通过一个按键加以连接。
2. 独立按键原理
按键在闭合和断开时,触点会存在抖动现象。由 于机械触点的弹性作用,一个按键在闭合时不会马上 稳定地接通,断开时不会立即断开。
为了避免这种现象而做的措施就是按键消抖。消抖方法 分为:硬件消抖、软件消抖。
独立按键实验
1.按键介绍
2.独立按键原理 3.编写独立按键控制程序
工程图示按键
键盘的分类
键盘分为编码键盘和非编码键盘。键盘上闭合键的识别由专用源自硬件编码器实现,如计算机键盘。靠软件编
程来识别称为非编码键盘。单片机组成的各系统中,用
最新独立按键及矩阵键盘控制LED灯

P10 P11 P12 P13 P14 P15 P16 P17
1 2 3 4 5 6 7 8 13 12 15 14 31 19 18 9 17 16
U1
P10 P11 P12 P13 P14 P15 P16 P17 INT1 INT0 P00 P01 P02 P03 P04 P05 P06 P07 P20 P21 P22 P23 P24 P25 P26 P27 VCC GND RXD TXD ALE/P PSEN
Q & +5V & Q
图3.6 硬件去抖动电路
(2)软件消抖法:键按下的时间与操作者的按 键动作有关,约为十分之几到几秒不等。而键抖动 时间与按键的机械特性有关,一般为5~10ms不等。 软件消抖法即是采用延时(一般延时10~20ms) 的方法,以避开按键的抖动,即在按键已稳定地闭 合或断开时才读出其状态。
图3.2 矩阵式键盘接口
特点:电路连接复杂,但提 高了I/O口利用率,软件编程 较复杂。适用于需使用大量 按键的场合。
独立式按键的软件结构
独立式按键软件常采用查询式结构。 先逐位查询每根I/O口线的输入状态,如某 一根I/O口线输入为低电平,则可确认该 I/O口线所对应的按键已按下,然后,再转 向该键的功能处理程序。
bb
F
7b 77
d7
b7
键盘控制流程 单片机对矩阵式 键盘接口处理的一 般过程如图所示。
N
等待键释放
开始 键扫描 有键按下? Y 消除抖动 键扫描 确有键按下? Y 求键值 键释放? Y 按键处理 返回 N 求键码 等待释放 按键处理 N 键扫描
消抖
图3.4 键盘处理流程框图
1. 键扫描 键扫描就是要判断有无键按下,当扫描到有键
[单片机矩阵键盘实验实验报告范文]矩阵键盘实验心得
![[单片机矩阵键盘实验实验报告范文]矩阵键盘实验心得](https://img.taocdn.com/s3/m/f25e771e4531b90d6c85ec3a87c24028915f8505.png)
[单片机矩阵键盘实验实验报告范文]矩阵键盘实验心得实验五矩阵键盘实验一、实验内容1、编写程序,做到在键盘上每按一个数字键(0-F)用发光二极管将该代码显示出来。
按其它键退出。
2、加法设计计算器,实验板上有12个按键,编写程序,实现一位整数加法运算功能。
可定义“A”键为“+”键,“B”键为“=”键。
二、实验目的学习独立式按键的查询识别方法。
2、非编码矩阵键盘的行反转法识别方法。
三、实验说明1、MCS51系列单片机的P0~P3口作为输入端口使用时必须先向端口写入“1”。
2、用查询方式检测按键时,要加入延时(通常采用软件延时10~20mS)以消除抖动。
3、识别键的闭合,通常采用行扫描法和行反转法。
行扫描法是使键盘上某一行线为低电平,而其余行接高电平,然后读取列值,如读列值中某位为低电平,表明有键按下,否则扫描下一行,直到扫完所有行。
行反转法识别闭合键时,要将行线接一并行口,先让它工作在输出方式,将列线也接到一个并行口,先让它工作于输入方式,程序使CPU通过输出端口在各行线上全部送低电平,然后读入列线值,如此时有某键被按下,则必定会使某一列线值为0。
然后,程序对两个并行端口进行方式设置,使行线工作于输入方式,列线工作于输出方式,并将刚才读得的列线值从列线所接的并行端口输出,再读取行线上输入值,那么,在闭合键所在行线上的值必定为0。
这样,当一个键被接下时,必定可以读得一对唯一的行线值和列线值。
由于51单片机的并口能够动态地改变输入输出方式,因此,矩阵键盘采用行反转法识别最为简便。
行反转法识别按键的过程是:首先,将4个行线作为输出,将其全部置0,4个列线作为输入,将其全部置1,也就是向P1口写入0某F0;假如此时没有人按键,从P1口读出的值应仍为0某F0;假如此时1、4、7、0四个键中有一个键被按下,则P1.6被拉低,从P1口读出的值为0某B0;为了确定是这四个键中哪一个被按下,可将刚才从P1口读出的数的低四位置1后再写入P1口,即将0某BF写入P1口,使P1.6为低,其余均为高,若此时被按下的键是“4”,则P1.1被拉低,从P1口读出的值为0某BE;这样,当只有一个键被按下时,每一个键只有唯一的反转码,事先为12个键的反转码建一个表,通过查表就可知道是哪个键被按下了。
独立式键盘的设计与应用实验报告

独立式键盘的设计与应用实验报告实验报告:指导教师:xxx实验者:13410801 xx 13410802 xxx一、实验目的:1.了解直接输入键盘与矩阵键盘的原理。
2.了解键盘寄存器的功能。
3.掌握键盘输入的编程方法。
二、实验要求:1.对所有16个按键进行编码,当按键后,在七段数码管上显示对应的键盘编码(可以使用一个或两个七段数码管)。
2.对所有16个按键进行编码,当按键后,在八个LED上显示对应的键盘编码。
三、实验内容:1.在键盘寄存器KPC中,使能矩阵键盘。
2.必须在使用前添加下面语句:#define KAPS_VALUE (*((volatile unsigned char*)(0x41500020)))3.接下来在button_statusFetch函数中定义变量,其中j用来获取矩阵键盘的键值,具体如下:char j = 0;j = KAPS_VALUE ;4.最后,在直入键盘的分支语句后添加矩阵键盘的分支代码段,即switch(j){}代码段:switch (j){case 0x00: //key-press 5kbd_buff=0x8F12;LED_CS2 = kbd_buff;Delay(400);break;……四、程序编辑:;post_initGpio.sEXPORT post_initGpioAREA post_initGpio ,CODE ,READONLYldr r1,=0x40e00000;GPSR0MOV R0,#0x3000 ;GPIO<13:12>STR R0,[R1,#0x18];GPCR0MOV R0,#0x800 ;GPIO<11>STR R0,[R1,#0x24];GAFR0_L/////////////////////////////////////////////// /// MOV R0,#0x80000000 ;GPIO<15>:F2:nCS1 STR R0,[R1,#0x54];GAFR0_Uldr R0,=0x10 ;0xa5000010STR R0,[R1,#0x58];GPDR0///////////////////////////////////////////////// ldr R0,=0xc1a08000 ;GPIO<15>:nCS1 STR R0,[R1,#0xc];GPSR1MOV R0,#0STR R0,[R1,#0x1c];GPCR1MOV R0,#0STR R0,[R1,#0x28];GAFR1_LLDR R0,=0xc9c ;0xa9558STR R0,[R1,#0x5c];GAFR1_ULDR R0,=0xca0 ;0xaaa590aaSTR R0,[R1,#0x60]LDR R0,=0xca4 ;0xfccf0382STR R0,[R1,#0x10];GPSR2MOV R0,#0x10000STR R0,[R1,#0x20];GPCR2MOV R0,#0STR R0,[R1,#0x2c];GAFR2_L////////////////////////////////////ldrR0,=0xa0000000 ;0xaaaaaaaa ;GPIO<79:78>:nCS<3:2> STR R0,[R1,#0x64];GAFR2_U/////////////////////////////////////////ldr R0,=0x50000400;0x50090402 ;GPIO<95:94,80>:KP_DKIN<1>,KP_DKIN<2>,nCS4 STR R0,[R1,#0x68];GPDR2///////////////////////////////////////////ldr R0,=0x0221ffff ;GPIO<80:78>:nCS<4:2>STR R0,[R1,#0x14]; LDR R0,=0xca8; STR R0,[R1,#0x68]MOV R0,#0x20000STR R0,[R1,#0x118];GPCR3MOV R0,#0STR R0,[R1,#0x124];GAFR3_L////////////////////////////////////////////// ldr R0,=0x020a95c3 ;GPIO<108,105:98>STR R0,[R1,#0x6c];GAFR3_Uldr R0,=0x1408STR R0,[R1,#0x70];GPDR3///////////////////////////////////////////////// / ldr R0,=0x21381;GPIO<108,105:103>STR R0,[R1,#0x10c];config twice:;GAFR0_Uldr R0,=0xa5000010 ;0x0x10STR R0,[R1,#0x58];GAFR1_LLDR R0,=0xa9558 ;0xc9cSTR R0,[R1,#0x5c]LDR R0,=0xaaa590aa ;0xca0STR R0,[R1,#0x60];GPDR1LDR R0,=0xfccf0382 ;0xca4STR R0,[R1,#0x10];GAFR2_L/////////////////////////////////////////////// ////ldr R0,=0xa0000000 ;GPIO<79:78>:nCS<3:2>STR R0,[R1,#0x64];GAFR2_U/////////////////////////////////////////////// //////////////// ////////ldr R0,=0x50090402;GPIO<95:94,80>:KP_DKIN<1>,KP_DKIN<2>,nCS4STR R0,[R1,#0x68]mov pc,r14END;post_initKey.sEXPORT post_initKeyAREA post_initKey, CODE, READONLYnopnopldr r1,=0x41500000;KPCldr r0,=0x3FAFF1C2 ; (0x2FAFF9C3:interrupt) str r0,[r1,#0x0];KPDK; ldr r0,=0x1; str r0,[r1,#0x8]; ;KPREC; ldr r0,=0x1; str r0,[r1,#0x10];KPMK; ldr r0,=0x1; str r0,[r1,#0x18];KPAS; ldr r0,=0x1; str r0,[r1,#0x20]; ldr r0,=0x1; str r0,[r1,#0x0];KPKDIldr r0,=0x707str r0,[r1,#0x48]mov pc,r14END五、实验结果:当按下键盘上的按键时,七段数码管可以显示出对应的编码。
实验5-独立键盘和矩阵键盘

实验5 独立键盘和矩阵键盘一、实验目的1、学会用C语言进行独立按键应用程序的设计。
2、学会用C语言进行矩阵按键应用程序的设计。
二、实验内容1、独立按键:对四个独立按键编写程序:当按k1时,8个LED同时100ms闪烁;当按k2时,8个LED从左到右流水灯显示;当按k3时,8个LED从右到左流水灯显示;当按k4时,8各LED同时从两侧向中间逐步点亮,之后再从中间向两侧逐渐熄灭;2、矩阵按键:采用键盘扫描方式,顺序按下矩阵键盘后,在一个数码管上顺序显示0~F,采用静态显示即可。
3、提高部分(独立按键、定时器、数码管动态扫描):编写程序,实现下面的功能。
用数码管的两位显示一个十进制数,变化范围为00~59,开始时显示00,每按一次k1,数值加1;每按一次k2,数值减1;每按一次k3,数值归零;按下k4,利用定时器功能使数值开始自动每秒加1;再按一次k4,数值停止自动加1,保持显示原数。
三、实验步骤1、硬件连接(1)使用MicroUSB数据线,将实验开发板与微型计算机连接起来;(2)在实验开发板上,用数据线将相应接口连接起来;2、程序烧入软件的使用使用普中ISP软件将HEX文件下载至单片机芯片内。
查看结果是否正确。
四、实验结果——源代码1. #include "reg52.h"typedef unsigned char u8;typedef unsigned int u16;#define LED P2sbit key1=P3^1;sbit key2=P3^0;sbit key3=P3^2;sbit key4=P3^3;const char tab[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f}; u8 code begMid[]={0x7e, 0xbd,0xdb,0xe7, 0xdb, 0xbd, 0x7e}; void Delay(u16 i){ while(i--);}void KeyDown(){u8 i;if(key2==0){Delay(1000);if(key2==0){for(i=0;i<8;i++){LED=tab[i];Delay(50000);}while(!key2);}LED=0xff;}else if(key1==0){Delay(1000);if(key1==0)for(i=0;i<3;i++){LED=0x00;Delay(10000);LED=0xff;Delay(10000);}}}}void Int0Init(){IT0=1;EX0=1;EA=1;}void Int1Init(){IT1=1;EX1=1;EA=1;} void main(){Int0Init();Int1Init();while(1){KeyDown();}}void Int0() interrupt 0{u8 i;if(key3==0){Delay(1000);if(key3==0)for(i=7;i>=0;i--){LED=tab[i];Delay(50000);}}}}void Int1() interrupt 2{u8 i;if(key4==0){Delay(1000);if(key4==0){for(i=0;i<=6;i++){LED=begMid[i];Delay(50000);}}}}2.#include "reg52.h"typedef unsigned int u16;typedef unsigned char u8;#define GPIO_DIG P0#define GPIO_KEY P1sbit LSA=P2^2;sbit LSB=P2^3;sbit LSC=P2^4;u8 KeyValue;u8 code smgduan[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//??0~F?? void delay(u16 i){while(i--);}void KeyDown(void){char a=0;GPIO_KEY=0x0f;if(GPIO_KEY!=0x0f){delay(1000);if(GPIO_KEY!=0x0f){GPIO_KEY=0X0F;switch(GPIO_KEY){case(0X07): KeyValue=0;break;case(0X0b): KeyValue=1;break;case(0X0d): KeyValue=2;break;case(0X0e): KeyValue=3;break;}GPIO_KEY=0XF0;switch(GPIO_KEY){case(0X70): KeyValue=KeyValue;break;case(0Xb0): KeyValue=KeyValue+4;break;case(0Xd0): KeyValue=KeyValue+8;break;case(0Xe0): KeyValue=KeyValue+12;break;}while((a<50)&&(GPIO_KEY!=0xf0)){delay(1000);a++;}}}}void main(){LSA=0;LSB=0;LSC=0;while(1){KeyDown();GPIO_DIG=smgduan[KeyValue];}}3.#include <reg52.h>typedef unsigned int u16;typedef unsigned char u8;#define KEYPORT P3sbit LSA=P2^2;sbit LSB=P2^3;sbit LSC=P2^4;sbit key1=P3^1;sbit key2=P3^0;sbit key3=P3^2;sbit key4=P3^3;u16 t;u8 sec;u8 DisplayData[2];u8 code smgduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; void Time1Init(){TMOD |= 0x10;TH1=0Xd8;TL1=0Xf0;EA=1;ET1=1;}void delay(u16 i){while(i--); }void DigDisplay(){u8 i;for(i=0;i<2;i++){switch(i){case 0:LSA=0;LSB=0;LSC=0;break;case 1:LSA=1;LSB=0;LSC=0;break;}P0=DisplayData[i];delay(100);P0=0x00;}}void datapros(){DisplayData[0]=smgduan[sec%10];DisplayData[1]=smgduan[sec/10];}void main(){Time1Init();while(1){if(key4==0){delay(1000);if(key4==0){TR1=!TR1;while(key4==0);}}if(key3==0){delay(1000);if(key3==0){sec=0;while(key3==0);}}if(key2==0){delay(1000);if(key2==0){sec--;while(key2==0);}}if(key1==0){delay(1000);if(key1==0){sec++;while(key1==0);}}}}void Time1() interrupt 2{TH1=0Xd8;TL1=0Xf0;t++;if(t==100){t=0;sec++;if(sec>=60){sec=0;}}datapros();DigDisplay();}五、实验体会——结果分析1、独立按键:位定义四个按键key1、key2、key3、key4,宏定义LED为P2口,tab数组保存流水灯D0-D7依次点亮的数值,begMid数组保存流水灯同时从两侧向中间逐步点亮,之后再从中间向两侧逐渐熄灭的赋值方式。
独立按键及矩阵键盘控制LED灯课件

通过动态刷新LED灯的状态,实现LED灯的闪烁、流水灯等效果,提高 系统的交互性和用户体验。
03
队列缓冲技术
将按键输入和LED灯输出分别放在不同的队列中处理,通过队列缓冲技
术实现程序的非阻塞性处理,提高系统的响应速度和处理效率。
实战项目:独立
05 按键及矩阵键盘 控制LED灯的综
合应用
行消抖处理。
硬件去抖
通过在按键与处理芯片之间增加 一个RC滤波电路,利用RC的充 放电过程来过滤按键电平抖动, 从而消除按键抖动对读取按键状
态的影响。
软件去抖
通过编写一段软件延时程序,在 检测按键状态时延时一段时间后 再进行检测,从而避免按键抖动
对读取按键状态的影响。
复杂矩阵键盘控制
1 2
扫描法
通过逐行逐列扫描键盘矩阵,依次识别每个按键 的行列坐标,从而判断出按下的按键位置。
连接电路
矩阵键盘的行线和列线分 别与树莓派的GPIO引脚相 连,形成矩阵结构。
电源和地线
需要连接电源和地线,以 给矩阵键盘提供工作电压 。
编程实现
01
02
03
04
安装库
需要安装相应的Python库, 如RPi.GPIO和MFRC522。
初始化
初始化树莓派的GPIO引脚和 MFRC522模块。
扫描按键
二极管和晶体管
介绍这两种重要的电子元件及其在 电路中的应用。
编程基础
01
02
03
编程语言
介绍适用于独立按键和矩 阵键盘控制的编程语言, 如C语言或Python。
程序结构
详细解释程序的各个部分 ,如变量、函数、循环等 。
条件语句
介绍条件语句及其在编程 中的应用。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
+5V
图8.1 独立式键盘接口
特点:每个按键占用一条I/O 线,当按键数量较多时,I/O 口利用率不高,但程序编制简 单。适用于所需按键较少的场 合。
图8.2 矩阵式键盘接口
特点:电路连接复杂,但提 高了I/O口利用率,软件编程 较复杂。适用于需使用大量 按键的场合。
U1
P10 1 P11 2 P12 3 P13 4 P14 5 P15 6 P16 7 P17 8
后沿 抖动
图8.5 键闭合及断开时的抖动
为确保每按一次键单片机只进行一次处理,使 键盘可靠地工作,必须消除按键抖动。消抖方法有 硬件消抖和软件延时两种。
(1)硬件消抖ห้องสมุดไป่ตู้:就是在键盘中附加去抖动电
路,从根上消除抖动产生的可能性。右图所示电路
实际上是由R-S触发器构成的单脉冲电路。当按钮
开关按下时Q端输出低电平,当开关松开时Q端恢
+5V
101 110 110 01
行线输出 列线输入
0111 1011 1101 1110
1111 1110 1111 1111
(2)线反转法。 线反转法也是识别闭合键的一种常用方法, 该法 比行扫描速度快, 但在硬件上要求行线与列线外接 上拉电阻。 先将行线作为输出线, 列线作为输入线, 行线输出 全“0”信号, 读入列线的值, 那么在闭合键所在的列 线上的值必为0;然后从列线输出全“0”信号,再 读取行线的输入值,闭合键所在的行线值必为 0。 这样,当一个键被按下时, 必定可读到一对唯一的行 列值。再由这一对行列值可以求出闭合键所在的位 置。
复高电平,即输出一个负脉冲,以此消除抖动。
Q
Q
&
&
+5V
图8.6 硬件去抖动电路
(2)软件消抖法:键按下的时间与操作者的按 键动作有关,约为十分之几到几秒不等。而键抖动 时间与按键的机械特性有关,一般为5~10ms不等。 软件消抖法即是采用延时(一般延时10~20ms) 的方法,以避开按键的抖动,即在按键已稳定地闭 合或断开时才读出其状态。
…… else if (表达式n-1) (语句n-1;) else {语句n}
【例】 if语句的用法。 (1)if (x!=y) printf(“x=%d,y=%d\n”,x,y); 执行上面语句时,如果x不等于y,则输出x的值和y的值。 (2)if (x>y) max=x;
else max=y; 执行上面语句时,如x大于y成立,则把x送给最大值变
(3)每一个case常量表达式的值必须不同否则会出现自相 矛盾的现象。
(4)case语句和default语句的出现次序对执行过程没有影 响。
(5)每个case语句后面可以有“break”,也可以没有。有 break语句,执行到break则退出switch结构,若没有,则会 顺次执行后面的语句,直到遇到break或结束。
A K11 E K15
B F
P17 P16 P15 P14
扫描法 和线反转法
+5V
89s52
P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 P1.7
图8.2 矩阵式键盘接口
0
1
2
3
ee
de
be
7e
4
5
6
7
ed dd bd 7d
8
9
A
B
eb db bb 7b
量max,如x大于y不成立,则把y送给最大值变量max。使 max变量得到x、y中的大数。
(3)if (score>=90) printf(“Your result is an A\n”);
else if (score>=80) printf(“Your result is an B\n”);
else if (score>=70) printf(“Your result is an C\n”);
100m s
10m
10m
s 键抖动时间 s
图8.7 软件消抖法延时区间示意图
3. 计算键码
键码是每个按键的标识。被按键确定下来之后, 接下来的工作是计算闭合键的键码,然后才能根据键 码进行对应的操作。
为编程方便,键码通常都是以键的排列顺序安 排,按照从左到右、从上向下的顺序编排。键码可 根据行号列号以查表求得,也可通过计算得到。我 们将结合实例加以介绍。
switch (表达式) {case 常量表达式1:{语句1;}break; case 常量表达式2:{语句2;}break; …… case 常量表达式n:{语句n;}break; default:{语句n+1;}
说明如下:
(1)switch后面括号内的表达式,可以是整型或字符型表 达式。
(2)当该表达式的值与某一“case”后面的常量表达式的 值相等时,就执行该“case”后面的语句,然后遇到break语 句退出switch语句。若表达式的值与所有case后的常量表达 式的值都不相同,则执行default后面的语句,然后退出 switch结构。
TT0189S52
EA/VP
P20 P21 P22 P23 P24 P25 P26 P27
21 22 23 24 25 26 27 28
X1 X2
RESET
RD WR
VCC GND RXD TXD ALE/P PSEN
40 20 10 11 30 29
P12K8 P13K12
8 K9 C K13
9 K10 D K14
键盘接口
键盘是单片机应用系统中使用最广泛的一种 数据输入设备。键盘是一组按键的组合。键通常 是一种常开型按钮开关,常态下键的两个触点处 于断开状态,按下键时它们才闭合(短路)。
通常,键盘有编码和非编码两种。编码键盘通 过硬件电路产生被按按键的键码和一个选通脉冲。 选通脉冲可作为CPU的中断请求信号。这种键盘使 用方便,所需程序简单,但硬件电路复杂,常不被 单片机采用。
…… else if (表达式n-1) (语句n-1;) else {语句n}
【例】 if语句的用法。 (1)if (x!=y) printf(“x=%d,y=%d\n”,x,y); 执行上面语句时,如果x不等于y,则输出x的值和y的值。 (2)if (x>y) max=x;
else max=y; 执行上面语句时,如x大于y成立,则把x送给最大值变
else if (score>=60) printf(“Your result is an D\n”);
else printf(“Your result is an E\n”); 执行上面语句后,能够根据分数score分别打出A、B、
C、D、E五个等级。
switch/case语句
if语句通过嵌套可以实现多分支结构,但结构复杂。 switch是C51中提供的专门处理多分支结构的多分支 选择语句。它的格式如下:
89C51 P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 P1.7
设第2行第 4列键按下
10 10 10 0
+5V 行值:1011
10 0 10 10
列值:1110
2.消抖 由于按键按下时的机械动作,在按键被按下或松 开的瞬间,其输出电压会产生波动,称为键的抖动。
键按下
前沿 抖动
5.1.2 键盘接口和键输入软件中应解决的几个问题
1.消除键抖动
键按下
键稳定
前沿抖动
后沿抖动
图5.2 键合断时的电压抖动
if语句 if语句是C51中的一个基本条件选择语句,它通常 有三种格式: (1)if (表达式) {语句;} (2)if (表达式) {语句1;} else {语句2;} (3)if (表达式1) {语句1;} else if (表达式2) (语句2;) else if (表达式3) (语句3;)
}
键盘控制流程
单片机对矩阵式 键盘接口处理的一 般过程如图8.3所示。
N
等待键释放
开始 键扫描
有键按下? Y
消除抖动
键扫描
确有键按下? Y
求键值
键释放? Y
按键处理
键扫描 N
消抖 N
求键码 等待释放 按键处理
返回
图8.3 键盘处理流程框图
1. 键扫描 键扫描就是要判断有无键按下,当扫描到有键
按下时再进行下一步处理,否则退出键盘处理程序。 独立式键盘扫描只需读取IO口状态,而矩阵式键盘 描通常有两种实现方法:逐行扫描法和线反转法。
switch (表达式) {case 常量表达式1:{语句1;}break; case 常量表达式2:{语句2;}break; …… case 常量表达式n:{语句n;}break; default:{语句n+1;}
(1) 逐行扫描法。依次从第一至最末行线上发出 低电平信号, 如果该行线所连接的键没有按下的 话, 则列线所接的端口得到的是全“1”信号, 如果 有键按下的话, 则得到非全“1”信号。
设第2行第 4列键按下
89C51 P1.0 P1.1 P1.2 P1.3 P1.4 11 11 11 1011 P1.5 P1.6 P1.7
非编码键盘按组成结构又可分为独立式键盘和 矩阵式键盘。独立式键盘的工作过程与矩阵式键盘 类似,无论是硬件结构还是软件设计都比较简单,。
P1.4 P1.5 P1.6 P1.7
89S52
+5V
S1 S2 S3 S4
89s52
P1.0 P1.1 P1.2 P1.3 P1.4 P1.5 P1.6 P1.7
4.等待释放
等待释放是为了保证键的一次闭合仅进行一次处 理。求得键码后,然后通过不断进行键扫描,如有键 按下,则继续扫描,否则认为键已释放。