矩阵键盘参考程序

合集下载

矩阵键盘程序设计

矩阵键盘程序设计

矩阵键盘程序设计矩阵键盘程序设计1.引言2.矩阵键盘的工作原理矩阵键盘由多行多列的按键组成,每个按键都与行线和列线相交。

当按下某一个按键时,行线和列线会形成一个闭合电路,通过这个闭合电路来传递按键的信号。

通过扫描行线和列线的状态,可以确定用户按下了哪个按键。

3.矩阵键盘的程序设计在程序设计中,需要初始化矩阵键盘的引脚配置,即将每个行线和列线连接到相应的引脚上。

然后,通过循环扫描行线和列线的状态,判断用户是否按下了某个按键。

一般情况下,矩阵键盘的扫描速度比较快,可以采用中断的方式来进行扫描,提高响应速度。

以下是一个简单的矩阵键盘程序设计示例:import RPi.GPIO as GPIO初始化引脚配置row_pins = [11, 13, 15, 16] 行引脚col_pins = [18, 22, 24, 26] 列引脚GPIO.setmode(GPIO.BOARD)设置行引脚为输出模式,列引脚为输入模式for pin in row_pins:GPIO.setup(pin, GPIO.OUT)for pin in col_pins:GPIO.setup(pin, GPIO.IN)循环扫描矩阵键盘while True:for row in row_pins:设置当前行引脚为低电平GPIO.output(row, GPIO.LOW)for col in col_pins:判断当前列引脚是否为高电平,即判断用户是否按下了某个按键if GPIO.input(col) == GPIO.HIGH:处理按键事件print(\。

4X4矩阵式键盘输入程序

4X4矩阵式键盘输入程序

4*4键盘程序readkeyboard:begin: acall key_onjnz delayajmp readkeyboarddelay:acall delay10msacall key_onjnz key_numajmp beginkey_num:acall key_panl a,#0FFhjz beginacall key_ccodepush akey_off:acall key_onjnz key_offpop aretkey_on: mov a,#00horl a,#0fhmov p1,amov a,p1orl a,#0f0hcpl aretkey_p: mov r7,#0efhl_loop:mov a,r7mov p1,amov a,p1orl a,#0f0hmov r6,acpl ajz nextajmp key_cnext: mov a,r7jnb acc.7,errorrl amov r7,aajmp l_looperror:mov a,#00hretkey_c:mov r2,#00hmov r3,#00hmov a,r6mov r5,#04hagain1:jnb acc.0,out1rr ainc r2djnz r5, again1out1: inc r2mov a,r7mov r5,#04hagain2:jnb acc.4,out2rr ainc r3djnz r5,again2out2: inc r3mov a, r2swap aadd a,r3retkey_ccode:push aswap aanl a,#0fhdec arl a ;行号乘4rl amov r7,apop aanl a,#0fhdec aadd a,r7retdelay10ms:anl tmod,#0f0horl tmod,#01hmov th0,#0d8hmov tl0,#0f0hsetb tr0wait:jbc tf0,overajmp waitclr tr0over:ret单片机键盘设计(二)从电路或软件的角度应解决的问题软件消抖:如果按键较多,硬件消抖将无法胜任,常采用软件消抖。

矩阵键盘程序设计精简版

矩阵键盘程序设计精简版

矩阵键盘程序设计矩阵键盘程序设计引言矩阵键盘的工作原理矩阵键盘由多行和多列组成,每个按键位于特定的行和列交叉点上。

在未按下任何按键时,所有的行和列都处于高电平状态。

当按下某个按键时,该按键所在的行和列会产生短接,从而导致相应的行和列变为低电平。

为了检测按键的输入,矩阵键盘通常采用矩阵扫描的方式。

具体来说,它通过依次将一行置为低电平,然后读取相应的列的状态来判断是否有按键按下。

为了提高检测的精度,还可以采用定时器中断的方式来不断扫描键盘状态。

矩阵键盘程序设计示例下面是一个简单的矩阵键盘程序设计示例,使用Arduino开发板和Keypad库来实现。

在该示例中,我们假设矩阵键盘由3行4列组成,使用数字1-9和星号()作为按键。

cppinclude <Keypad.h>const byte ROWS = 3; // 定义行数const byte COLS = 4; // 定义列数char keys[ROWS][COLS] = {{'1','2','3','A'},{'4','5','6','B'},{'7','8','9','C'}};byte rowPins[ROWS] = {9, 8, 7}; // 设置行引脚byte colPins[COLS] = {6, 5, 4, 3}; // 设置列引脚Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);void setup() {Serial.begin(9600); // 初始化串口通信}void loop() {char key = keypad.getKey(); // 读取按键if (key != NO_KEY) { // 判断是否有按键按下Serial.println(key); // 打印按下的按键到串口}delay(100); // 延时等待}在上述示例中,我们定义了矩阵键盘的行数和列数,并指定了每个按键的字符表示。

51单片机44矩阵键盘源程序

51单片机44矩阵键盘源程序

51单片机4*4矩阵键盘源程序;P3口接键盘;P0口接数码管段码端控位,再将任一数码管的位码接地AD EQU 30H org 0000hLJMP MAINORG 0030HMAIN: mov p3,#0Fh ;p0-3输出1,作为输入位mov a ,p3ANL A,#0FHCJNE A,#0FH,DELAYSJMP MAINDELAY: ACALL DELAY1 ; 延时去键抖mov a ,p3ANL A,#0FHCJNE A,#0FH,HA VESJMP MAINHA VE:MOV A,#0EFH ;行扫描码NEXT:MOV B,AMOV P3,AMOV A,p3ANL A,#0FH ;检测列CJNE A,#0FH,YESMOV A,BRL ACJNE A,#0FEH,NEXTYES: orl a,#0f0h ;高四位置1CPL Amov r2,#00hMOV R2,A ;存列码MOV A,B ;取行码,CPL AORL A,R2 ;列码+行码=键植MOV P2,A ; 用P2口接发光二极管查看结果MOV AD,#00H ACALL DISPKEYVJMP MAINDISPKEYV:KEY0:CJNE A,#11H,KEY1AJMP WORD0KEY1:CJNE A,#12H,KEY2AJMP WORD1KEY2:CJNE A,#14H,KEY3AJMP WORD2KEY3:CJNE A,#18H,KEY4AJMP WORD3KEY4:CJNE A,#21H,KEY5AJMP WORD4KEY5:CJNE A,#22H,KEY6AJMP WORD5KEY6:CJNE A,#24H,KEY7AJMP WORD6KEY7:CJNE A,#28H,KEY8AJMP WORD7KEY8:CJNE A,#41H,KEY9AJMP WORD8KEY9:CJNE A,#42H,KEY10 AJMP WORD9KEY10:CJNE A,#44H,KEY11 AJMP WORD10KEY11:CJNE A,#48H,KEY12 AJMP WORD11KEY12:CJNE A,#81H,KEY13 AJMP WORD12KEY13:CJNE A,#82H,KEY14 AJMP WORD13KEY14:CJNE A,#84H,KEY15 AJMP WORD14KEY15:CJNE A,#88H,PASSAJMP WORD15 WORD0:MOV AD,#00ACALL DISPAjmp PASSWORD1:MOV AD,#01ACALL DISPAjmp PASSWORD2:MOV AD,#02ACALL DISPAjmp PASSWORD3:MOV AD,#03ACALL DISPAjmp PASSWORD4:MOV AD,#04ACALL DISPAjmp PASSWORD5:MOV AD,#05 ACALL DISPAjmp PASSWORD6:MOV AD,#06 ACALL DISPAjmp PASSWORD7:MOV AD,#07ACALL DISPAjmp PASSWORD8:MOV AD,#08 ACALL DISPAjmp PASSWORD9:MOV AD,#9ACALL DISPAjmp PASSWORD10:MOV AD,#10 ACALL DISPAjmp PASSWORD11:MOV AD,#11 ACALL DISPAjmp PASSWORD12:MOV AD,#12 ACALL DISPAjmp PASS WORD13:MOV AD,#13 ACALL DISPAjmp PASSWORD14:MOV AD,#14 ACALL DISPAjmp PASSWORD15:MOV AD,#15ACALL DISPPASS: retDISP: MOV A,ADMOV DPTR,#numtabMOVC A,@A+DPTRMOV P0,ARETnumtab: DB 0c0H,0f9H,0a4H,0b0H,99H,92H,82H,0f8H,80H,90H,88H,83H,0C6H,0A1H,86H,8EHDELAY1:MOV R5,#10D1: MOV R6,#250DJNZ R7, $DJNZ R5,D1RETEND。

矩阵键盘过程及扫描程序

矩阵键盘过程及扫描程序

键盘是单片机常用输入设备,在按键数量较多时,为了节省I/O口等单片机资源,一般采取扫描的方式来识别到底是哪一个键被按下。

即通过确定被按下的键处在哪一行哪一列来确定该键的位置,获取键值以启动相应的功能程序。

矩阵键盘的四列依次接到单片机的P1.0~P1.3,四行依次接到单片机的P1.4~P1.7;同时,将列线上拉,通过10K电阻接电源。

查找哪个按键被按下的方法为:一个一个地查找。

先第一行输出0,检查列线是否非全高;否则第二行输出0,检查列线是否非全高;否则第三行输出0,检查列线是否非全高;如果某行输出0时,查到列线非全高,则该行有按键按下;根据第几行线输出0与第几列线读入为0,即可判断在具体什么位置的按键按下。

下面是具体程序:void Check_Key(void){unsigned char row,col,tmp1,tmp2;tmp1 = 0x10;//tmp1用来设置P1口的输出,取反后使P1.4~P1.7中有一个为0for(row=0;row<4;row++) // 行检测{P1 = 0x0f; // 先将p1.4~P1.7置高P1 =~tmp1; // 使P1.4~p1.7中有一个为0tmp1*=2; // tmp1左移一位if ((P1 & 0x0f) < 0x0f)// 检测P1.0~P1.3中是否有一位为0,只要有,则说明此行有键按下,进入列检测{tmp2 = 0x01; // tmp2用于检测出哪一列为0for(col =0;col<4;col++) // 列检测{if((P1 & tmp2)==0x00)// 该列如果为低电平则可以判定为该列{key_val =key_Map[ row*4 +col ];// 获取键值,识别按键;key_Map为按键的定义表return; // 退出循环}tmp2*=2; // tmp2左移一位}}}} //结束。

矩阵键盘程序及原理

矩阵键盘程序及原理

程序效果:‎按下任意键‎,LED显‎示P0读回‎的数据其中‎4*4的矩‎阵键盘接P‎0口*/‎#inc‎l ude<‎r eg52‎.h> /‎/头文件‎u nsig‎n ed c‎h ar k‎e y=0x‎f f; ‎//定义‎一个变量用‎于存放按键‎值voi‎d rea‎d key(‎); ‎//读按键‎子函数,获‎取键值v‎o id m‎a in()‎ /‎/主函数‎{whi‎l e(1)‎{ ‎read‎k ey()‎; //读‎按键值i‎f(key‎!=0xf‎f) //‎判断是否有‎按键按下‎P2=~k‎e y;//‎这里取反:‎是因为LE‎D为共阴,‎显示所按下‎的值‎}}‎v oid ‎r eadk‎e y() ‎//读键盘‎子函数{‎P0=0‎x fe; ‎//将第一‎列拉低,扫‎描是否有按‎键按下,第‎一列键值为‎:0,4,‎8,C k‎e y=P0‎; //‎读取键盘值‎if(k‎e y!=0‎x fe) ‎//若ke‎y!=0x‎f e,说明‎有按键按下‎,则返回‎r etur‎n; ‎//否则‎继续扫描下‎一列P0‎=0xfd‎;key‎=P0;‎i f(ke‎y!=0x‎f d)r‎e turn‎;P0=‎0xfb;‎key=‎P0;i‎f(key‎!=0xf‎b)re‎t urn;‎P0=0‎x f7;‎k ey=P‎0;if‎(key!‎=0xf7‎)ret‎u rn;‎k ey=0‎x ff;‎}‎键盘扫‎描程序:‎从以‎上分析得到‎键盘扫描程‎序的流程图‎所示。

程序‎如下‎SCAN‎: MOV‎P1,#‎0FH‎MOV‎A,P1‎A‎N L A,‎#0FH ‎CJ‎N E A,‎#0FH,‎N EXT1‎S‎J MP N‎E XT3 ‎NE‎X T1: ‎A CALL‎D20M‎S‎M OV A‎,#0EF‎H‎N EXT2‎: MOV‎R1,A‎M‎O V P1‎,A‎MOV ‎A,P1 ‎AN‎L A,#‎0FH‎CJN‎E A,#‎0FH,K‎C ODE;‎M‎O V A,‎R1‎SETB‎C‎RLC ‎A‎J C NE‎X T2‎NEX‎T3: M‎O V R0‎,#00H‎R‎E T‎KCOD‎E: MO‎V B,#‎0FBH ‎NE‎X T4: ‎R RC A‎I‎N C B ‎JC‎NEXT‎4‎M OV A‎,R1‎SWA‎P A‎NEX‎T5: R‎R C A ‎IN‎C B‎INC‎B‎INC ‎B‎I NC B‎J‎C NEX‎T5‎NEXT‎6: MO‎V A,P‎1‎A NL A‎,#0FH‎C‎J NE A‎,#0FH‎,NEXT‎6‎M OV R‎0,#0F‎F H‎RET ‎<2‎>确定矩阵‎式键盘上何‎键被按下介‎绍一种“高‎低电平翻转‎法”。

经典的矩阵键盘扫描程序

经典的矩阵键盘扫描程序

经典的矩阵键盘扫描程序矩阵键盘是一种常见的输入设备,广泛应用于电子产品中。

为了实现对矩阵键盘的扫描和输入响应,需要编写一个矩阵键盘扫描程序。

本文将详细介绍如何编写一个经典的矩阵键盘扫描程序。

1. 程序功能描述矩阵键盘扫描程序的主要功能是实现对矩阵键盘的扫描,并根据按键的状态进行相应的处理。

程序需要实现以下功能:- 扫描矩阵键盘的按键状态;- 根据按键状态进行相应的处理;- 输出按键的值或执行相应的操作。

2. 程序设计思路矩阵键盘通常由多行多列的按键组成,每个按键都有一个唯一的行列地址。

程序的设计思路如下:- 初始化矩阵键盘的引脚和状态变量;- 循环扫描矩阵键盘的按键状态;- 检测按键状态变化,并根据变化进行相应的处理;- 输出按键的值或执行相应的操作。

3. 程序代码示例下面是一个简单的矩阵键盘扫描程序的代码示例:```#include <stdio.h>#include <stdbool.h>// 定义矩阵键盘的行列数#define ROWS 4#define COLS 4// 定义矩阵键盘的引脚int rowPins[ROWS] = {2, 3, 4, 5}; int colPins[COLS] = {6, 7, 8, 9}; // 定义矩阵键盘的按键值char keys[ROWS][COLS] = {{'1', '2', '3', 'A'},{'4', '5', '6', 'B'},{'7', '8', '9', 'C'},{'*', '0', '#', 'D'}};// 初始化矩阵键盘void setup() {// 设置引脚模式为输入for (int i = 0; i < ROWS; i++) { pinMode(rowPins[i], INPUT); }// 设置引脚模式为输出for (int i = 0; i < COLS; i++) {pinMode(colPins[i], OUTPUT);}}// 扫描矩阵键盘void scanKeypad() {for (int i = 0; i < COLS; i++) {// 将当前列引脚设置为高电平digitalWrite(colPins[i], HIGH);for (int j = 0; j < ROWS; j++) {// 检测当前行引脚的状态bool state = digitalRead(rowPins[j]); // 如果按键状态发生变化if (state != lastState[i][j]) {// 更新按键状态lastState[i][j] = state;// 如果按键被按下if (state == LOW) {// 输出按键的值Serial.println(keys[j][i]);// 执行相应的操作switch (keys[j][i]) {case '1':// 执行操作1break;case '2':// 执行操作2break;// 其他按键的操作}}}}// 将当前列引脚设置为低电平 digitalWrite(colPins[i], LOW); }}void loop() {// 扫描矩阵键盘scanKeypad();// 延时一段时间,避免频繁扫描delay(10);}```4. 程序运行结果编写完成矩阵键盘扫描程序后,可以将程序上传到相应的开发板或单片机上进行测试。

矩阵键盘控制12864显示最经典程序

矩阵键盘控制12864显示最经典程序

矩阵键盘控制12864显示最经典程序#include //这个程序的功能:用4*4的矩阵键盘(接P3口)按键盘k1——k16中的任何一个键ki#include //12864液晶上显示数字i-1 (液晶数据口接P0)#define uint unsigned int//键盘扫描的思想是将行设置为低,列设置为高,来读取P3口的值,就能知道是哪个按键按下了#define uchar unsigned char#define LCDdata P0sbit E = P2^7;sbit RW = P2^6;sbit RS = P2^5;void init();void delayms(uint x);void displaykey();void write_com(uchar com);//写命令void write_data(uchar date);//写数据uchar temp;//--------------主函数-----------------void main(){init();// P3=0xfe;//P3=0xfd;//P3=0xfb;//P3=0xf7;while(1){displaykey();}}//-------------液晶初始化----------------void init(){write_com(0x01);write_com(0x02);write_com(0x06);write_com(0x0e);}//------------毫秒延时--------------- void delayms(uint x){uchar i;while(x--){for(i=0;i<120;i++);}}//------------写命令----------------- void write_com(uchar com){RS = 0;RW = 0;E = 0;LCDdata = com;E = 1;delayms(5);E = 0;}//-------------写数据------------------ void write_data(uchar date){RS = 1;RW = 0;E = 0;LCDdata = date;E = 1;delayms(5);E = 0;}//----void displaykey(){ //****************************判断第一行的键盘P3=0xfe; temp=P3; temp=temp&0xf0;while(temp!=0xf0)//判断是否有键盘按下为真有键盘按下{ delayms(50); temp=P3; temp=temp&0xf0;while(temp!=0xf0)//再次判断是否有键盘按下为真有键盘按下{ temp=P3;switch(temp){case0xee:write_com(0x80);write_data('0');write_com(0x81);write_data (' ');break;case0xde:write_com(0x80);write_data('1');write_com(0x81);write_data (' ');break;case0xbe:write_com(0x80);write_data('2');write_com(0x81);write_data (' ');break;case0x7e:write_com(0x80);write_data('3');write_com(0x81);write_data (' ');break;}break;//这个break很重要不能丢下,若丢下会这这个中退步出来}}//******************************判断第二行的键盘P3=0xfd; temp=P3; temp=temp&0xf0;while(temp!=0xf0){ delayms(50); temp=P3; temp=temp&0xf0;while(temp!=0xf0){ temp=P3;switch(temp){case0xed:write_com(0x80);write_data('4');write_com(0x81);write_data (' ');break;case0xdd:write_com(0x80);write_data('5');write_com(0x81);write_data (' ');break;case0xbd:write_com(0x80);write_data('6');write_com(0x81);write_data (' ');break;case0x7d:write_com(0x80);write_data('7');write_com(0x81);write_data (' ');break;} break;}}//******************************判断第三行的键盘P3=0xfb; temp=P3; temp=temp&0xf0;while(temp!=0xf0){ delayms(50); temp=P3; temp=temp&0xf0;while(temp!=0xf0){ temp=P3;switch(temp){case0xeb:write_com(0x80);write_data('8');write_com(0x81);write_data (' ');break;case0xdb:write_com(0x80);write_data('9');write_com(0x81);write_data (' ');break;case0xbb:write_com(0x80);write_data('1');write_com(0x81);write_ data('0');break;case0x7b:write_com(0x80);write_data('1');write_com(0x81);write_ data('1');break;}break;}}//******************************判断第四行的键盘P3=0xf7; temp=P3; temp=temp&0xf0;while(temp!=0xf0){ delayms(50); temp=P3; temp=temp&0xf0;while(temp!=0xf0){ temp=P3;switch(temp){case0xe7:write_com(0x80);write_data('1');write_com(0x81);write_ data('2');break;case0xd7:write_com(0x80);write_data('1');write_com(0x81);write_ data('3');break;case0xb7:write_com(0x80);write_data('1');write_com(0x81);write_ data('4');break;case0x77:write_com(0x80);write_data('1');write_com(0x81);write_ data('5');break;}break;}}}。

矩阵键盘例程

矩阵键盘例程

MOV R5,A AJMP KEY
MOV R6,#100 ;1个机器周期 DJNZ R6,D1 ;2个机器周期 ;2个机器周期 ;2个机器周期
DJNZ R7,D2 RET
CJNE A,#0FH,PD2 PD2处理程序

AJMP KEY
;无键按下,返回重新扫描
;以下是那一个按键被按下处理程序 PD2:MOV R2,#0EFH MOV R4,#00H MOV A,R2 KPD: MOV P1,A MOV A,P1 JB ACC.0,HONE 理程序 MOV A,#00H AJMP LKP ;装0行行首键号 ;跳转到计算键值程序 ;扫描初值送R2;1110 1111第一列送0 ;扫描次数初值送R4 ;被扫描列线送0 ;将A中的值(初值为1110 1111)送P1口 ;读键状态 ;ACC.0为1,第0行无键被按下,转HONE处
• 以下是4行*4列键盘程序: • KEY:MOV R5,#00H ;用于存放简码,初值为0(定义为无键 • ;按下) • • • • MOV P1,#0F MOV A,P1 ANL A,#0FH ;列扫描线输出0,行扫描线置1 ;读键盘状态 ;屏蔽高4位(列线),检测行线状态 ;判断有无按键按下,有则转到
RL A;循环左移一位,A的值为0DFH;1101 1111备第二列置0 MOV R2,A ;将A的值存与R2中,以便下一列的扫描 CJNE R4,#04H,KPD;若列未扫描到4次,则返回继续扫描 AJMP KEY ;扫描完毕,开始新的一轮扫描(重新判断有无 按键按下)
;以下是计算键码程序 LKP: ADD A,R4 ;行首键号加列号是被按下的键号 ;被按下的键号存放在R5 ;开始新的一轮扫描,若为键盘子程序,; 此行为RET ;以下是10ms(采用12M晶振)延时子程序 DELAY:MOV R7,#50 D2: D1: ;1个机器周期

矩阵键盘源程序(详细)

矩阵键盘源程序(详细)
}
}
//延时子程序
//12MHz晶振,AT89S52 : 1ms
//测试结果:n=1, 1.015ms; n=10, 10.006ms;
void delay(unsigint i,j;
for(i=0;i<n;i++)
{
for(j=0;j<123;j++)
//NumBuffer[3]=(((KEY_PORT & 0xF0)^0xF0)>>4);
NumBuffer[2]=(((KEY_PORT & 0xF0))>>4);
switch(keycode)
{
case 0x7E: keycode=0; break;
case 0xBE: keycode=1; break;
{
case 0: //有按键按下吗?
if(keypad_0==keypad_0_DOWN)
{
mKey0SwapTask=1;
mKey0Value=kbdKeyRead(); //读键值
}
break;
case 0xDE: keycode=2; break;
case 0xEE: keycode=3; break;
case 0x7D: keycode=4; break;
case 0xBD: keycode=5; break;
case 0xDD: keycode=6; break;
NumDisplayIndex=0;
}
}
//按键矩阵扫描子程序
void kbdScan(void)
{
#define keypad_0 kbdIsKeyDown() //定义端口

4X4矩阵键盘的测试程序

4X4矩阵键盘的测试程序

#include <reg52.h>#define uchar unsigned char#define uint unsigned int#define LCDDATA P0 //数码管数据端口定义#define LCDCS P2 //数码管位选端口定义#define KEYDATA P1 //矩阵键盘接口定义uchar key; //定义键值为全局变量uchar dis_buf; //显示缓存uchar disp_num[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};//显示数据列表0---9//功能:延时1毫秒//入口参数:x//出口参数:无void Delay_xms(uint x){uint i,j;for(i=0;i<x;i++)for(j=0;j<112;j++);}//关闭数码管显示,当Q0~Q3均为高电平时,三极管均截止,无电流流过数码管,显示被关闭void tube_off(void){LCDCS|=0xf0;}//数码管数据显示//入口参数:x为需要显示的数据,addr为数码管地址即第几位数码管void tube_disp(uchar addr,uchar x){LCDDATA=disp_num[x];//将显示数据送P0口switch(addr){case 1: //选通第1位数码管LCDCS&=0xef;break;case 2: //选通第2位数码管LCDCS&=0xdf;break;case 3: //选通第3位数码管LCDCS&=0xbf;break;case 4: //选通第4位数码管LCDCS&=0x7f;break;}Delay_xms(2);tube_off();}//键扫描子程序void keyscan(void){uchar temp=0,key=0;KEYDATA=0xF0; //高四位输入行为高电平列为低电平Delay_xms(1);temp=KEYDA TA; //读P1口temp=temp&0xF0; //屏蔽低四位temp=~((temp>>4)|0xF0);if(temp==1) // P1.4 被拉低key=0;else if(temp==2) // P1.5 被拉低key=1;else if(temp==4) // P1.6 被拉低key=2;else if(temp==8) // P1.7 被拉低key=3;elsekey=16;KEYDATA=0x0F; //低四位输入列为高电平行为低电平Delay_xms(1);temp=KEYDA TA; //读P1口temp=temp&0x0F;temp=~(temp|0xF0);if(temp==1)key=key+12;else if(temp==2) // P1.1 被拉低key=key+8;else if(temp==4) // P1.2 被拉低key=key+4;else if(temp==8) // P1.3 被拉低key=key+0;elsekey=16;if(key<16){dis_buf = key; //键值入显示缓存}}//判断键是否按下uchar keydown(void){uchar key_flag;KEYDATA=0xf0;if(KEYDATA!=0xf0){key_flag=1;}else{key_flag=0;}return key_flag;}//定时器中断函数void Timer2() interrupt 5 //定时器2是5号中断{uchar shiwei,gewei;TF2=0;shiwei=dis_buf%100/10;tube_disp(3,shiwei);//第3位数码管显示"十位"gewei=dis_buf%10;tube_disp(4,gewei); //第4位数码管显示"个位"}//定时器2初始化void Init_timer2(void){RCAP2H=0xb1;//赋T2初始值0xb1e0,溢出50次为1秒,则每次溢出时间为1/50=0.02s RCAP2L=0xe0;TR2=1; //启动定时器2ET2=1; //打开定时器2中断EA=1; //打开总中断}//主函数void main(void){Delay_xms(50);//等待系统稳定Init_timer2();//定时器2初始化P2=0xFF; //置P2口tube_off(); //关闭数码管显示while(1){if(keydown()){Delay_xms(20);if(keydown()){keyscan();}}}}。

单片机 矩阵键盘实验 实验报告

单片机 矩阵键盘实验 实验报告

实验五矩阵键盘实验一、实验内容1、编写程序,做到在键盘上每按一个数字键(0-F)用发光二极管将该代码显示出来。

按其它键退出。

2、加法设计计算器,实验板上有12个按键,编写程序,实现一位整数加法运算功能。

可定义“A”键为“+”键,“B”键为“=”键。

二、实验目的1、学习独立式按键的查询识别方法。

2、非编码矩阵键盘的行反转法识别方法。

三、实验说明1、MCS51系列单片机的P0~P3口作为输入端口使用时必须先向端口写入“1”。

2、用查询方式检测按键时,要加入延时(通常采用软件延时10~20mS)以消除抖动。

3、识别键的闭合,通常采用行扫描法和行反转法。

行扫描法是使键盘上某一行线为低电平,而其余行接高电平,然后读取列值,如读列值中某位为低电平,表明有键按下,否则扫描下一行,直到扫完所有行。

行反转法识别闭合键时,要将行线接一并行口,先让它工作在输出方式,将列线也接到一个并行口,先让它工作于输入方式,程序使CPU通过输出端口在各行线上全部送低电平,然后读入列线值,如此时有某键被按下,则必定会使某一列线值为0。

然后,程序对两个并行端口进行方式设置,使行线工作于输入方式,列线工作于输出方式,并将刚才读得的列线值从列线所接的并行端口输出,再读取行线上输入值,那么,在闭合键所在行线上的值必定为0。

这样,当一个键被接下时,必定可以读得一对唯一的行线值和列线值。

由于51单片机的并口能够动态地改变输入输出方式,因此,矩阵键盘采用行反转法识别最为简便。

行反转法识别按键的过程是:首先,将4个行线作为输出,将其全部置0,4个列线作为输入,将其全部置1,也就是向P1口写入0xF0;假如此时没有人按键,从P1口读出的值应仍为0xF0;假如此时1、4、7、0四个键中有一个键被按下,则P1.6被拉低,从P1口读出的值为0xB0;为了确定是这四个键中哪一个被按下,可将刚才从P1口读出的数的低四位置1后再写入P1口,即将0xBF写入P1口,使P1.6为低,其余均为高,若此时被按下的键是“4”,则P1.1被拉低,从P1口读出的值为0xBE;这样,当只有一个键被按下时,每一个键只有唯一的反转码,事先为12个键的反转码建一个表,通过查表就可知道是哪个键被按下了。

矩阵键盘程序c程序-51单片机.

矩阵键盘程序c程序-51单片机.

/*编译环境:Keil 7.50A c51 *//*******************************************************//*********************************包含头文件********************************/#include<reg51.h>/*********************************数码管表格********************************/ unsigned char table[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0xC6,0xA1,0x86,0x 8E};/****************************************************************************函数功能:延时子程序入口参数:出口参数:****************************************************************************/ void delay(void){unsigned char i,j;for(i=0;i<20;i++)for(j=0;j<250;j++);}/****************************************************************************函数功能:LED显示子程序入口参数:i出口参数:****************************************************************************/ void display(unsigned char i){P2=0xfe;P0=table[i];}/****************************************************************************函数功能:键盘扫描子程序入口参数:出口参数:****************************************************************************/ void keyscan(void){unsigned char n;//扫描第一行P1=0xfe;n=P1;n&=0xf0;if(n!=0xf0){delay();P1=0xfe;n=P1;n&=0xf0;if(n!=0xf0){switch(n){case(0xe0):display(3);break;case(0xd0):display(2);break;case(0xb0):display(1);break;case(0x70):display(0);break;}}}//扫描第二行P1=0xfd;n=P1;n&=0xf0;if(n!=0xf0){delay();P1=0xfd;n=P1;n&=0xf0;if(n!=0xf0){switch(n){case(0xe0):display(7);break;case(0xd0):display(6);break;case(0xb0):display(5);break;case(0x70):display(4);break;}}}//扫描第三行P1=0xfb;n=P1;n&=0xf0;if(n!=0xf0){delay();P1=0xfb;n=P1;n&=0xf0;if(n!=0xf0){switch(n){case(0xe0):display(11);break;case(0xd0):display(10);break;case(0xb0):display(9);break;case(0x70):display(8);break;}}}//扫描第四行P1=0xf7;n=P1;n&=0xf0;if(n!=0xf0){delay();P1=0xf7;n=P1;n&=0xf0;if(n!=0xf0){switch(n){case(0xe0):display(15);break;case(0xd0):display(14);break;case(0xb0):display(13);break;case(0x70):display(12);break;}}}}/**************************************************************************** 函数功能:主程序入口参数:出口参数:****************************************************************************/ void main(void){while(1){keyscan();}}。

矩阵键盘程序(汇编+lcd显示)

矩阵键盘程序(汇编+lcd显示)

; p0接lcd; p2接矩阵键盘rs equ p1.5 ;确定具体硬件的连接方式rw equ p1.6 ;确定具体硬件的连接方式e equ p1.7 ;lcd1602引脚org 0hmain:acall startmov p0,#8fh ;写入显示起始地址(第一行第一个位置)acall enable ;调用写入命令子程序mov r0,#2fhmov 2fh,#30hmov r6,#1acall write1d: mov 56h,#0mov r1,#50hmov 54h,#2fhtest: ;键盘扫描mov p2,#0f0hmov a,p2cjne a,#0f0h,havesjmp testhave:mov a,#0fehnext:mov b,amov p2,aread:mov a,p2anl a,#0F0hcjne a,#0F0h,scondmov a,brl acjne a,#0efh,nextscond:acall daymov a,p2anl a,#0f0hcjne a,#0f0h,jssjmp testjs:mov r2,amov a,banl a,#0fhorl a,r2ajmp mains1: cjne a,#0d7h,s4mov b,#31h ;1的ACSII值为31Hajmp yzs4: cjne a,#0b7h,s7mov b,#34hajmp yzs7: cjne a,#77h,s0mov b,#37hajmp yzs0: cjne a,#0ebh,s2mov b,#30hajmp yzs2: cjne a,#0dbh,s5mov b,#32hajmp yzs5: cjne a,#0bbh,s8mov b,#35hajmp yzs8: cjne a,#7bh,s3mov b,#38hajmp yzs3: cjne a,#0ddh,s6mov b,#33hajmp yzs6: cjne a,#0bdh,s9mov b,#36hajmp yzs9: cjne a,#7dh,testmov b,#39hajmp yzyz:mov a,56hcjne a,#0,yz1sjmp yz2yz1:cjne @r1,#10,yz2ajmp testyz2:cjne r1,#50h,yz3mov 55h,#0mov 58h,#0mov a,56hmov 56h,#1mov 50h,#0mov r0,#20hyz3:cjne @r1,#1,yz4mov r0,54hcjne @r0,#30h,yz4mov @r0,#0mov @r1,#0yz4:mov r2,#8yz5:mov a,54hsubb a,r2mov r0,amov a,@r0dec r0mov @r0,adec r2inc r0mov a,r0cjne a,54h,yz5mov r0,54hmov @r0,bacall showajmp testshow:acall startmov a,#8fhsubb a,@r1mov p0,a ;写入显示起始地址(第一行第一个位置)acall enable ;调用写入命令子程序mov a,54hsubb a,@r1mov r0,ainc @r1mov a,@r1mov r6,aacall write1ret;lcd1602部分start:mov p0,#1h ;清屏并光标复位acall enable ;调用写入命令子程序mov p0,#8h ;设置显示模式:8位2行5x7点阵acall enable ;调用写入命令子程序mov p0,#0ch ;显示器开、光标关acall enable ;调用写入命令子程序mov p0,#6h ;文字不动,光标自动右移acall enable ;调用写入命令子程序retenable:clr rs ;写入控制命令的子程序clr rwclr eacall delaysetb eretwrite1:mov a,@r0lcall write2 ;调用写入数据寄存器子程序inc r0 ;取码指针加1djnz r6,write1retwrite2:mov p0,asetb rs ;rs=1clr rw ;rw=0准备写入数据clr e ;e=0执行显示命令acall delay ;判断液晶模块是否忙?(用延时代替) setb e ;e=1retdelay:mov r2,#2fhdl1:mov r3,#0fhdjnz r3,$djnz r2,dl1retday:mov r2,#100 ;按键延时0.1sdl3:mov r3,#250dl2:nopnopdjnz r3,dl2djnz r2,dl3retend。

矩阵键盘程序

矩阵键盘程序

/****************************************************************************** ** 实验名: 矩阵键盘实验* 使用的IO : 数码管使用P0,键盘使用P3.0、P3.1、P3.2、P3.3* 实验效果: 按矩阵键盘分别显示在数码管上面显示十六进制的0到F。

* 注意:******************************************************************************* /#include<reg51.h>#define GPIO_DIG P0#define GPIO_KEY P1unsigned char code DIG_CODE[17]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0、1、2、3、4、5、6、7、8、9、A、b、C、d、E、F的显示码unsigned char KeyValue;//用来存放读取到的键值void Delay10ms(); //延时10msvoid KeyDown(); //检测按键函数/****************************************************************************** ** 函数名: main* 函数功能: 主函数* 输入: 无* 输出: 无******************************************************************************* /void main(void){while(1){KeyDown();GPIO_DIG=~DIG_CODE[KeyValue];}}/****************************************************************************** ** 函数名: KeyDown* 函数功能: 检测有按键按下并读取键值* 输入: 无******************************************************************************* /void KeyDown(void){char a=0;GPIO_KEY=0x0f;if(GPIO_KEY!=0x0f)//读取按键是否按下{Delay10ms();//延时10ms进行消抖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)) //检测按键松手检测{Delay10ms();a++;}}}}/****************************************************************************** ** 函数名: Delay10ms* 函数功能: 延时函数,延时10ms* 输入: 无******************************************************************************* /void Delay10ms(void) //误差0us{unsigned char a,b,c;for(c=1;c>0;c--)for(b=38;b>0;b--)for(a=130;a>0;a--);}。

矩阵键盘C语言程序

矩阵键盘C语言程序

/********************************************************************************* 描述:** 矩阵键盘数码管显示键值** 排线连接方法:JP8(P1)与JP4(矩阵键盘接口)连接 P0与JP3(静态数码管)连接 * * 矩阵键盘定义:** P1.1-P1.4为列线,P1.4-P1.7为行线** 喇叭接P1.5口矩阵键盘P1口,** 注意:请将JP165短路冒断开*********************************************************************************/#include <reg51.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intuchar dis_buf; //显示缓存uchar temp;uchar key; //键顺序吗void delay0(uchar x); //x*0.14MS#define delayNOP(); {_nop_();_nop_();_nop_();_nop_();};// 此表为 LED 的字模 0 1 2 3 4 5 6 78 9 a b c d e funsigned char code LED7Code[] ={~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0x39,~0x5E,~0x79,~0x71};/*************************************************************//* *//* 延时子程序 *//* *//*************************************************************/void delay(uchar x){ uchar j;while((x--)!=0){ for(j=0;j<125;j++){;}}}/*************************************************************/ /* */ /* 键扫描子程序 (4*3 的矩阵) P1.4 P1.5 P1.6 P1.7为行 */ /* P1.1 P1.2 P1.3为列 *//* *//*************************************************************/void keyscan(void){ temp = 0;P1=0xF0; //高四位输入行为高电平列为低电平 delay(1);temp=P1; //读P1口temp=temp&0xF0; //屏蔽低四位temp=~((temp>>4)|0xF0);if(temp==1) // p1.4 被拉低key=0;else if(temp==2) // p1.5 被拉低key=1;else if(temp==4) // p1.6 被拉低key=2;else if(temp==8) // p1.7 被拉低key=3;elsekey=16;P1=0x0F; //低四位输入列为高电平行为低电平delay(1);temp=P1; //读P1口temp=temp&0x0F;temp=~(temp|0xF0);if(temp==2) // p1.1 被拉低key=key+0;else if(temp==4) // p1.2 被拉低key=key+4;else if(temp==8) // p1.3 被拉低key=key+8;elsekey=16;dis_buf = key; //键值入显示缓存dis_buf = dis_buf & 0x0f;}/*************************************************************//* *//*判断键是否按下 *//* *//*************************************************************/void keydown(void){P1=0xF0;if(P1!=0xF0) //判断按键是否按下如果按钮按下会拉低P1其中的一个端口{keyscan(); //调用按键扫描程序}}/*************************************************************//* *//* 主程序 *//* *//*************************************************************/main(){P0=0xFF; //置P0口P1=0xFF; //置P1口delay(10); //延时while(1){keydown(); //调用按键判断检测程序P0 = LED7Code[dis_buf%16]&0x7f; //LED7 0x7f为小数点共阴和共阳此处也是不一样; %16表示输出16进制}}/************************************************************/。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1、参考程序
#include <reg51.h>
#include <intrins.h>
#define uint unsigned int
#define uchar unsigned char
//uchar code table[10] = {0x03, 0x9f, 0x25, 0x0d, 0x99, 0x49, 0x41, 0x1f, 0x01, 0x09}; //共阴段码
uchar code table[10] = {0xC0, 0xf9, 0xa4, 0xb0, 0x99, 0x92, 0x82, 0xf8, 0x80, 0x90}; //共阳段码
/**************************************************************
* 名称: Delay_1ms()
* 功能: 延时子程序,延时时间为1ms * x
* 输入: x (延时一毫秒的个数)
注意后面的调用格式!!!!!!
可以搜集常用延时,积累到小本上
****************************************************************/
void Delay_1ms(uint x)
{
uint i;
uchar j;
for(i = 0; i < x; i++) for(j = 0; j <= 148; j++);
}
***************************************************************/
uchar Keyscan(void)
{
uchar i, j, temp, Buffer[4] = {0xef, 0xdf, 0xbf, 0x7f}; //查阅C语言数据的存储结构
for(j = 0; j < 4; j++) { //循环四次
P1 = Buffer[j]; //在P1高四位分别输出一个低电平
temp = 0x01; //计划先判断P1.0位
for(i = 0; i < 4; i++) { //行扫描
if(!(P1 & temp)) //重点理解此语句
return (i + j * 4); //返回取得的按键值
temp <<= 1; //判断的位,左移一位
} }
return 16; //判断结束,没有键按下,返回16
}
/**************************************************************
* 名称:Display(uchar k)
* 功能:将参数分成十位、个位分别显示
* 输入:k (键盘数值)
* 输出:P0口输出___________,P2口输出____________
***************************************************************/
void Display(uchar k)
{
P2 = 0; //消隐
P0 = table[k / 10]; //_______该语句的含义
P2 = 0x02; Delay_1ms(5); //显示5ms十位
P2 = 0; //消隐
P0 = table[k % 10]; _______该语句含义
P2 = 0x01; Delay_1ms(5); //显示5ms个位
}
/************************************************************** * 名称: Main()
* 功能: 主函数
***************************************************************/ void Main(void)
{
uchar Key_Value = 16, Key_Temp1, Key_Temp2; //两次读出的键值
while(1) {
//---------以下读入按键、消抖、等待按键释放
P1 = 0xff;
Key_Temp1 = Keyscan(); //先读入按键
if(Key_Temp1 != 16) { //如果有键按下
//Delay_1ms(10); //延时一下
Display(Key_Value); //可用显示代替延时
Key_Temp2 = Keyscan(); //再读一次按键
if (Key_Temp1 == Key_Temp2) {//必须是两次相等
Key_Value = Key_Temp1; //才保存下来,这就是消除抖动
while(Keyscan() < 16) //等待按键释放
Display(Key_Value); //等待期间显示键值
//---------以下是对按键的处理
Display(Key_Value); //显示键值
} }
Display(Key_Value); //没有按键按下,也显示键值
}
}。

相关文档
最新文档