单片机按键扫描通用程序(绝对原创)
单片机控制的矩阵键盘扫描程序集

单片机控制的矩阵键盘扫描程序集各种各样的矩阵键盘扫描程序集矩阵键盘的扫描对初学者来说是不可避免的,然而也相对来说有点难度.鉴于此,我整理了一下,我所遇到的矩阵键盘扫描程序集,将相继贴上来,供大家参考! 说明:这些大多都是网上转贴来的,其所有权归原作者!谢谢合作.最简单矩阵键盘扫描程序key:MOV p0,#00001111b;上四位和下四位分别为行和列,所以送出高低电压检查有没有按键按下jmp k10;跳到K10处开始扫描,这里可以改成其它条件转移指令来决定本次扫描是否要继续,例如减1为0转移或者位为1或0才转移,这主要用来增加功能,确认上一按键功能是否完成?是否相当于经过了延时?是否要封锁键盘?goend:jmp kend;如果上面判断本次不执行键盘扫描程序,则立即转到程序尾部,不要浪费CPU的时间k10:jb p0.0,k20;扫描正式开始,先检查列1四个键是否有键按下,如果没有,则跳到K20检查列2k11:MOV p0,#11101111b;列1有键按下时,P0.0变低,到底是那一个键按下?现在分别输出各行低电平jb p0.0,k12;该行的键不按下时,p0.0为高电平,跳到到K12,检查其它的行MOV r1,#1;如果正好是这行的键按下,将寄存器R0写下1,表示1号键按下了k12:MOV p0,#11011111bjb p0.0,k13MOV r1,#2;如果正好是这行的键按下,将寄存器R0写下2,表示2号键按下了k13:MOV p0,#10111111bjb p0.0,k14MOV r1,#3;如果正好是这行的键按下,将寄存器R0写下3,表示3号键按下了k14:MOV p0,#01111111bjb p0.0,kend;如果现在四个键都没有按下,可能按键松开或干扰,退出扫描(以后相同)MOV r1,#4如果正好是这行的键按下,将寄存器R0写下4,表示4号键按下了jmp kend;已经找到按下的键,跳到结尾吧k20:jb p0.1,k30;列2检查为高电平再检查列3、4k21:MOV p0,#11101111b;列2有健按下时,P0.0会变低,到底是那一行的键按下呢?分别输出行的低电平jb p0.1,k22;该行的键不按下时p0.0为高电平,跳到到K22,检查另外三行MOV r1,#5;如果正好是这行的键按下,将寄存器R0写下5,表示5号键按下了(以后相同,不再重复了)k22:MOV p0,#11011111bjb p0.1,k23MOV r1,#6k23:MOV p0,#10111111bjb p0.1,k24MOV r1,#7k24:MOV p0,#01111111bjb p0.1,kendMOV r1,#8jmp kend;已经找到按下的键,跳到结尾吧(以后相同,不要重复了)k30:jb p0.2,k40k31:MOV p0,#11101111bjb p0.2,k32MOV r1,#9k32:MOV p0,#11011111bjb p0.2,k33MOV r1,#10k33:MOV p0,#10111111bjb p0.2,k34MOV r1,#11k34:MOV p0,#01111111bjb p0.2,kendMOV r1,#12jmp kendk40:jb p0.3,kendk41:MOV p0,#11101111bjb p0.3,k42MOV r1,#13k42:MOV p0,#11011111bjb p0.3,k43MOV r1,#14k43:MOV p0,#10111111bjb p0.3,k44MOV r1,#15k44:MOV p0,#01111111bjb p0.3,kendMOV r1,#16kend: ret行列扫描键盘可检测出双键按下#include <reg52.h>#define ulong unsigned long#define uint unsigned int#define uchar unsigned charextern void delay(unsigned int x);unsigned char Tab_key[]= //行列式键盘映射{0x00, //无键按下’’7’’,’’8’’,’’9’’,’’/’’,’’4’’,’’5’’,’’6’’,’’*’’,’’1’’,’’2’’,’’3’’,’’-’’,’’C’’,’’0’’,’’=’’,’’+’’,//下面为按’’C’’同时再按的键:’’7’’,’’8’’,’’9’’,’’/’’,’’4’’,’’5’’,’’6’’,’’*’’,’’1’’,’’2’’,’’3’’,’’-’’,’’0’’,’’=’’,’’+’’,};// P1口行列式键盘//#define KEYPIN_L P1 // 定义键扫描列端口为P1低四位输入//#define KEYPIN_H P1 // 定义键扫描行端口为P1高四位扫描输出//// P1口行列式键盘////公用函数unsigned char KeysCAN(void); // 键扫描函数// //内部私有函数unsigned char fnKeycode(unsigned char key); // 根据键盘映射表输出顺序键值///*// P1口行列式键盘//extern unsigned char KeysCAN(void); // 键扫描函数//*/// P1口行列式键盘////---------------------------------------------------------------------------//unsigned char KeysCAN(void) // 键扫描函数//{unsigned char sccode,recode,keytemp = 0;KEYPIN_L = KEYPIN_L|0x0f; // P1低四位为列线输入//KEYPIN_H = KEYPIN_H&0x0f; // P1高四位为行线发全零扫描码//if ((KEYPIN_L&0x0f) != 0x0f){delay(10); // 延时10 MS 消抖//if ((KEYPIN_L&0x0f) != 0x0f){sccode = 0xef; // 逐行扫描码初值(1110 1111) //while(sccode != 0xff) //将扫描4次,keytemp为每次键值相或的值//{KEYPIN_H = sccode; // 输出行扫描码//if ((KEYPIN_L&0x0f) != 0x0f) // 本行有键按下//{recode = (KEYPIN_L&0x0f)|0xf0; // 只要低位,高位置1 //keytemp |= (~sccode)+(~recode); //特征码(高位为列P3,低位为行KEYPIN_H) //}sccode = (sccode << 1)|0x01; // 扫描码0向高位移动//}}}KEYPIN_H = KEYPIN_H|0xf0;return(fnKeycode(keytemp));}//---------------------------------------------------------------------------//unsigned char fnKeycode(unsigned char key) // 根据键盘映射表输出顺序键值//{switch(key){case 0x11: // 1 键//key = 0x01;break;case 0x21: // 2 键// key = 0x02;break;case 0x41: // 3 键// key = 0x03;break;case 0x81: // 4 键// key = 0x04;break;case 0x12: // 5 键// key = 0x05;break;case 0x22: // 6 键// key = 0x06;break;case 0x42: // 7 键// key = 0x07;break;case 0x82: // 8 键// key = 0x08;break;case 0x14: // 9 键// key = 0x09;break;case 0x24: // 10 键// key = 0x0A;break;case 0x44: // 11 键// key = 0x0B;break;case 0x84: // 12 键// key = 0x0C;break;case 0x18: // 13 键// key = 0x0D;break;case 0x28: // 14 键// key = 0x0E;break;case 0x48: // 15 键// key = 0x0F;break;case 0x88: // 16 键// key = 0x10;break;//以下为功能键//case 0x19: // ’’C’’ +1 键//key = 0x11;break;ca se 0x29: // ’’C’’ +2 键//key = 0x12;break;case 0x49: // ’’C’’ +3 键//key = 0x13;break;case 0x89: // ’’C’’ +4 键//key = 0x14;break;case 0x1A: // ’’C’’ +5 键// key = 0x15;break;case 0x2A: // ’’C’’ +6 键// key = 0x16;break;case 0x4A: // ’’C’’ +7 键// key = 0x17;break;case 0x8A: // ’’C’’ +8 键// key = 0x18;break;case 0x1C: // ’’C’’ +9 键//key = 0x19;break;case 0x2C: // ’’C’’ +10 键// key = 0x1A;break;case 0x4C: // ’’C’’ +11 键// key = 0x1B;break;case 0x8C: // ’’C’’ +12 键// key = 0x1C;break;// case 0x18: // ’’C’’ +13 键// // key = 0x1D;// break;case 0x38: // ’’C’’ +14 键// key = 0x1D;break;case 0x58: // ’’C’’ +15 键// key = 0x1E;break;case 0x98: // ’’C’’ +16 键// key = 0x1F;break;default : // 无键//key = 0x00;break;}return(Tab_key[key]);}矩键查寻键值44程序与显示#include <reg52.h>//#include <math.h>#include <intrins.h>#define uchar unsigned char#define TURE 1#define FALSE 0int key;int del;void Tkey(void);void led(void);/************主程序*************/void main(void){void tkey(void);void led(void);void delay(int);SCON=0x00;TI=0;while(TURE){Tkey();led();delay(2000);}}/********矩键查寻键值4*4程序******/按键为P1.0---P1.7 void Tkey(void){uchar readkey;//rereadkey;uchar x_temp,y_temp;P1=0x0f;x_temp=P1&0x0f;if(x_temp==0x0f) goto keyout;P1=0xf0;y_temp=P1&0xf0;readkey=x_temp|y_temp;readkey=~readkey;switch(readkey){case 0x11:key=0; break;case 0x21:key=1; break;case 0x41:key=2; break;case 0x81:key=3; break;case 0x12:key=4; break;case 0x22:key=5; break;case 0x42:key=6; break;case 0x82:key=7; break;case 0x14:key=8; break;case 0x24:key=9; break;case 0x44:key=10;break;case 0x84:key=11;break;case 0x18:key=12;break;case 0x28:key=13;break;case 0x48:key=14;break;case 0x88:key=15;break;default: key=16;break;}keyout:_nop_();}/************显示程序*************/void led(void){uchar code LEDValue[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; //0-9 uchar data num[6];uchar k;num[0]=0;num[1]=0;num[2]=0;num[3]=0;num[4]=key/10;num[5]=key-(key/10)*10;for(k=0;k<=5;k++){SBUF=LEDValue[num[5-k]];while(TI==0);TI=0;}}/************延时程序*************/void delay(del){for(del;del>0;del--);;伪定义KEYBUF EQU 30H ;键值暂存单元,查表时用;*************************************;* *;* 主程序和中断程序入口*;* *;*************************************ORG 0000H ;程序执行开始地址AJMP MAIN ;跳至MAIN执行;*************************************;* *;* 主程序*;* *;*************************************ORG 0040HMAIN: MOV P1,#0FFHMOV P3,#0FFHLCALL KEYSCAN ;主体程序。
51单片机矩阵键盘行扫描

51单⽚机矩阵键盘⾏扫描————————————————————————————————————————————分类:按结构原理分:触点式开关按键⽆触点开关按键接⼊⽅式独⽴式按键矩阵式键盘————————————————————————————————————————————矩阵式键盘识别⽅法(⾏扫描法)检测列线的状态:列线Y4~Y7置⾼电平,⾏线Y0~Y3置低电平。
只要有⼀列的电平为低,则表⽰键盘该列有⼀个或多个按键被按下。
若所有列线全为⾼电平,则键盘中⽆按键按下。
判断闭合按键所在的位置:⾏线置⾼电平,列线置低电平。
检测⾏线的状态。
举例:当按下第⼀⾏第⼀列的按键时⾏扫描,⾏线为低电平,列线为⾼电平,得到 1110 0000列扫描,⾏线为⾼电平,列线为低电平,得到 0000 1110将得到的结果进⾏或运算,得到 1110 1110,对应第⼀⾏第⼀列,⼗六进制为0xEE按键表⾏列bin hex111110 11100xEE121101 11100xDE131011 11100xBE140111 11100x7E211110 11010xED221101 11010xDD231011 11010xBD240111 11010x7D311110 10110xEB321101 10110xDB331011 10110xBB340111 10110x7B411110 01110xE7421101 01110xD7431011 01110xB7440111 01110x77————————————————————————————————————————————矩阵式键盘应⽤实例实现结果:通过4*4矩阵键盘对应数码管显⽰0~F设计思路:当检测到按键被按下时,将此时⾏扫描的结果存⼊临时变量,再进⾏列扫描,得到的结果和临时变量进⾏或运算。
通过数组存放按键和数码管编码,⾏列扫描得到结果后遍历数组,找到对应的编码位置并显⽰数码管编码实现代码:1 #include <reg52.h>2 typedef unsigned char uchar;3 typedef unsigned int uint;4 uchar code KEY_TABLE[] =5 {60xEE, 0xDE, 0xBE, 0x7E,70xED, 0xDD, 0xBD, 0x7D,80xEB, 0xDB, 0xBB, 0x7B,90xE7, 0xD7, 0xB7, 0x7710 };11 uchar code TABLE[] =12 {130x3F, 0x06, 0x5B, 0x4F,140x66, 0x6D, 0x7D, 0x07,150x7F, 0x6F, 0x77, 0x7C,160x39, 0x5E, 0x79, 0x71,17 };18void Delay(uchar m)19 {20 --m;21 }22void main()23 {24 uchar temp, key, i;25while(1)26 {27 P3 = 0xF0;28if (P3 != 0xF0)29 {30 Delay(2000);31if (P3 != 0xF0)32 {33 temp = P3;34 P3 = 0x0F;35 key = temp | P3;36for (i = 0; i < 16; ++i)37if (key == KEY_TABLE[i])38break;39 P2 = TABLE[i];40 }41 }42 }43 }。
单片机实验--键盘扫描

实验4 键盘实验一、实验目的:1.掌握8255A编程原理。
2.了解键盘电路的工作原理。
3.掌握键盘接口电路的编程方法。
二、实验设备:CPU挂箱、8031CPU模块三、实验原理:1.识别键的闭合,通常采用行扫描法和行反转法。
行扫描法是使键盘上某一行线为低电平,而其余行接高电平,然后读取列值,如所读列值中某位为低电平,表明有键按下,否则扫描下一行,直到扫完所有行。
本实验例程采用的是行反转法。
行反转法识别键闭合时,要将行线接一并行口,先让它工作于输出方式,将列线也接到一个并行口,先让它工作于输入方式,程序使CPU通过输出端口往各行线上全部送低电平,然后读入列线值,如此时有某键被按下,则必定会使某一列线值为0。
然后,程序对两个并行端口进行方式设置,使行线工作于输入方式,列线工作于输出方式,并将刚才读得的列线值从列线所接的并行端口输出,再读取行线上的输入值,那么,在闭合键所在的行线上的值必定为0。
这样,当一个键被按下时,必定可以读得一对唯一的行线值和列线值。
2.程序设计时,要学会灵活地对8255A的各端口进行方式设置。
3.程序设计时,可将各键对应的键值(行线值、列线值)放在一个表中,将要显示的0~F字符放在另一个表中,通过查表来确定按下的是哪一个键并正确显示出来。
实验题目利用实验箱上的8255A可编程并行接口芯片和矩阵键盘,编写程序,做到在键盘上每按一个数字键(0~F),用发光二极管将该代码显示出来。
四、实验步骤:将键盘RL10~RL17接8255A的PB0~PB7;KA10~KA12接8255A的PA0~PA2;PC0~PC7接发光二极管的L1~L8;8255A芯片的片选信号8255CS接CS0。
五、实验电路:六、程序框图7.程序清单八、附:8251/8255扩展模块该模块由8251可编程串行口电路和8255可编程并行口电路两部分组成,其电源、数据总线、地址总线和片选信号均由接口挂箱上的接口插座提供。
一、8251可编程串行口电路(1)8251可编程串行接口芯片引脚及功能8251A是通用同步/异步收发器USART,适合作异步起止式数据格式和同步面向字符数据格式的接口,其功能很强。
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)扫描过程接着,通过编写程序实现键盘的扫描过程。
简单的按键扫描&读取程序

/*GPIOA的置位复位定义*/
#define PA0_BSRR (*(uint32_t *)0x42010a00)
#define PA1_BSRR (*(uint32_t *)0x42010a04)
//
char get_key_riseedge(char keynum)
{
char val;
u32 mid = 0;
val = (key_riseedge >> keynum) & 0x01;//将该位上升沿取出送到val
mid = ~( 1 << keynum );
key_riseedge &= mid;//该上升沿清零
key_falledge &= ~(redge);//同上
key_riseedge |= redge;//将上升沿取到寄存器中待读
key_falledge |= fedge;//同上
}
//别的函数查询某个键的键值=========================================
#define PA3_OUT (*(uint32_t *)0x4221018c)
#define PA4_OUT (*(uint32_t *)0x42210190)
#define PA5_OUT (*(uint32_t *)0x42210194)
#define PA6_OUT (*(uint32_t *)0x42210198)
//
char get_key_val(char keynum)
PIC单片机键盘扫描汇编程序

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;*************以下为键盘码值转换表******************CONVERTADDWF PCL,1RETLW 0XC0 ;0,显示段码与具体的硬件连接有关RETLW0XF9 ;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 ;HRETLW0XFF ;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 ;关闭所有中断MOVLW 0XC0MOVWF SSPSTAT ;设置SSPSTAT 寄存器MOVLW0X30MOVWF SSPCON1 ;设置SPI 的控制方式,允许SSP 方式,并且时钟下降;沿发送数据,与”74HC595当其SCLK 从低到高电平;跳变时,串行输入数据(DI)移入寄存器”的特点相对应MOVLW 0X01 MOVWF JIANR ;显示值寄存器(复用为键值寄存器)赋初值CLRF FLAG ;清除标志寄存器RETURN ;返回;。
单片机实验--键盘扫描

实验4 键盘实验一、实验目的:1.掌握8255A编程原理。
2.了解键盘电路的工作原理。
3.掌握键盘接口电路的编程方法。
二、实验设备:CPU挂箱、8031CPU模块三、实验原理:1.识别键的闭合,通常采用行扫描法和行反转法。
行扫描法是使键盘上某一行线为低电平,而其余行接高电平,然后读取列值,如所读列值中某位为低电平,表明有键按下,否则扫描下一行,直到扫完所有行。
本实验例程采用的是行反转法。
行反转法识别键闭合时,要将行线接一并行口,先让它工作于输出方式,将列线也接到一个并行口,先让它工作于输入方式,程序使CPU通过输出端口往各行线上全部送低电平,然后读入列线值,如此时有某键被按下,则必定会使某一列线值为0。
然后,程序对两个并行端口进行方式设置,使行线工作于输入方式,列线工作于输出方式,并将刚才读得的列线值从列线所接的并行端口输出,再读取行线上的输入值,那么,在闭合键所在的行线上的值必定为0。
这样,当一个键被按下时,必定可以读得一对唯一的行线值和列线值。
2.程序设计时,要学会灵活地对8255A的各端口进行方式设置。
3.程序设计时,可将各键对应的键值(行线值、列线值)放在一个表中,将要显示的0~F字符放在另一个表中,通过查表来确定按下的是哪一个键并正确显示出来。
实验题目利用实验箱上的8255A可编程并行接口芯片和矩阵键盘,编写程序,做到在键盘上每按一个数字键(0~F),用发光二极管将该代码显示出来。
四、实验步骤:将键盘RL10~RL17接8255A的PB0~PB7;KA10~KA12接8255A的PA0~PA2;PC0~PC7接发光二极管的L1~L8;8255A芯片的片选信号8255CS接CS0。
五、实验电路:六、程序框图7.程序清单八、附:8251/8255扩展模块该模块由8251可编程串行口电路和8255可编程并行口电路两部分组成,其电源、数据总线、地址总线和片选信号均由接口挂箱上的接口插座提供。
一、8251可编程串行口电路(1)8251可编程串行接口芯片引脚及功能8251A是通用同步/异步收发器USART,适合作异步起止式数据格式和同步面向字符数据格式的接口,其功能很强。
PIC单片机键盘扫描程序

//3*3键盘扫描程序,键盘为3个行上拉电阻,扫描函数完全自主知识产权//数码管扫描函数据说是华为的程序员编写的,本人稍加改动#include <pic.h>#define uchar unsigned char#define uint unsigned int__CONFIG(PWRTDIS&HS&WDTDIS&LVPDIS&BORDIS);const uchar table[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//共阴极数码管段表const uchar keycode[9][2]={{0x1E,1},{0x2E,2},{0x36,3},{0x1D,4}, {0x2D,5},{0x35,6},{0x1B,7},{0x2B,8},{0x33,9}};//矩阵键盘键值码void delayms(uint delay){uint i;for(;delay>0;delay--)for(i=0;i<453;i++);}void init(){ADCON1=0x8E;TRISD=0x00;TRISA&=0xE1;PORTD=0x00;PORTA=0x00;}uchar scankey(){uchar key3H,key3L,scancode;TRISB=0x38;//高3位置为输入,低3位为输出PORTB=0x00;//低3位输出低电平key3H=PORTB;//读取D口状态key3H=PORTB&0x38;if(key3H!=0x38){key3H=PORTB;delayms(5);if(key3H!=0x38){TRISB=0x07;//低3位输入,高3位输出PORTB=0x00;//高3位输出低电平key3L=PORTB;key3L=PORTB&0x07;if(key3L!=0x07){scancode=key3H|key3L;while(PORTB!=0x07);//等待按键松开return(scancode);}}}elsereturn(0xFF);}uchar getvalue(){uchar myvalue=0,i=0;myvalue=scankey();if(myvalue!=0xFF){while(myvalue!=keycode[i][0])i++;return(keycode[i][1]);}elsereturn(0xFF);}void display(uchar data){uchar i,j,k,num[5]={0,0,0,0,0};num[1]=data/1000;//千位num[2]=(data%1000)/100;//百位num[3]=data%100/10;//十位num[4]=data%10;//十位for(i=0;i<10;i++){PORTA=~(0x02);k=0x02;for(j=1;j<=4;j++){PORTA=~k;PORTD=table[num[j]];delayms(2);k=k<<1;}}}void main(){uchar mynum=0,i=0;init();//初始化while(1){i=getvalue();if(i!=0xFF)mynum=i;display(mynum);}}。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
页: 1
文 文 : D:\ScanKey.c 2012-10-18, 9:31:46
//短 要 要 很 很 //包 要 要 很 很
#define C_KEY_MASK
0x7f //要 要 MASK
/*******************************************************
function: 要 要 不 不 按 按
Input : 20ms很 很 时 时
{
unsigned char R=0;
struct
{
static unsigned char Cnt=0;
//发 很
static unsigned char State=C_IDLE;
//状 状
unsigned char UpValue=0;
//短 短 不 要 要
static unsigned char DownValue=0;
#define C_IDLE #define C_DEBOUNCE #define C_SHORT_KEY #define C_LONG_KEY
0
//空 空
1
//消 消
2
//短 要 要
3
//包 要 要
#define C_KEY_SHORT_TIME 2
#define C_KEY_LONG_TIME
100
else if(KeyInfo.DownValue)
//还 终 要 要 在 要 我 , 则 检 检 包 要 要
{
t=0;
KeyInfo.State = C_LONG_KEY;
}
break;
case C_DEBOUNCE://消 消
if(KeyInfo.Pre != KeyInfo.Cur)
KeyInfo.DownValue &= ~KeyInfo.UpValue;
//要 我 不 要 -
短短不要 = 剩剩要我不要
KeyInfo.State = C_IDLE;
KeyInfo.Pre = KeyInfo.Cur;
//当 当ห้องสมุดไป่ตู้要 不 覆 覆
在上要不
break; case C_LONG_KEY://包 要 要
Output : ( 短 要 要 ) or( 包 要 要 +0x80)
Detail : 1.支 支 包 要 要 /支 支 要 /要 要 要 各 各 要 要 /支 支 支 支 7要 要 要
2.短 要 要 但 要 短 要 要 短 短 短 不 不 不 要 要 不
3.包 要 要 长 要 很 很 要 功 不 不 ( 要 要 不 +0x80)
文 文 : D:\ScanKey.c 2012-10-18, 9:31:46
/*在 在 在 在 在 在 在 , 要 要 要 要 要 , 包 包 包 要 要 , 短 要 要 , 改 改 改 改 , 很 很 很 不不不在在不要不在在要要不不不不不,很很很很很,而而不而在 我在我在我我我要要不不不我要不不,但但我我但但但我要但但但但但但不, 要要很要要要很要要,移移移不移,于但于于于但但不在在, 功功功但短要要功包要要 1.要 要 要 在 要 要 功 要 要 要 要 , 互 不 互 互 , 支 支 支 支 要 2.支 支 包 要 要 功 短 要 要 , 3.要 按 在 在 要 很 , 另 在 在 要 功 另 另 要 要 4.在 在 包 要 要 一 , 不 不 不 不 在 在 不 要 要 不 发发要发发在在功功发发要要不不要不不,还还不要要还(我我我但我很我) 不我但但,终于终我但但不终终 发如如如我如要发发如如不如,可可可可我可不不 */
4.按 按 函 要 函 函 20ms不 很 很 时 时
5.按 按 函 要 函 函 要 要 不 函 函 , 不 很 同 改 MASK
author : 但 天 改 天
********************************************************/
unsigned char ScanKey(unsigned char TimerFlag)
{
t++;
if(t >= C_KEY_SHORT_TIME)//消 消 OK
{
KeyInfo.State = C_SHORT_KEY;
}
}
else //消 消 消 消
{
KeyInfo.State = C_IDLE;
}
break;
case C_SHORT_KEY://短 要 要
//区 区 包 要 要 区 短 要 要
页: 2
t++; if(KeyInfo.Pre != KeyInfo.Cur) //终 要 要 检 检 , 则 则 则 包 要 要 检 检 {
KeyInfo.State = C_IDLE; } else if(t >= C_KEY_LONG_TIME) {
R = KeyInfo.DownValue | 0x80; KeyInfo.DownValue = 0; KeyInfo.State = C_IDLE; } break; } return R; }
//要 我 不 要 要
unsigned char Cur=0;
//当 当 不 要 不
static unsigned char Pre=0;
//在 上 不 要 不
}KeyInfo;
if(TimerFlag)return 0; TimerFlag=0;
//短 等 很 很 时 时
KeyInfo.Cur &= C_KEY_MASK; //读 要 要 不 (高 高 高 高 高 要 要 ) switch(KeyInfo.State) {
KeyInfo.UpValue = (KeyInfo.Pre ^ KeyInfo.Cur) & KeyInfo.Pre;
//短 短 不 要 要
KeyInfo.DownValue |= (KeyInfo.Pre ^ KeyInfo.Cur) & KeyInfo.Cur;
//要 我 不 要 要
R = KeyInfo.UpValue & KeyInfo.DownValue; //短 要 要