51单片机的键盘扫描程序,算法简单有效

合集下载

单片机键盘扫描程序(汇编)

单片机键盘扫描程序(汇编)
;这一段只是验证有键按下,并不能判断是哪一行
MOV R7,#0FFH ;设置计数常数,作为延时
KEY1: DJNZ R7,KEY1
MOV A,P1 ;读取P1口的列值
ANL A,#0F0H ;判别有键值按下吗(当有键按下时,P1口的高四位就不全为1了,底四位还是都为0的)
MOV P2,A
SJMP LOOP
;子程序内容 ,P1口的第四位为行线,高四位为列线
KEY: PUSH PSW
PUSH ACC
MOV P1,#0F0H ;令所有的行为低电平,全扫描字-P1.0-P1.3,列为输入方式
AJMP DKEY
;取出具体的行号,再加上列号,最终确认按键的号码
DKEY: MOV R4,#00H
MOV A,R0
MOV B,#04H
MUL AB ;让行号*4,第四位放在A中(总共就4行,相乘后一定<16,也就是只有第四位有值)
DB 79H
DB 71H
END
LCALL DEL20ms ;有键按下,进行处理
;下面进行行行扫描,1行1行扫
SKEY: MOV A,#00H
MOV R0,A ;R0作为行计数器,开始初值为0
MOV R1,A ;R1作为列计数器,开始初值为0
;单片机键盘扫描程序(汇编)
;键盘扫描程序;此程序比较复杂,不过如果你坚持的理解下去的话,还是能够理解的,比较经典
;最终是按键的值输出到数码管中(接在P2口)
ORG 0000H
START: MOV R0,#00H ;初始化程序,开始的延时是为了使硬件能够准备好
;有键按下后行扫描过后,此为确列行

实验四 单片机按键扫描编程

实验四 单片机按键扫描编程

仲恺农业工程学院实验报告纸信息科学与技术学院(院、系)电子信息工程专业通信161 班单片机原理及接口技术课实验四单片机按键扫描编程一、实验目的1、掌握单片机按键扫描的工作方式;2、掌握单片机按键扫描的编程方法。

二、实验内容1、学习单片机按键扫描的工作方式;2、扫描按键,控制LED灯实现闪烁和停止闪烁两种状态的切换。

基本要求:用按键Key1控制,按一下Key1,控制LED灯闪烁和停止闪烁的切换。

提高要求:用按键Key1,Key2控制,按一下Key1,控制LED灯闪烁;按一下Key2,控制LED灯常亮。

当LED灯闪烁时,按Key1,灯状态不变;当LED灯常亮时,按Key2,灯状态不变。

可考虑用无延时按键扫描的方式实现。

三、实验设备1、STC单片机开发板;2、PC机以及串口线。

四、实验分析及关键代码#include<reg51.h>#include <intrins.h>#define uchar unsigned charuchar counter=0;sbit KEY1=P2^6; //按下,值为0sbit LEDG=P2^5;void delay_10ms(void) //10ms延时函数{unsigned char i,j;for(j=0;j<10;j++){for (i=0;i<250;i++)_nop_();}}void timer()interrupt 1 using 1 //定时器1方式1,采用中断方式{TH0=(65536-50000)/256;TL0=(65536-50000)%256; //重置初值counter++;if(counter==10){LEDG=!LEDG; //LEDG取反改变灯的状态counter=0;}}void main(){TMOD=0X21;EA=1;ET0=1;TR0=1; //启动T/C0开始定时while(1){if(!KEY1){ delay_10ms();if(!KEY1){while(!KEY1);delay_10ms();TR0=!TR0; //执行按键任务LEDG=0;}}}实验分析:主函数分析:1.计时器初始化 2.进入while循环延时按键扫描,如果KEY1=0(按下),进行按键延时,再判断KEY1是否=0,=0再进行按键延时,然后定时器启动取反(既每次按下定时器依次启动或中断),使LEDG 灯定义亮。

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单片机使用状态机的键盘程序

51单片机使用状态机的键盘程序
break;
}
default://其它
{
step = _Key1_up;//单键抬起消抖
#define Key_Down 0x3D //下箭头
#define Key_Add 0x3B //加
#define Key_Sub 0x37 //减
#define Key_Enter 0x2F //回车
传入参数:无
返回参数:无
设 计:莫汉伟 amo73@
修改日期:2007-10-12
备 注:详细功能和处理算法请参照本文件相关的流程图和文档
**************************************************************************/
#define KeyBuffLen 8 //定义键值环形缓冲区长度为8(缓冲区大小可自由定义,只要大于0即可)
//定义一个键盘缓冲区结构体
struct Struct_KeyBoardBuff
{
u8 buff[KeyBuffLen];//键值环形缓冲区
u8 in; //写键值指示(定时器中断写)
u8 Read_Key(void)
{
u8 Value;
if(Key.out != Key.in)
{
Value=Key.buff[Key.out++];//"读"还没有追上"写",缓冲区有键值,读之
if(Key.out >= KeyBuffLen) //如果"读"跑到了队列尾部,则重新跳回原点
u8 out; //读键值指示(用户读)

单片机矩阵键盘扫描的两种方式

单片机矩阵键盘扫描的两种方式

单片机矩阵键盘扫描的两种方式单片机矩阵键盘扫描的两种方式矩阵键盘扫描方式:第一种:逐行扫描法,就是一行一行的扫描。

实现代码如下(键盘连接P2口):#define NO_KEY 0XFF#define KEY_LO() P2 &= 0XF0#define KEY_HI() P2 |= 0X0F#define KEY_L(i) P2 &= ~(1<<i)#define KEY_RD() ((P2>>4) & 0x0f)UINT8 OnceKey(void){UINT8 line = 0;UINT8 key = NO_KEY;//key valueKEY_LO();if (KEY_RD() == 0X0F){KEY_HI();return NO_KEY;}for (line=0; line<4; line ++){KEY_HI();KEY_L(line);key = KEY_RD();switch (key){case ROW_FIRST:key = 4*line + 0;break;case ROW_SECOND:key = 4*line + 1;break;case ROW_THIRD:key = 4*line + 2;break;case ROW_FOURTH:key = 4*line +3;break;default :key = 0x0f;break;}if (key < 0x10){return key;}}return NO_KEY;}第二种,线性反转法。

就是行和列分别读出。

实现代码如下:#define CVT(i) ((i)==(~1)&0x0f)? 0: ((i)==(~2)&0x0f)? 1: ((i)==(~4)&0x0f)? 2: ((i)==(~8)&0x0f)? 3: 4;#define KEY0_3HI() P2 |= 0X0F#define KEY0_3LO() P2 &= 0XF0#define KEY4_7HI() P2 |= 0XF0#define KEY4_7LO() P2 &= 0X0F#define KEY0_3RD() (P2 & 0X0F)#define KEY4_7RF() ((P2>>4) & 0X0F)UINT8 OnceKey(void){UINT8 line = NO_KEY;UINT8 row = NO_KEY;UINT8 key;KEY0_3HI();KEY4_7LO();line = KEY0_3RD();//读入行的值if (0x0f == line){key = NO_KEY;}else{KEY0_3LO();KEY4_7HI();row = KEY4_7RD();//读入列的值if (0x0f == row){key = NO_KEY;}else{key = CVT(line)*4 + CVT(row);}}KEY0_3HI();KEY4_7HI();return key; }。

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

单片机键盘扫描程序

单片机键盘扫描程序

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

程序不支持双键同时按下,;// 如果发生双键同时按下时,程序将只识别其中先扫描的按键;// 程序入口:void;// 程序出口:KEYNAME,包含按键信息、按键有效信息、当前按键状态;// 编写人:黄伟,2007-12-11;// 最后修改:黄伟,2007-12-12;//;//====================================================================== 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,无须置0 NEXT1:; SETB C ;Acc不等于0FH,则ACC必小于0FH,;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 ;送信号提示时间(每次按键闪100ms) 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单片机键盘扫描汇编程序收录时间:2010-06-19 09:29:12 来源: 作者: 【大中小】点击:20;本程序用于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单片机的键盘扫描程序

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);//返回按键号}/*************************************************************************未按键时,扫描线一直变化。

单片机键盘扫描程序与原理图

单片机键盘扫描程序与原理图

keydown(); //调用按键判断检测程序 P2 = LED7Code[dis_buf%16]&0x7f; P3= LED7Code[dis_buf1%16]&0x7f; //LED7 0x7f为小数点 和共阳此处也是不一样; %16表示输出16进制 d <reg51.h> #define uchar unsigned char //宏的定义变量类型 uchar 代替 unsigned char #define uint unsigned int //宏的定义变量类型 uint 代替 unsigned int uchar dis_buf,dis_buf1; //显示缓存 uchar temp; uchar l,h; //键顺序吗 void delay0(uchar x); //x*0.14MS
// 此表为 LED 的字模 0 1 2 3 4 5 6 7 8 9 a b c d e f unsigned char code LED7Code[] = {~0x3F,~0x06,~0x5B,~0x4F,~0x66,~0x6D,~0x7D,~0x07,~0x7F,~0x6F,~0x77,~0x7C,~0 /************************************************************* * * * 延时子程序 * * * *************************************************************/ void delay(uchar x) { uchar j; while((x--)!=0) //CPU执行x*12次,x=10 { for(j=0;j<125;j++) {;} } } /************************************************************* * * * 键扫描子程序 (4*3 的矩阵) P1.4 P1.5 P1.6 P1.7为行 * * P1.1 P1.2 P1.3为列 * * * *************************************************************/

单片机经典长短按程序

单片机经典长短按程序

新型的按键扫描程序不过我在网上游逛了很久,也看过不少源程序了,没有发现这种按键处理办法的踪迹,所以,我将他共享出来,和广大同僚们共勉。

我非常坚信这种按键处理办法的便捷和高效,你可以移植到任何一种嵌入式处理器上面,因为C语言强大的可移植性。

同时,这里面用到了一些分层的思想,在单片机当中也是相当有用的,也是本文的另外一个重点。

对于老鸟,我建议直接看那两个表达式,然后自己想想就会懂的了,也不需要听我后面的自吹自擂了,我可没有班门弄斧的意思,hoho~~但是对于新手,我建议将全文看完。

因为这是实际项目中总结出来的经验,学校里面学不到的东西。

以下假设你懂C语言,因为纯粹的C语言描述,所以和处理器平台无关,你可以在MCS-51,AVR,PIC,甚至是ARM平台上面测试这个程序性能。

当然,我自己也是在多个项目用过,效果非常好的。

好了,工程人员的习惯,废话就应该少说,开始吧。

以下我以AVR的MEGA8作为平台讲解,没有其它原因,因为我手头上只有AVR的板子而已没有51的。

用51也可以,只是芯片初始化部分不同,还有寄存器名字不同而已。

核心算法:unsigned char Trg;unsigned char Cont;void KeyRead( void ){unsigned char ReadData = PINB^0xff; // 1Trg = ReadData & (ReadData ^ Cont); // 2Cont = ReadData; // 3}完了。

有没有一种不可思议的感觉?当然,没有想懂之前会那样,想懂之后就会惊叹于这算法的精妙!!下面是程序解释:Trg(triger)代表的是触发,Cont(continue)代表的是连续按下。

1:读PORTB的端口数据,取反,然后送到ReadData 临时变量里面保存起来。

2:算法1,用来计算触发变量的。

一个位与操作,一个异或操作,我想学过C 语言都应该懂吧?Trg为全局变量,其它程序可以直接引用。

(原创)51单片机C语言程序设计--速学教程实例(入门篇)之矩阵键盘(逐行扫描法)

(原创)51单片机C语言程序设计--速学教程实例(入门篇)之矩阵键盘(逐行扫描法)

Delay1ms(5); temp=P3; temp=temp&0x0f; if(temp!=0x0f) { temp=P3; switch(temp) { case 0xde:num=9; break; case 0xdd:num=10; break; case 0xdb:num=11; break; case 0xd7:num=12; break; } } } else num=17; P3=0xef; temp=P3; temp=temp&0x0f; if(temp!=0x0f) { Delay1ms(5); temp=P3; temp=temp&0x0f; if(temp!=0x0f) { temp=P3; switch(temp) { case 0xee:num=13; break; case 0xed:num=14; break; case 0xeb:num=15; break; case 0xe7:num=16; break; } }
case 0x7e:num=1; break; case 0x7d:num=2; break; case 0x7b:num=3; break; case 0x77:num=4; break; } } } else num=17; P3=0xbf; temp=P3; temp=temp&0x0f; if(temp!=0x0f) { Delay1ms(5); temp=P3; temp=temp&0x0f; if(temp!=0x0f) { temp=P3; switch(temp) { case 0xbe:num=5; break; case 0xbd:num=6; break; case 0xbb:num=7; break; case 0xb7:num=8; break; } } } else num=17; P3=0xdf; temp=P3; temp=temp&0x0f; if(temp!=0x0f) {

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端口连接到矩阵键盘的列和行,通过扫描不同的列和检测行的状态来判断按键是否被按下。

单片机经典长短按程序

单片机经典长短按程序

单片机经典长短按程序新型的按键扫描程序不过我在网上游逛了很久,也看过不少源程序了,没有发现这种按键处理办法的踪迹,所以,我将他共享出来,和广大同僚们共勉。

我非常坚信这种按键处理办法的便捷和高效,你可以移植到任何一种嵌入式处理器上面,因为C语言强大的可移植性。

同时,这里面用到了一些分层的思想,在单片机当中也是相当有用的,也是本文的另外一个重点。

对于老鸟,我建议直接看那两个表达式,然后自己想想就会懂的了,也不需要听我后面的自吹自擂了,我可没有班门弄斧的意思,hoho~~但是对于新手,我建议将全文看完。

因为这是实际项目中总结出来的经验,学校里面学不到的东西。

以下假设你懂C语言,因为纯粹的C语言描述,所以和处理器平台无关,你可以在MCS-51,AVR,PIC,甚至是ARM平台上面测试这个程序性能。

当然,我自己也是在多个项目用过,效果非常好的。

好了,工程人员的习惯,废话就应该少说,开始吧。

以下我以AVR的MEGA8作为平台讲解,没有其它原因,因为我手头上只有AVR的板子而已没有51的。

用51也可以,只是芯片初始化部分不同,还有寄存器名字不同而已。

核心算法:unignedcharTrg;unignedcharCont;voidKeyRead(void){unignedcharReadData=PINB^0某ff;//1Trg=ReadData&(ReadData^Cont);//2Cont=ReadData;//3}完了。

有没有一种不可思议的感觉?当然,没有想懂之前会那样,想懂之后就会惊叹于这算法的精妙!!下面是程序解释:Trg(triger)代表的是触发,Cont(continue)代表的是连续按下。

1:读PORTB的端口数据,取反,然后送到ReadData临时变量里面保存起来。

2:算法1,用来计算触发变量的。

一个位与操作,一个异或操作,我想学过C语言都应该懂吧?Trg为全局变量,其它程序可以直接引用。

单片机部队式键盘扫描程序

单片机部队式键盘扫描程序

单片机部队式键盘扫描程序单片机部队式键盘扫描程序一、部队扫描法矩阵式键盘的构造与作业原理:在键盘中按键数量较多时,为了削减I/O口的占用,一般将按键摆放成矩阵方法,如图1所示。

在矩阵式键盘中,每条水平线和笔直线在穿插处不直接连通,而是通过一个按键加以联接。

这么,一个端口(如P1口)就能够构成4*4=16个按键,比之直接将端口线用于键盘多出了一倍,并且线数越多,差异越显着,比方再多加一条线就能够构成20键的键盘,而直接用端口线则只能多出一键(9键)。

由此可见,在需求的键数比照多时,选用矩阵法来做键盘是合理的。

矩阵式构造的键盘显着比直接法要杂乱一些,辨认也要杂乱一些,上图中,列线通过电阻接正电源,并将行线所接的单片机的I/O 口作为输出端,而列线所接的I/O口则作为输入。

这么,当按键没有按下时,悉数的输出端都是高电平,代表无键按下。

行线输出是低电平,一旦有键按下,则输入线就会被拉低,这么,通过读入输入线的情况就可得知是不是有键按下了。

详细的辨认及编程方法如下所述。

矩阵式键盘的按键辨认方法断定矩阵式键盘上何键被按下介绍一种行扫描法。

行扫描法行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键辨认方法,如上图所示键盘,介绍进程如下。

差异键盘中有无键按下将悉数行线Y0-Y3置低电平,然后查看列线的情况。

只需有一列的电平为低,则标明键盘中有键被按下,并且闭合的键坐落低电平线与4根行线相穿插的4个按键傍边。

若悉数列线均为高电平,则键盘中无键按下。

差异闭合键地址的方位在供认有键按下后,即可进入断定详细闭合键的进程。

其方法是:顺次将行线置为低电平,即在置某根行线为低电往常,其它线为高电平。

在断定某根行线方位为低电平后,再逐行查看各列线的电平情况。

若某列为低,则该列线与置为低电平的行线穿插处的按键即是闭合的按键。

下面给出一个详细的比方:8031单片机的P1口用作键盘I/O口,键盘的列线接到P1口的低4位,键盘的行线接到P1口的高4位。

51单片机按键扫描程序

51单片机按键扫描程序

51单片机按键扫描程序#include#define uint unsigned int#define uchar unsigned charvoid delay(uint z);sbit LE=P1^4;uchar code table[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6,0xee,0x3e,0x9c,0x7a,0x9e,0x8e};void main(){uchar temp;uint num;while(1){P2=0xfe; //按键扫描第一行temp=P2;temp=temp&0xf0;while(temp!=0xf0){delay(10); //消抖temp=P2;temp=temp&0xf0;while(temp!=0xf0) //再次确认是否有键按下{temp=P2;switch(temp){case 0xee:num=0;break; case 0xde:num=1;break; case 0xbe:num=2;break; case 0x7e:num=3;break;}while(temp!=0xf0) //松手检测{temp=P2;temp=temp&0xf0;}delay(10); //消抖LE=1;P0=table[num];LE=0;P1=0x0f;}}P2=0xfd; //按键扫描第二行temp=P2;temp=temp&0xf0;while(temp!=0xf0){delay(10);temp=P2;temp=temp&0xf0;while(temp!=0xf0){temp=P2;switch(temp){case 0xed:num=4;break; case 0xdd:num=5;break; case 0xbd:num=6;break; case 0x7d:num=7;break; }while(temp!=0xf0){temp=P2;temp=temp&0xf0;}delay(10);LE=1;P0=table[num];LE=0;P1=0x0f;}}P2=0xfb; //按键扫描第三行temp=P2;temp=temp&0xf0; while(temp!=0xf0){delay(10);temp=P2;temp=temp&0xf0; while(temp!=0xf0){temp=P2;switch(temp){case 0xeb:num=8;break; case 0xdb:num=9;break; case 0xbb:num=10;break; case 0x7b:num=11;break; }while(temp!=0xf0){temp=P2;temp=temp&0xf0;}delay(10);LE=1;P0=table[num];LE=0;P1=0x0f;}}P2=0xf7; //按键扫描第四行temp=P2;temp=temp&0xf0; while(temp!=0xf0){delay(10);temp=P2;temp=temp&0xf0;while(temp!=0xf0){temp=P2;switch(temp){case 0xe7:num=12;break; case 0xd7:num=13;break; case 0xb7:num=14;break; case 0x77:num=15;break;}while(temp!=0xf0){temp=P2;temp=temp&0xf0;}delay(10);LE=1;P0=table[num];LE=0;P1=0x0f;}}}}void delay(uint z) //延时子函数{uint x;for(z;z>0;z--)for(x=1000;x>0;x--); }。

单片机按键扫描实验报告

单片机按键扫描实验报告

单片机按键扫描实验报告
实验目的:
通过实验,掌握单片机按键的原理和按键的扫描方法。

实验器材:
1. STC89C52单片机开发板
2. 按键模块
3. 面包板、杜邦线等
实验原理:
单片机按键的原理是通过按键模块接通或断开单片机的某个IO口,从而改变该IO口的电平状态,由单片机检测到电平状态的改变,从而实现对按键的检测和响应。

按键模块一般采用矩阵按键的形式,通过多个IO口设为输出,多个IO口设为输入的方式,实现对多个按键的扫描检测。

按键模块一般会采用行列扫描的方法,即将按键分为多个行和列,按下按键时,某一行和某一列之间接通,从而改变了IO口的电平状态。

实验步骤:
1. 将按键模块连接到单片机开发板的IO口上。

根据按键模块的接口定义将VCC、GND和各个行列引脚分别连接到开发板上。

2. 根据按键模块的引脚定义,编写单片机程序进行按键的扫描。

通过循环检测每个行引脚和每个列引脚之间的电平变化,来判断按键是否被按下。

3. 在程序中可以通过LED等显示设备来显示按键是否被按下的状态。

4. 执行程序,观察按键是否可以正常检测和响应。

实验结果:
实验完成后,观察到按键的检测和响应正常,按下按键时,LED等显示设备可以正确显示按键被按下的状态。

经过实验,掌握了单片机按键的原理和按键的扫描方法,进一步提升了对单片机设备的理解和应用能力。

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

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