51单片机矩阵键盘扫描程序

合集下载

基于51单片机的利用单片机IO口实现阵列式键盘程序

基于51单片机的利用单片机IO口实现阵列式键盘程序

基于51单片机的利用单片机IO口实现阵列式键盘程序//-----------------------函数声明,变量定义---------------------------#include //头文件#define uchar unsigned char //类型定义#define uint unsigned int //类型定义#define KEY P1//-----------------------函数声明------------------------------------void SCANkey(); //程序扫描键盘,供主程序调用void delay(uint N); //延时子程序,实现(16*N+24)us的延时bit hitkey(); //判断是否有键按下,有返回1,没有返回0 uchar scan_key(); //扫描键盘,返回键值void key_manage(uchar keycode); //键值处理跳转程序void key1(void); //按键1处理程序//……//其它按键处理程序省略//main():主函数//在主函数中,先对系统进行初始化设置,其后主要任务是实时检测有无按键按下,有按键按下时,调用相应处理程序;无按键按下时,继续循环检测。

void main(){EA=0; //关中断while(1) //循环检测按键,调用相应处理程序{SCANkey(); //调用扫描键盘程序}}//SCANkey():扫描键盘程序//扫描键盘程序,有键按下完成按键处理,无键按下直接返回。

void SCANkey(){uchar key_code;if(hitkey()) //判断是否有键按下{delay(1000); //延时20ms左右,消除抖动干扰if(hitkey()) //判断是否有效按键{key_code=scan_key();while(hitkey()); //等待按键释放key_manage(key_code); //键盘扫描、键值处理跳转、按键处理} }}//delay():延时子程序//延时子程序,实现(16*N+24)us的延时。

51键盘矩阵扫描程序

51键盘矩阵扫描程序

51键盘矩阵扫描程序假设按下的是S1键进行如下检测(4*4键盘)先在P3口输出p3 00001111低四位行会有变化cord_h =00001111&00001110 =00001110if !=00001111延时0.1uscord_h=00001110&00001111=00001110if !=00001111P3再输出11111110P3 =00001110|11110000=11111110输出高四位cord_l=P3&0xf0 //此时P3口就是(实际值)输入值01111110 而不是上面的11111110cord_l=01111110&11110000=01110000cord_h+cord_l=00001110+01110000=01111110=0x7e //此编码即为S1的编码#include <reg52.h>//包含头文件#define uchar unsigned char#define uint unsigned intunsigned char consttable[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};//0-Fuchar keyscan(void);void delay(uint i);void main(){uchar key;P2=0x00;//1数码管亮按相应的按键,会显示按键上的字符while(1){key=keyscan();//调用键盘扫描,switch(key){case 0x7e:P0=table[0];break;//0 按下相应的键显示相对应的码值case 0x7d:P0=table[1];break;//1case 0x7b:P0=table[2];break;//2case 0x77:P0=table[3];break;//3case 0xbe:P0=table[4];break;//4case 0xbd:P0=table[5];break;//5case 0xbb:P0=table[6];break;//6case 0xb7:P0=table[7];break;//7case 0xde:P0=table[8];break;//8case 0xdd:P0=table[9];break;//9case 0xdb:P0=table[10];break;//acase 0xd7:P0=table[11];break;//bcase 0xee:P0=table[12];break;//ccase 0xed:P0=table[13];break;//dcase 0xeb:P0=table[14];break;//ecase 0xe7:P0=table[15];break;//f}}}uchar keyscan(void)//键盘扫描函数,使用行列反转扫描法{uchar cord_h,cord_l;//行列值P3=0x0f; //行线输出全为0cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f) //先检测有无按键按下{delay(100); //去抖cord_h=P3&0x0f; //读入列线值if(cord_h!=0x0f){P3=cord_h|0xf0; //输出当前列线值cord_l=P3&0xf0; //读入行线值return(cord_h+cord_l);//键盘最后组合码值}}return(0xff); //返回该值}void delay(uint i)//延时函数{while(i--);}。

键盘扫描程序实验报告

键盘扫描程序实验报告

一、实验目的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. 实验结果:程序下载到单片机后,按键按下时,单片机能够正确读取按键值。

51单片机矩阵键盘扫描程序

51单片机矩阵键盘扫描程序
void Timer0_isr(void) interrupt 1
{
TH0=(65536-2000)/256;//重新赋值2ms
TL0=(65536-2000)%256;
Display(0,8); //调用数码管扫描
}
/*------------------------------------------------
unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,
0x77,0x7c,0x39,0x5e,0x79,0x71};//显示段码值0~F
unsigned char code dofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码
case 0xd7:return 11;break;//b
case 0xee:return 12;break;//c
case 0xed:return 13;break;//d
case 0xeb:return 14;break;//e
case 0xe7:return 15;break;//f
default:return 0xff;break;
}
}
/*------------------------------------------------
uS延时函数,含有输入参数unsigned char t,无返回值
unsigned char是定义无符号字符变量,其值的范围是
0~255这里使用晶振12M,精确延时请使用汇编,大致延时
长度如下T=tx2+5 uS

51单片机矩阵键盘C语言编程

51单片机矩阵键盘C语言编程

X1
19 X1
P20 P21 P22 P23 P24 P25 P26 P27
21 22 23 24 25 26 27 28
+5V
RES X1
+5V
C3 1uF
R1
C1
1K
X2
18 X2
RES
9 RESET
EA/VPP RD/P37 WR/P36 ALE/PRDG
PSEN
31 17 16 30 29
1
}
/****************************************************************************** 函数名称:void keyscan() 函数功能:键盘扫描及按键处理
******************************************************************************/
//如果有按键闭合
{ keyvalue=(~HSM)+(~(LJC|0x0f));
//计算键盘值
return(keyvalue);
//返回键值
} else HSM=(HSM<<1)|0x01;
//行扫描左移 1 位,准备扫描下一行}} Nhomakorabea}
return(0x00);
}
break;
case 0x12: P0=0x66; //4
break;
case 0x22: P0=0x6d; //5
break;
case 0x42: P0=0x7d; //6
break;
case 0x82: P0=0x07; //7
break;

矩阵键盘扫描汇编程序

矩阵键盘扫描汇编程序

4*4矩阵键盘扫描汇编程序(基于51单片机)// 程序名称:4-4keyscan.asm;// 程序用途:4*4矩阵键盘扫描检测;// 功能描述:扫描键盘,确定按键值。

程序不支持双键同时按下,;// 如果发生双键同时按下时,程序将只识别其中先扫描的按键;// 程序入口:void;// 程序出口:KEYNAME,包含按键信息、按键有效信息、当前按键状态;//================================================================== ====PROC KEYCHKKEYNAME DATA 40H ;按键名称存储单元;(b7-b5纪录按键状态,b4位为有效位,;b3-b0纪录按键)KEYRTIME DATA 43H ;重复按键时间间隔SIGNAL DATA 50H ;提示信号时间存储单元KEY EQU P3 ;键盘接口(必须完整I/O口) KEYPL EQU P0.6 ;指示灯接口RTIME EQU 30 ;重复按键输入等待时间KEYCHK:;//=============按键检测程序========================================= ====MOV KEY,#0FH ;送扫描信号MOV A,KEY ;读按键状态CJNE A,#0FH,NEXT1 ;ACC<=0FH; CLR C ;Acc等于0FH,则CY为0,无须置0NEXT1:; SETB C ;Acc不等于0FH,则ACC必小于0 FH,;CY为1,无须置1MOV A,KEYNAMEANL KEYNAME,#1FH ;按键名称屏蔽高三位RRC A ;ACC带CY右移一位,纪录当前按键状态ANL A,#0E0H ;屏蔽低五位ORL KEYNAME,A ;保留按键状态;//=============判别按键状态,决定是否执行按键扫描=================== =====CJNE A,#0C0H,NEXT2 ;110按键稳定闭合,调用按键检测子程序SJMP KEYSCANNEXT2:CJNE A,#0E0H,NEXT3 ;111按键长闭合,重复输入允许判断SJMP WAITNEXT3:CJNE A,#0A0H,EXIT ;101干扰,当111长闭合处理ORL KEYNAME,#0E0HWAIT:MOV A,KEYRTIMEJNZ EXIT ;时间没到,退出;//=============键盘扫描程序========================================= =====KEYSCAN:MOV R1,#0 ;初始化列地址MOV R3,#11110111B ;初始化扫描码LOOP:MOV A,R3RL AMOV R3,A ;保留扫描码MOV KEY,A ;送扫描码MOV A,KEY ;读键盘ORL A,#0F0H ;屏蔽高四位CJNE A,#0FFH,NEXT31 ;A不等于FFH,说明该列有按键动作INC R1 ;列地址加1,准备扫描下一列CJNE R1,#4,LOOP ;列地址不等于4,扫描下一列SJMP EXIT ;没有按键,退出;//=============按键判断对应位等于零,说明该行有按键按下============= =====NEXT31:JB ACC.0,NEXT32MOV R2,#0 ;第0行有按键SJMP NEXT5NEXT32:JB ACC.1,NEXT33MOV R2,#1 ;第1行有按键SJMP NEXT5NEXT33:JB ACC.2,NEXT34MOV R2,#2 ;第2行有按键SJMP NEXT5NEXT34:MOV R2,#3 ;第3行有按键NEXT5: ;计算按键地址MOV A,R1RL ARL A ;列地址乘4(每列对应4行)ADD A,R2 ;加行地址MOV DPTR,#KEYTABMOVC A,@A+DPTRANL KEYNAME,#0E0HORL KEYNAME,A ;送按键(送值的时候已经置按键有效)MOV KEYRTIME,#RTIME ;送重复按键等待时间CLR KEYPL ;打开指示灯MOV SIGNAL,#10 ;送信号提示时间(每次按键闪10 0ms)EXIT:MOV KEY,#0FFH ;置键盘接口高电平RET ;退出;//=============按键名称表=========================================== =====KEYTAB:DB 1AH ;扫描码0,对应A ************************************ ******DB 1BH ;扫描码1,对应B ** **DB 1CH ;扫描码2,对应C ** I/O口 PX.4 PX.5 PX.6 PX.7 **DB 1DH ;扫描码3,对应D ** **DB 11H ;扫描码4,对应1 ** PX.0 A(0) 1(4) 2(8) 3 (C) **DB 14H ;扫描码5,对应4 ** **DB 17H ;扫描码6,对应7 ** PX.1 B(1) 4(5) 5(9) 6 (D) **DB 1EH ;扫描码7,对应E ** **DB 12H ;扫描码8,对应2 ** PX.2 C(2) 7(6) 8(A) 9 (E) **DB 15H ;扫描码9,对应5 ** **DB 18H ;扫描码A,对应8 ** PX.3 D(3) E(7) 0(B) F(F) **DB 10H ;扫描码B,对应0 ** **DB 13H ;扫描码C,对应3 ************************************ ******DB 16H ;扫描码D,对应6DB 19H ;扫描码E,对应9DB 1FH ;扫描码F,对应FEND第二种解法ORG 0000HSTART: MOV R0,#00H ;初始化程序,开始的延时是为了使硬件能够准备好DJNZ R0,$LOOP: MOV SP,#60HCALL KEYDISPLAY:MOV A,R4MOV DPTR,#TABLE ;定义字形表的起始地址MOVC A,@A+DPTR ;TABLE为表的起始地址MOV P2,ASJMP LOOP;子程序内容,P1口的低四位为行线,高四位为列线KEY: PUSH PSWPUSH ACCMOV P1,#0F0H ;令所有的行为低电平,全扫描字-P1.0-P1.3,列为输入方式;这一段只是验证有键按下,并不能判断是哪一行MOV R7,#0FFH ;设置计数常数,作为延时KEY1: DJNZ R7, KEY1MOV A,P1 ;读取P1口的列值ANL A,#0F0H ;判别有键值按下吗(当有键按下时,P1口的高四位就不全为1了,底四位还是都为0的);这个地方进行相或的原因,是因为要把底四位的0000变成1111,以便下一步进行求反ORL A,#0FH //这个地方原版上没有,这是又加了,如果不加的的话,是不对的********CPL A ;求反后,有高电平就有键按下JZ EKEY;累加器为0则转移(意为求反后本来全为0的,如果有键按下时,求反后高四位就有1了),退出LCALL DEL20ms ;有键按下,进行处理;下面进行行行扫描,1行1行扫SKEY: MOV A,#00HMOV R0,A ;R0作为行计数器,开始初值为0MOV R1,A ;R1作为列计数器,开始初值为0MOV R2,#0FEH ;R2作为扫描暂存字,开始初值为1111 1110,(第四位作为行扫描字)SKEY2: MOV A,R2MOV P1,A ;输出行扫描字,1111 1110NOPNOPNOP ;3个NOP操作使P1口输出稳定MOV A,P1 ;读列值(和开始一样)MOV R1,A ;暂存列值(第一次为**** 1110,既高四位有一位"可能"会为0)ANL A,#0F0H ;取高四位,ORL A,#0FH ;使第四位全部置1CPL ABIAOZHI:JNZ SKEY3 ;累加器为非0则转移指令(意思是判断到按键在这一行),转去处理INC R0 ;如果按键没在这一行,行计数器加1SETB C ;进位标志位加1,为了在左移的时候开始的低位0不在出现在低(循环一圈后)MOV A,R2RLC A ;带进位左移1位(形成下一行扫描字,再次扫描)MOV R2,AMOV A,R0;把加1后的行计数器R0和总共扫描次数(4次比较)CJNE A,#04H,SKEY2 ;(扫描完了么)书本上这个地方也有错误,书本上写的是:SKEY1AJMP EKEY ;如果没有的话,退出;有键按下后行扫描过后,此为确列行SKEY3: MOV A,R1 ;JNB ACC.4,SKEY5 ;直接寻址位为0咋转移指令JNB ACC.5,SKEY6JNB ACC.6,SKEY7JNB ACC.7,SKEY8AJMP EKEY //我自己感觉到这命令没有用处SKEY5: MOV A,#00H ;存0列号MOV R3,AAJMP DKEYSKEY6: MOV A,#01H ;存1列号MOV R3,AAJMP DKEYSKEY7: MOV A,#02H ;存2列号MOV R3,AAJMP DKEYSKEY8: MOV A,#03H ;存3列号MOV R3,AAJMP DKEY;取出具体的行号,再加上列号,最终确认按键的号码DKEY: //MOV R4,#00HMOV A,R0MOV B,#04HMUL AB ;让行号*4,第四位放在A中(总共就4行,相乘后一定<16,也就是只有第四位有值)ADD A,R3 ;让行号和列号相加,最终确认任按键的具体号MOV R4,AEKEY: POP ACCPOP PSWRET ;按键扫描处理函数DEL20ms:MOV R7,#2DL2: MOV R6,#18DL1: MOV R5,#255DJNZ R5,$DJNZ R6,DL1DJNZ R7,DL2RET;此为共阴极数码管的数字表TABLE: DB 3FH ;0DB 06H ;1DB 5BH ;2DB 4FH ;3DB 66H ;4DB 6DH ;5DB 7DH ;6DB 27H ;7DB 7FH ;8DB 6FH ;9DB 77HDB 7CHDB 39HDB 5EHDB 79HDB 71HEND第三种PIC单片机键盘扫描汇编程序;本程序用于PIC外接键盘的识别,通过汇编程序,使按下K1键时第一个数码管显示1,按下K2键时第一;个数码管上显示2,按下K3键时第一个数码管上显示3,按下K4键时第一个数码管上显示4,;汇编程序对键盘的扫描采用查询方式LIST P=18F458INCLUDE "P18F458.INC";所用的寄存器JIANR EQU 0X20FLAG EQU JIANR+1 ;标志寄存器DEYH EQU JIANR+2DEYL EQU JIANR+3F0 EQU 0 ;FLAG的第0位定义为F0ORG 0X00GOTO MAINORG 0X30;*************以下为键盘码值转换表****************** CONVERT ADDWF PCL,1RETLW 0XC0 ;0,显示段码与具体的硬件连接有关RETLW 0XF9 ;1RETLW 0XA4 ;2RETLW 0XB0 ;3RETLW 0X99 ;4RETLW 0X92 ;5RETLW 0X82 ;6RETLW 0XD8 ;7RETLW 0X80 ;8RETLW 0X90 ;9RETLW 0X88 ;ARETLW 0X83 ;BRETLW 0XC6 ;CRETLW 0XA1 ;DRETLW 0X86 ;ERETLW 0X8E ;FRETLW 0X7F ;"."RETLW 0XBF ;"-"RETLW 0X89 ;HRETLW 0XFF ;DARKRETURN;***************PIC键盘扫描汇编程序初始化子程序***************** INITIALBCF TRISA,5 ;置RA5为输出方式,以输出锁存信号BCF TRISB,1BCF TRISA,3BCF TRISE,0BCF TRISE,1BSF TRISB,4 ;设置与键盘有关的各口的输入输出方式BCF TRISC,5BCF TRISC,3 ;设置SCK与SDO为输出方式BCF INTCON,GIE ;关闭所有中断LW 0XC0WF SSPSTAT ;设置SSPSTAT寄存器LW 0X30WF SSPCON1 ;设置SPI的控制方式,允许SSP方式,并且时钟下降;沿发送数据,与"74HC595当其SCLK从低到高电平;跳变时,串行输入数据(DI)移入寄存器"的特点相对应LW 0X01WF JIANR ;显示值寄存器(复用为键值寄存器)赋初值CLRF FLAG ;清除标志寄存器RETURN ;返回;**************显示子程序*****************DISPLAYCLRF PORTAWF SSPBUFAGAINBTFSS PIR1,SSPIFGOTO AGAINNOPBCF PIR1,SSPIFBSF PORTA,5 ;详细的程序语句请参考 pic教程语句部分,可在首页搜索。

51单片机键盘扫描程序7294详细介绍

51单片机键盘扫描程序7294详细介绍

51单片机键盘扫描程序7294详细介绍1. 前言随着人们对电子产品的需求不断增加,微处理器成为现代电子设备中必不可少的一个组成部分。

其中,单片机作为一种嵌入式微处理器,由于其功能强大、价格低廉和易于编程等优点,被广泛应用于各个领域。

在单片机应用中,键盘扫描技术是常见的一种应用技术。

它既可以用于普通键盘,也可以用于定制键盘或遥控器等输入设备。

在51单片机中,键盘扫描程序7294是最为常用和经典的键盘扫描程序之一。

本文将详细介绍7294程序的原理、功能和实现方法。

2. 概述7294程序是一种基于矩阵扫描的键盘输入程序,也称为键盘扫描程序。

该程序主要由两个部分组成,即扫描部分和解码部分。

扫描部分是通过读取每个行端口和列端口的状态,得出当前按下的键位信息。

在实现过程中,通常采用交错式扫描,即先扫描行端口再扫描列端口。

这种方式可以避免多个键同时按下时无法识别的情况。

解码部分负责将扫描部分得到的行列矩阵转换成对应的键位信息。

这里我们可以采用查表法或者位运算法来实现。

3. 原理主要原理7294程序的主要工作原理如下:(1)行列扫描首先,程序将所有行端口设为输出,所有列端口设为输入。

接着,程序对每个行端口进行扫描,每次只将一个行端口输出高电平,同时读取所有列端口的状态。

如果任意一个列端口检测到低电平,说明该列与当前行对应的键被按下,程序将该键位信息保存下来。

反之,如果所有列端口均输出高电平,说明该行无按键按下。

(2)解码当扫描部分输出一个键位矩阵后,解码部分即开始工作。

首先,程序将每个键位的状态 (按下或放开)保存到一个矩阵中。

接着,程序通过查表法或者位运算法将该矩阵转换成对应的键位信息,然后提交给主程序进行后续处理。

4. 具体实现为了更好地理解7294程序的实现步骤,我们这里以4x4矩阵键盘为例展示其具体实现过程。

(1)硬件连接首先,将4个行端口 (行1~行4)和4个列端口 (列1~列4)分别连接到51单片机的IO口,如图所示:(2)扫描过程接着,通过编写程序实现键盘的扫描过程。

51单片机4×4矩阵按键扫描方法

51单片机4×4矩阵按键扫描方法
{
key=0xf0;//低四位为0
if(key==0xf0)//若无变化,证明按键松开
return 0;//返回0
else//否则,按键未松开
return 1;//返回1
}
//*********主函数*********//
int main()
{
key=0xff;//按键初始化
led=0xff;//关闭LED灯
//送至led显示
/*
eg:如果是第三行第二列按键按下
则第3个、第6(2列+4)个LED灯亮
如下图所示(Proteus仿真电路图)
*/
}
}
led_arry[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//数组定义,便于显示
//******检测是否有按键按下*****//
uchar Check_Button()
{
key=0x0f;//高四位为0
if(key==0x0f)//若无变化,证明无按键按下
return 0;//返回0
else//否则
return 1;//返回1
}
//********行检测********//
uchar Line[]={0x0e,0x0d,0x0b,0x07}; //那个按键按下,检测出的状态则对应数组中的第几个数
void Check_Line()
{
uchar i;
key=0x0f;//高四位为0
/*****4×4按键扫描******/
/***编程要点
1.首先检测是否有按键按下
2.若有按键按下,即进行行检测,列检测
3.行检测:高4位设为0,低4位为1,进行检测0x0f

51单片机数码管显示及矩阵键盘扫描程序

51单片机数码管显示及矩阵键盘扫描程序

51单片机数码管显示及矩阵键盘扫描程序硬件实验十一八段数码管实验一、实验任务1、在静态数码管上轮流显示数字0-9。

2、在两个4位数码管上动态显示数字0-9二、流程图及程序静态显示:流程图:程序代码:#include#define uchar unsigned chucharcodevalue[10]={0xC0,0xF9,0xA4,0xB0,0X99,0x92,0x82,0xF8,0 x80,0x90};//0 -9数码管显示段码void delay(char x) //延时子程序{uchar i;for(i=0;i<200;i++);}main() //主函数{int i;while(1){for(i=0;i<10;i++) //显示0-9{P0=codevalue[i];delay(500); //延时1秒}}}动态显示:#include#includetab1[]={0x3f,0x06,0x5b,0x4f,0x66,0x6D,0x7D,0x07,0x7f,0x6f}; //数码管显示数字字段unsigned char tab2[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//片选字段unsigned char i,k,j,x;void delay(x); //声明延时子函数void main() //主函数{while(1){for(i=0;i<8;i++) //显示0-7{ P1=tab1[i];P0=tab2[i];delay(5); //延时}P1=tab1[8]; P0=tab2[0]; delay(5); //显示8-9P1=tab1[9]; P0=tab2[1]; delay(5);}}void delay(x) //延时函数定义{do{for(j=0;j<250;j++)for(k=0;k<250;k++);}}硬件实验十二矩阵键盘扫描显示一、实验任务1、把矩阵键盘上的按键输入的键码在静态数码管上显示出来。

51单片机的矩阵按键扫描的设计C语言程序

51单片机的矩阵按键扫描的设计C语言程序

#include <reg51.h>#define KEY P1// ----------------------- 变量声明-------------------------------------------------------------------- void program_SCANkey(); // 程序扫描键盘 ,供主程序调用void delay(unsigned int N) ;// 延时子程序,实现 (16*N+24)us 的延时bitjudge_hitkey();// 判断是否有键按下,有返回 1,没 有返回 0void key_manage(unsigned char keycode); //键盘散转////函数名称:program_SCANkey//函数声明,变量定义unsigned char scan_key();表行,低四位代表列 )// 扫描键盘,返回键值 (高四位代void manage_key1(void);// 按键 1 处理程序 void manage_key2(void);// 按键 2 处理程序 void manage_key3(void);// 按键 3 处理程序 void manage_key4(void);// 按键 4 处理程序 //每个按键对应一个处理程序,这里// 函数功能:程序扫描键盘,// 有键按下完成按键处理,无键按下直接返回// -------------------------------------------------------------------------------------------------- void program_SCANkey(){unsigned char key_code;----------------------------------------------------------------- //函数名称: delay //入口参数:N//函数功能:延时子程序,实现(16*N+24)us 的延时// 系统采用11.0592MHz 的时钟时,延时满足要求,其它情况需要改动// --------------------------------------------------------------------------------------------------void delay(unsigned int N){int i;for(i=0;i<N;i++);}// --------------------// 函数名称:system_init()if(judge_hitkey())(1000);if(judge_hitkey())while(judge_hitkey());key_manage(key_code);// ------------------------------// 判断是否有键按下 {delay //延时20ms 左右,消除抖动干扰 //判断是否有效按键 {key_code=scan_key (;) // 等待按键释放 // 键盘扫描、键盘散转、按键处理 }}}// 函数功能:初始化设置// 设定INT0、INT1 及T0、T1的工作方式// --------------------------------------------------------------------------------------------------/* void system」nit(void ){TMOD=0x55;〃定时器1和定时器0工作在方式1,的计数模式TR0=1; //定时器 1 和定时器0开始计数TR1=1;ET0=1; //定时器1 和定时器0中断允许ET1=1;IT1=0; //选择INTO和INT1为电平触发方式IT0=0;EX0=1; //外部中断允许EX1=0;EA=1; // 系统中断允许}// --------------------------------------------------------------// 函数名称:INT0_intrupt// 函数功能:外部中断0 处理程序//void INT0_intrupt() interrupt 0 using 1{EA=0; // 系统中断禁止delay(1000); // 键盘消抖动if(INT_0==0) // 判断是否干扰{ // 的确有健按下while(INT_O==O);〃等待键盘释放delay(1000); //键盘消抖动manage_key1();}EA=1;}*/// -------------------------------------------------------------------------------------------------- // 函数名称:judge_hitkey// 函数功能:// 判断是否有键按下,有返回1,没有返回0// --------------------------------------------------------------------------------------------------bitjudge_hitkey() // 判断是否有键按下,有返回1,没有返回0{unsigned char scancode,keycode;scancode=0xff; //P1.4~P1.7 输出全 1 则无键闭合 KEY=scancode;// 函数名称:scan_key// 函数功能:// 扫描键盘,返回键值 (高四位代表行,低四位代表列 )// ----------------------------- unsignedcharscan_key() // 扫描键盘,返回键值 (高四位代表 行,低四位代表列 ){unsigned char scancode,keycode;scancode=0xef; // 键盘扫描码,采用逐行扫描的方法 while(scancode!=0xff){KEY=scancode; // 输入扫描 码,扫描 P1.4 对应的行keycode=KEY;1.0~P1.3 的状态if(keycode==0xff)return(0);elsereturn(1);// 读 P // 全 1 则无键闭合 //否则有键闭合 }//if((keycode&0x0f)!=0x0f)keycode=~keycode;return(keycode);}// --------------------------------------------------------------------------- // 函数名称:key_manage// 入口参数:keycode 扫描键盘返回的键值 (高四位代表行,低四位代表列 )// 函数功能: 键盘散转// -------------------------------------------------------------------------------------------------- void key_manage(unsigned char keycode){switch(keycode){case 0x11:manage_key1();break;case 0x12: manage_key2();break;case 0x14: manage_key3();break;case 0x18: manage_key4();break;case 0x21:manage_key5();break;case 0x22: manage_key6();break;case 0x24: manage_key7();break;case 0x28: manage_key8();break;keycode=KEY;列键盘被按下// 读出数据,看是否在此行上的某 break; scancode=(keycode<<1)|0x0f;// 扫描到按下的键,则退出// 否则,更新扫描码继续扫描 }case 0x41:manage_key9();break;case 0x42: manage_key10();break;case 0x44: manage_key11();break;case 0x48: manage_key12();break;case 0x81:manage_key13();break;case 0x82: manage_key14();break;case 0x84: manage_key15();break;case 0x88: manage_key16();break;// default:}}// -------------------------------------------------------------------------------------------------- // 函数名称:manage_key1// 函数功能:按键 1 处理程序// -------------------------------------------------------------------------------------------------- void manage_key1(void){}程序扫描键盘,有键按下完成按键处理,无键按下直接返回。

51单片机键盘扫描讲解

51单片机键盘扫描讲解

51单片机键盘扫描讲解单片机键盘扫描程序单片机键盘扫描单片机键盘扫描原理单片机基础知识讲解单片机矩阵键盘单片机矩阵键盘程序单片机矩阵键盘原理单片机键盘单片机44键盘
键盘的应用
1、键盘的分类 键盘分编码键盘和非编码键盘。键盘上 闭合键的识别由专用的硬件编码器实现,并 产生键编码号或键值的称为编码键盘,如计 算机键盘. 而靠软件编程来识别的称为非编码键盘; 在单片机组成的各种系统中,用的最多的是 非编码键盘。也有用到编码键盘的。
K0
P10
K4
0 4 8 C
4
K1
1 5 9 D
P15
K2
2 6 A E
P16
K3
3 7 B F
P17
K5
K6
K7
P11 P12 P13
K8
K9
K10
K11
89C52
E A/VP X1 X2 RE SE T RD WR
K12
K13
K14
K15
1.数码管前三位显示一个跑表,从000到 999之间以1%秒速度运行,当按下一个独 立键盘时跑表停止,松开手后跑表继续运 行。(用定时器设计表)。 在上题的基础上,用另外三个独立键盘实 现按下第一个时计时停止,按下第二个时 计时开始,按下第三个是计数值清零从头 开始。 按下16个矩阵键盘依次在数码管上显示116的平方。如按下第一个显示1,第二个 显示4...
非编码键盘有分为:独立键盘和行列式(又 称为矩阵式)键盘。
按键在闭合和断开时,触点会存在抖动现象:
+5V
无抖动
理想波形 A 实际波形
按下抖动
B 稳定闭合
释放抖动
+5V
有抖动
U1

C51单片机矩阵键盘扫描去抖程序

C51单片机矩阵键盘扫描去抖程序

C51单片机矩阵键盘扫描去抖程序最近有一个C51的项目,用的是新华龙的C51 F020单片机。

项目中要实现4*5的矩阵键盘。

矩阵电路图如下如示其中,四条列线接在F020的P2~P5口线上,5条行线接在P5口线上(F020的P5口是不同于普通C51的扩展接口,不能位寻址)。

同时4条列线接在一四输入与非门(74LS20)上,门输出接F020的外中断1,这样,任何一键按下,都会产生中断,通知程序进行键盘扫描。

托一个新手给写了键盘的扫描程序,基本功能都能实现,但对于键盘的去抖处理总是做不好,表现是或者不能去抖,或者按键响应过慢,或者采集到错误键值。

看来新手对于矩阵键盘扫描原理掌握较好(网上资料多),但对于键盘去抖的知识却有所欠缺,基本都是按照书上说的延时一段时间再采集键值,实际应用中,这样的处理是远远不够的,过于简单。

实际去抖处理应该这样进行更合理一些,即连续采集键值,当采集到的键值在一段时间内是相同的,即认为按键状态已稳定,此键值为真实键值。

另外,按键释放时,也会有抖动,导致误采键值,因此在键释放时,也应进行去抖处理,处理方法同时是连续一段时间采集到无键按下状态,才认为按键被释放。

根据这个方法,我重写了新手的程序,实际应用中表现极好。

现将程序公布如下,供新手参考。

Key.h文件内容#ifndef __key_H__#define __key_H__#define NULL_KEY 0x0000#define S1 0x3801#define S2 0x3401#define S3 0x3802#define S4 0x3402#define S5 0x3804#define S6 0x3404#define S7 0x3808#define S8 0x3408#define S9 0x3810#define S10 0x3410#define S11 0x2C01#define S12 0x1C01#define S13 0x2C02#define S14 0x1C02#define S15 0x2C04#define S16 0x1C04#define S17 0x2C08#define S18 0x1C08#define S19 0x2C10#define S20 0x1C10#define KEY_DELAY 20extern unsigned int Key_Value;extern void Init_Key();extern void Scan_Key();extern bit Key_Pressed;extern bit Key_Released;extern unsigned int idata Keypress_Count;extern unsigned int idata Keyrelease_Count;#endifkey.c 文件内容#include <string.h>#include "key.h"bit Key_Down; //是否有键按下的标志unsigned int idata Keypress_Count;sbit Col_Key0 = P2^2;sbit Col_Key1 = P2^3;sbit Col_Key2 = P2^4;sbit Col_Key3 = P2^5;bit Key_Pressed;bit Key_Released;unsigned int Key_Value;bit Key_Down; //是否有键按下的标志unsigned int idata Keypress_Count; //一毫秒增加一次的变量unsigned int idata Keyrelease_Count; //一毫秒增加一次的变量//矩阵键盘使用中断1作为键盘中断void Init_Key(){P5 = 0; //行线全部置为0EX1 = 1; // 允许外部时钟秒中断IT1 = 1; // 外部时钟中断设置为边沿触发}void Key_Int() interrupt 2{Key_Pressed = 1;EX1 = 0;}void Scan_Key(){unsigned char temp,rowvalue;unsigned int key;int i;temp = P2;temp &= 0x3C;if(temp == 0x3C){Key_Released = 0;Key_Pressed = 0;key = NULL_KEY;EX1 = 1;}else{key = temp;key = key<<8;rowvalue = 0x01;for(i=0;i<5;i++){P5 = rowvalue<<i;DelayMs(1);temp = P2;temp &= 0x3C;if(temp == 0x3c){rowvalue = rowvalue<<i;key = key | rowvalue;P5 = 0x00;break;}}P5 = 0x00;DelayMs(1);}if(key!=NULL_KEY) //如果有键按下{if(key==Key_Value) //如果按下的是相同的键{if(Keypress_Count>=KEY_DELAY){Key_Down = 1;}}else if(Key_Down != 1){Keypress_Count=0;Keyrelease_Count = 0;Key_Value=key;}}else //如果无键按下{if(Key_Down) //如果当前是键释放,返回键值{if(Keyrelease_Count >= KEY_DELAY){Key_Down=0;Keypress_Count=0;Keyrelease_Count=0;Key_Released = 1;EX1 = 1;return;}}else{Keypress_Count=0;Keyrelease_Count=0;Key_Value = NULL_KEY;EX1 = 1;return;}}}在main.c中的调用方法为if(Key_Pressed == 1){//Key_Pressed = 0;Scan_Key();}if(Key_Released == 1){Key_Released = 0;Ack_Key();}其中Ack_Key()函数为具体的键盘响应程序,就不列出了。

51单片机的矩阵按键扫描的设计C语言程序

51单片机的矩阵按键扫描的设计C语言程序

51单片机的矩阵按键扫描的设计C语言程序以下为一个基于51单片机的矩阵按键扫描的设计C语言程序:```c#include <reg51.h>//定义端口连接到矩阵键盘sbit col1 = P2^0;sbit col2 = P2^1;sbit col3 = P2^2;sbit row1 = P2^3;sbit row2 = P2^4;sbit row3 = P2^5;sbit row4 = P2^6;//声明按键函数char read_keypad(;void maiwhile (1)char key = read_keypad(; // 读取按键值//根据按键值进行相应操作switch(key)case '1'://第一行第一列按键逻辑//在此处添加相应的代码break;case '2'://第一行第二列按键逻辑//在此处添加相应的代码break;//继续处理其他按键//...default://未识别到按键break;}}//按键扫描函数char read_keypacol1 = 0; col2 = 1; col3 = 1; // 激活第一列if (row1 == 0) { // 第一行第一列按键被按下while (row1 == 0); //等待按键释放return '1'; // 返回按键值}if (row2 == 0) { // 第二行第一列按键被按下while (row2 == 0); //等待按键释放return '4'; // 返回按键值}if (row3 == 0) { // 第三行第一列按键被按下while (row3 == 0); //等待按键释放return '7'; // 返回按键值}if (row4 == 0) { // 第四行第一列按键被按下while (row4 == 0); //等待按键释放return '*'; // 返回按键值}col1 = 1; col2 = 0; col3 = 1; // 激活第二列//处理第二列的按键逻辑//...col1 = 1; col2 = 1; col3 = 0; // 激活第三列//处理第三列的按键逻辑//...return '\0'; // 返回空字符表示未检测到按键```以上代码中,我们使用51单片机的P2端口连接到矩阵键盘的列和行,通过扫描不同的列和检测行的状态来判断按键是否被按下。

51单片机的键盘扫描程序

51单片机的键盘扫描程序

一个51单片机的键盘扫描程序,算法简单有效/****************************************键盘_不采用定时器_不延时特点:按键在松手后有效,灵敏度高,消耗资源少,运行效率高独立键盘为:K01=P2^4;K02=P2^5;K03=P2^6;K04=P2^7;矩阵键盘为:行(上到下)_P2.3_P2.2_P2.1_P2.0列(左到右)_P2.7_P2.6_P2.5_P2.4提供的操作函数://独立键盘.无按键动作时其返回值num_key=0,否则返回按键号num_keyextern unsigned char keyboard_self();//矩阵键盘.无按键动作时其返回值num_key=0,否则返回按键号num_key****检测高四位extern unsigned char keyboard_matrix();****************************************/先看独立键盘(和矩阵键盘的算法一样)-----------------------------------------------------------------------#include<reg52.h>#include<intrins.h>//独立键盘.无按键动作时其返回值num_key=0,否则返回按键号num_keyextern unsigned char keyboard_self(){unsigned char num_key=0;//按键号unsigned char temp=0;//用于读取P2线上按键值static unsigned char temp_code=0;//保存按键值static unsigned char num_check=0;//低电平有效次数static unsigned char key_flag=0;//按键有效标识temp=P2&0xF0;//读取P2线数据if(temp!=0xF0)//低电平判断{num_check++;if(num_check==10)//连续10次(10ms)低电平有效,则认为按键有效{key_flag=1;//使能按键有效标识temp_code=temp;//保存按键值}}else//松手时判断{num_check=0;if(key_flag==1)//按键有效{key_flag=0;switch(temp_code)//读取按键号{case 0xE0: num_key=1;break;case 0xD0: num_key=2;break;case 0xB0: num_key=3;break;case 0x70: num_key=4;break;}}}return(num_key);}现在是矩阵键盘的-----------------------------------------------------------------------#include<reg52.h>#include<intrins.h>//矩阵键盘.无按键动作时其返回值num_key=0,否则返回按键号num_key****检测高四位extern unsigned char keyboard_matrix(){unsigned char num_key=0;//按键号unsigned char temp=0;//读取P2口线数据static unsigned char temp_code=0;//用于保存按键值static unsigned char temp_circle=0xFE;//保存P2线上的循环扫描值static unsigned char num_check=0;//低电平计数static unsigned char key_flag=0;//按键有效标识P2=temp_circle;//0xFXtemp=P2;//读取P2口线数据if(temp!=temp_circle)//有按键动作{num_check++;//低电平计数|逢低电平加1if(num_check==10)//连续10次(10ms)低电平有效{key_flag=1;//按键有效标识置1temp_code=temp;//保存按键值}}else//松手OR无按键动作,此时应该改变扫描线{num_check=0;if(key_flag==1)//按键有效判断{key_flag=0;switch(temp_code)//读取按键号{//P2^0线case 0xEE: num_key=1;break;case 0xDE: num_key=2;break;case 0xBE: num_key=3;break;case 0x7E: num_key=4;break;//P2^1线case 0xED: num_key=5;break;case 0xDD: num_key=6;break;case 0xBD: num_key=7;break;case 0x7D: num_key=8;break;//P2^2线case 0xEB: num_key=9;break;case 0xDB: num_key=10;break;case 0xBB: num_key=11;break;case 0x7B: num_key=12;break;//P2^3线case 0xE7: num_key=13;break;case 0xD7: num_key=14;break;case 0xB7: num_key=15;break;case 0x77: num_key=16;break;}}temp_circle=_crol_(temp_circle,1);//改变扫描线if(temp_circle==0xEF){temp_circle=0xFE;}}return(num_key);//返回按键号}/************************************************************************* 未按键时,扫描线一直变化。

基于51单片机矩阵键盘程序

基于51单片机矩阵键盘程序
{
j=0;
for(k=0;k{
P3=table[k];//P3接有一排指示灯
delay (1000);//延时1S
}
}
}
}
主程序2:
main(){
int i,j,a[2][5]={10,15,25,15,75,15,45,65,85,95};
for(i=0;ifor(j=0;jprintf(“%d“,a[i][j]);
}
printf(“\n”);
}
主程序3:
由键盘输入一个3×4矩阵a,选出各列最小的元素组成一个一维数组b并输

由键盘输入一个3×4矩阵a,选出各列最小的元素组成一个一维数组b并输

#include“stdio.h”
#include“conio.h”
void main()
{
int i,j,a[3][4],b[4],min;
基于51单片机矩阵键盘程序
主程序1:
void main(){uch来自r i,j,ki=0;
j=0;
while(1)
{
i=key();//键盘循环扫描,其值赋给变量数组table
if(i!=0)//键盘子程序返回值非0,即有按键按下
{
table[j]=i;//将值存在变量数组中
j++;
}
if(j==6)
for(i=0;ifor(j=0;jscanf(“%d”,&a[i][j]);
for(i=0;ib[i]=a[0][i];
for(i=0;ifor(j=1;jif(a[i][j]for(i=0;iprintf(“%d”,b[i]);
getch();
}

4×4矩阵键盘51单片机识别实验与程序

4×4矩阵键盘51单片机识别实验与程序

4×4矩阵键盘51单片机识别实验与程序1.实验任务如图所示,用AT89S51的并行口P1接4×4矩阵键盘,以-作输入线,以-作输出线;在数码管上显示每个按键的“0-F”序号。

对应的按键的序号排列如图所示图2.硬件电路原理图图3.系统板上硬件连线(1.把“单片机系统“区域中的-端口用8芯排线连接到“4X4行列式键盘”区域中的C1-C4 R1-R4端口上;(2.把“单片机系统”区域中的AD0-AD7端口用8芯排线连接到“四路静态数码显示模块”区域中的任一个a-h端口上;要求:AD0对应着a,AD1对应着b,……,AD7对应着h。

4.程序设计内容(1.4×4矩阵键盘识别处理(2.每个按键有它的行值和列值,行值和列值的组合就是识别这个按键的编码。

矩阵的行线和列线分别通过两并行接口和CPU通信。

每个按键的状态同样需变成数字量“0”和“1”,开关的一端(列线)通过电阻接VCC,而接地是通过程序输出数字“0”实现的。

键盘处理程序的任务是:确定有无键按下,判断哪一个键按下,键的功能是什么;还要消除按键在闭合或断开时的抖动。

两个并行口中,一个输出扫描码,使按键逐行动态接地,另一个并行口输入按键状态,由行扫描值和回馈信号共同形成键编码而识别按键,通过软件查表,查出该键的功能。

5.程序框图图C语言源程序#include <>unsigned char code table[]={0x3f,0x06,0x5b,0x4f, 0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};unsigned char temp;unsigned char key; unsigned char i,j;void main(void) {while(1){P3=0xff;P3_4=0;temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {for(i=50;i>0;i--)for(j=200;j>0;j--); temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {temp=P3;temp=temp & 0x0f; switch(temp){case 0x0e:key=7;break;case 0x0d:key=8;break;case 0x0b:key=9;break;case 0x07:key=10;break;}temp=P3;P1_0=~P1_0;P0=table[key]; temp=temp & 0x0f; while(temp!=0x0f) {temp=P3;temp=temp & 0x0f; }}}P3=0xff;P3_5=0;temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {for(i=50;i>0;i--)for(j=200;j>0;j--); temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {temp=P3;temp=temp & 0x0f; switch(temp){case 0x0e:key=4;break;case 0x0d:key=5;break;case 0x0b:key=6;break;case 0x07:key=11;break;}temp=P3;P1_0=~P1_0;P0=table[key]; temp=temp & 0x0f; while(temp!=0x0f) {temp=P3;temp=temp & 0x0f; }}}P3=0xff;P3_6=0;temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {for(i=50;i>0;i--)for(j=200;j>0;j--); temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {temp=P3;temp=temp & 0x0f; switch(temp){case 0x0e:key=1;break;case 0x0d:key=2;break;case 0x0b:key=3;break;case 0x07:key=12;break;}temp=P3;P1_0=~P1_0;P0=table[key]; temp=temp & 0x0f; while(temp!=0x0f) {temp=P3;temp=temp & 0x0f; }}}P3=0xff;P3_7=0;temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {for(i=50;i>0;i--)for(j=200;j>0;j--); temp=P3;temp=temp & 0x0f; if (temp!=0x0f) {temp=P3;temp=temp & 0x0f; switch(temp){case 0x0e:key=0;break;case 0x0d:key=13;break;case 0x0b:key=14;break;case 0x07:key=15;break;}temp=P3;P1_0=~P1_0;P0=table[key]; temp=temp & 0x0f; while(temp!=0x0f) {temp=P3;temp=temp & 0x0f;} } } } }。

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

/* ---------------------------------------------名称:矩阵键盘依次输入控制使用行列逐级扫描论坛:编写:shifang日期:2009.5修改:无内容:如计算器输入数据形式相同从右至左使用行列扫描方法 */#include<reg52.h> // 包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#define DataPort P0 〃定义数据端口程序中遇到DataPort则用P0替换#define KeyPortP1sbit LATC H仁P2八2;/定义锁存使能端口段锁存sbit LATCH2=P2A3;/位锁存unsigned char codedofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71};/显示段码值0~Fun sig nedcharcodedofly_WeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};〃分别对应相应的数码管点亮,即位码unsigned char TempData[8]; //存储显示值的全局变量void DelayUs2x(unsigned char t);//us 级延时函数声明void DelayMs(unsigned char t); //ms 级延时void Display (un sig ned char FirstBit, un sig ned char Num);/数码管显示函数un sig ned char KeySca n(v oid);/键盘扫描unsigned char KeyPro(void);void Init_Timer0(void);// 定时器初始化/* -----------------------------------------------主函数----------------------------------------------- */void main (void){unsigned char num,i,j;unsigned char temp[8];Init_Timer0();while(1)// 主循环{num=KeyPro(); if(num!=0xff){if(i<8){temp[i]=dofly_DuanMa[num];for(j=0;j<=i;j++)TempData[7-i+j]=temp[j];}i++;if(i==9)〃多出一个按键输入为了清屏原本应该为8{i=0;for(j=0;j<8;j++)〃清屏TempData[j]=0;}}//Display(0,8); // 显示全部8 位// 主循环中添加其他需要一直工作的程序}}/* -----------------------------------------------uS延时函数,含有输入参数un sig ned char t,无返回值un sig ned char是定义无符号字符变量,其值的范围是0~255这里使用晶振12M,精确延时请使用汇编,大致延时长度如下T=tx2+5 uS ----------------- */void DelayUs2x(unsigned char t){while(--t);}/* -------------------- mS延时函数,含有输入参数un sig ned char t,无返回值un sig ned char是定义无符号字符变量,其值的范围是0~255这里使用晶振12M,精确延时请使用汇编----------------------------------------------- */void DelayMs(unsigned char t){while(t--){//大致延时1mS DelayUs2x(245);DelayUs2x(245);}}/* -----------------------------------------------显示函数,用于动态扫描数码管输入参数FirstBit 表示需要显示的第一位,如赋值 2 表示从第三个数码管开始显示如输入0 表示从第一个显示。

Num 表示需要显示的位数,如需要显示99 两位数值则该值输入2 */void Display(unsigned char FirstBit,unsigned char Num){static unsigned char i=0;DataPort=0;// 清空数据,防止有交替重影LATCH仁1;/段锁存LATCH1=0;DataPort=dofly_WeiMa[i+FirstBit]; // 取位码LATCH2=1;/位锁存LATCH2=0;DataPort=TempData[i]; //取显示数据,段码LATCH仁1;/段锁存LATCH1=0;i++;if(i==Num)i=0;}/* ------------------------------------------------定时器初始化子程序------------------- */void Init_Timer0(void){TMOD |= 0x01 ;//使用模式1 ,1 6位定时器,使用"|" 符号可以在使用多个定时器时不受影响〃THO=OxOO;〃给定初值//TL0=0x00;EA=1;〃总中断打开ET0=1;〃定时器中断打开TR0=1;〃定时器开关打开}/* -----------------------------------------------定时器中断子程序----------------------------------------------- */void TimerO_isr(void) interrupt 1{TH0=(65536-2000)/256;〃重新赋值2msTL0=(65536-2000)%256;Display(0,8);〃调用数码管扫描}/* ------------------------------------------------按键扫描函数,返回扫描键值----------------------------------------------- */un sig ned char KeySca n(void)/键盘扫描函数,使用行列逐级扫描法{un sig ned char Val;KeyPort=OxfO;〃高四位置高,低四位拉低if(KeyPort!=OxfO)〃表示有按键按下{DelayMs(10);//去抖if(KeyPort!=0xf0){//表示有按键按下KeyPort=0xfe; //检测第一行if(KeyPort!=0xfe){Val=KeyPort&0xf0;Val+=0x0e;while(KeyPort!=0xfe);DelayMs(10); //去抖while(KeyPort!=0xfe);return Val;}KeyPort=0xfd; // 检测第二行if(KeyPort!=0xfd){Val=KeyPort&0xf0; Val+=0x0d;while(KeyPort!=0xfd);DelayMs(10); //去抖while(KeyPort!=0xfd);return Val;}KeyPort=0xfb; // 检测第三行if(KeyPort!=0xfb){Val=KeyPort&0xf0; Val+=0x0b;while(KeyPort!=0xfb);DelayMs(10); //去抖while(KeyPort!=0xfb);return Val;}KeyPort=0xf7; // 检测第四行if(KeyPort!=0xf7){Val=KeyPort&0xf0; Val+=0x07;while(KeyPort!=0xf7);DelayMs(10); //去抖while(KeyPort!=0xf7);return Val;}}}return 0xff;}/* ------------------------------------------- 按键值处理函数,返回扫键值------------------------------------------------ */unsigned char KeyPro(void){switch(KeyScan()){case 0x7e: return 0;break;//0 按下相应的键显示相对应的码值case 0x7d:return 1;break;//1case 0x7b:return 2;break;//2case 0x77:return 3;break;//3case 0xbe:return 4;break;//4case 0xbd:return 5;break;//5case 0xbb:return 6;break;//6case 0xb7:return 7;break;//7case 0xde:return 8;break;//8case 0xdd:return 9;break;//9case 0xdb:return 10;break;//acase 0xd7:return 11;break;//bcase 0xee:return 12;break;//ccase 0xed:return 13;break;//dcase 0xeb:return 14;break;//ecase 0xe7:return 15;break;//f default: return 0xff;break;}}。

相关文档
最新文档