51 单片机键盘扫描 键盘扫描 汇编程序

c语言超经典矩阵式键盘的接法,流程图和扫描程序
日 09:19 来源:本站整理 作者:胡哥 (0)
列线输入端P1.0~P1.3通过电阻接正电源,行线P1.4~P1.7所接的单片机的I/O口作为输出端。将输入端置为高电平,输出端置为低电平。这样,当按键没有按下时,所有的输入端无变化,代表无键按下。一旦有键按下,则输入线就受输出线的影响被拉低,这样,通过读入输入线的状态就可得知是否有键按下了。
& 行扫描法又称为逐行(或列)扫描查询法,是一种最常用的按键识别方法,如上图所示键盘,介绍过程如下。
判断键盘中有无键按下 将全部行线置低电平,然后检测列线的状态。只要有一列的电平为低,则表示键盘中有键被按下,而且闭合的键位于低电平线与4根行线相交叉的4个按键之中。若所有列线均为高电平,则键盘中无键按下。
判断闭合键所在的位置 在确认有键按下后,即可进入确定具体闭合键的过程。其方法是:依次将行线置为低电平,即在置某根行线为低电平时,其它线为高电平。在确定某根行线位置为低电平后,再逐行检测各列线的电平状态。若某列为低,则该列线与置为低电平的行线交叉处的按键就是闭合的按键。
/*************************C语言键盘扫描子函数************************/
uchar KeyV()
{& uchar Key,a;
&& P3=0x0f;&&&&&&&&&&&&&&&& //确定P3.0~P3.3为输入线,P3.4~P3.7为输出线。
&& if(P3==0x0f) return(0);&&&&& //无键按下返回0.
&&& { mling(6);&&&&&&&&&&&&&& //调用延时函数,去前沿键抖
&&&&& for(a=0;a&4;a++)
&&&&&&& { P3=_cror_(0x7f,a);&& //计算键值,依次将输出线置低电平,检查输入线。
&&&&&&&&& if(P30==0)&& //P30表示p3.0口引脚。预先定义,以下类同
&&&&&&&&& if(P31==0)
&&&&&&&&& if(P32==0)
&&&&&&&&& if(P33==0)
&&&&&&& }& Key=P3;&&&&&&&&& //取得键值
&&&&& for(;P3!=0x0f;P3=0x0f) ;& //等待按键释放,去后沿键抖
&&&&& return(Key);&&&&&&&&&&& //带键值返回
计算后变量Key得到的键值对照:
【0 0xee】 【1 0xed】 【2 0xeb】 【3 0xe7】 【4 0xde】 【5 0xdd】 【6 0xdb】 【7 0xd7】
【8 0xbe】 【9 0xbd】 【A 0xbb】 【B 0xb7】 【C 0x7e】 【D 0x7d】 【E 0x7b】 【F 0x77】
单片机矩阵式键盘C语言扫描子函数详细N_S图&&
相关技术文章:
相关资料下载:
上周热点文章排行榜
上周资料下载排行榜
技术交流、我要发言! 发表评论可获取积分! 请遵守相关规定。
创新实用技术专题
在28nm FPGA战场上,Xilinx和Altera已经展...查看: 18877|回复: 5
单片机4*4矩阵键盘扫描程序(c语言+汇编语言2个版本)
;4X4矩阵键盘程序。主要原理为扫描键盘矩阵时,每次只有一行电平拉低。在逐次扫描拉低的这些行的同时,去读那些列的电平。
;被拉低的行上,按下的键对应的列的电平为0 ,其它为1. 用左移位的指令,在进位位CY里就可以检测出是0还是1.为1表示无按下,
;为0表示该键按下。在扫描按键时,如无按下,则取码指针R1加1后,继续扫描 。如有键按下,转按键处理子程序,按键按下标志位
;F0清0(表示按下)。此时,取码指针的值,就是按键的键名。 随后继续进入按键检测子程序重新扫描。
;注:本程序只通过仿真,因无按键防抖,实物中正常与否,未能确定 。
;& & D:\DPJ\4X4KEY.ASM
ORG 00H& &
AJMP MAIN& &
MOV SP,#60H
MOV DPTR,#TABLE
ACALL KEY0_1& &;调用KEY0_1,判断是否有键按下
JB F0,$-2& &;无键按下,转ACALL KEY0_1,继续扫描
MOV A,R1& &;R1为取码指针
MOVC A,@A+DPTR&&;取码,关送显示
KEY0_1:& & ;按键检测子程序
SETB F0& &;设F0=1
MOV R3,#0F7H&&;行扫描指针初值(P2.3=0)
MOV R1,#00H& &;取码指针初值
MOV A,R3& &;载入扫描指针
MOV P2,A& &;输出至P2,开始扫描为0的一行
MOV A,P2& &;读入P2
MOV R5,#4& &;检测P2.7~P2.4,共4 列
L3:& & ;检测4列
RLC A& &;左移一位(P2.7~P2.4)
JNC KEY1& &;检测到C=0,表示被按下
INC R1& &;无键按下则取码指针加1
DJNZ R5,L3& &;4列检测完毕?
MOV A,R3& &;载入扫描指针
RRC A& && & ;扫描为0的下一行,
MOV R3,A& &;存回R3扫描指针寄存器
JC L2& &;C=0,行扫描完毕
CLR F0& &;F0清0 ,表示按键按下
DB& && &0C0H;0
DB& && &0F9H;1
DB& && &0A4H;2
DB& && &0B0H;3
DB& && &099H;4
DB& && &092H;5
DB& && &082H;
DB& && &0F8H;7
DB& && &080H;8
DB& && &090H;9
DB& && &088H;A
DB& && &083H;b
DB& && &0C6H;C
DB& && &0A1H;d
DB& && &086H;E
DB& && &08EH;F
其实4X4矩阵的51C程序很多,有的也简单。这个完全按上面汇编的写成C的,有点繁了。
//E:\DPJ_C\4X4KEY\4X4KEY.C
#include&reg51.h&
#include&intrins.h&
#define uchar unsigned char
#define uint unsigned int
uchar a,b,&&//a
uchar code tab[]={
& && && &&&0xC0,/*0*/
& && && &&&0xF9,/*1*/
& && && &&&0xA4,/*2*/
& && && &&&0xB0,/*3*/
& && && &&&0x99,/*4*/
& && && &&&0x92,/*5*/
& && && &&&0x82,/*6*/
& && && &&&0xF8,/*7*/
& && && &&&0x80,/*8*/
& && && &&&0x90,/*9*/
& && && &&&0x88,/*A*/
& && && &&&0x83,/*b*/
& && && &&&0xC6,/*C*/
& && && &&&0xA1,/*d*/
& && && &&&0x86,/*E*/
& && && &&&0x8E,/*F*/
void keyscan()
uchar i,j;
flag=1;//flag 有键按下标志
temp=0xf7; //temp 行扫描指针
for(j=0;j&4;j++)
&&_nop_();
&&b=P2; // b 列
&&for(i=0;i&4;i++)
& &b=b&&1;
& &if(!CY)
& & flag=0;//有键按下,标志置0
& & //跳出
& &a++;//无键按下,
&&temp=_cror_(temp,1);//扫描下一行
void main()
&&keyscan();
&&if(!flag)
&&P1=tab[a];
好东东,可以测试一下
谢谢楼主的奉献。
很好很强大。学习了。。。。
很好很强大。学习了。。。。
请问有仿真图么
Powered by51单片机矩阵键盘扫描程序
> 51单片机矩阵键盘扫描程序
51单片机矩阵键盘扫描程序
#include //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义#define DataPort P0 //定义数据端口 程序中遇到DataPort 则用P0 替换#define KeyPort P1sbit LATCH1=P2^2;//定义锁存使能端口 段锁存sbit LATCH2=P2^3;// 位锁存unsigned char code dofly_DuanMa[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f, 0x77,0x7c,0x39,0x5e,0x79,0x71};// 显示段码值0~Funsigned char code dofly_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(unsigned char FirstBit,unsigned char Num);//数码管显示函数unsigned char KeyScan(void);//键盘扫描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延时函数,含有输入参数 unsigned char t,无返回值unsigned char 是定义无符号字符变量,其值的范围是0~255 这里使用晶振12M,精确延时请使用汇编,大致延时长度如下 T=tx2+5 uS------------------------------------------------*/void DelayUs2x(unsigned char t){while(--t);}/*------------------------------------------------mS延时函数,含有输入参数 unsigned char t,无返回值unsigned 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; //清空数据,防止有交替重影 LATCH1=1; //段锁存 LATCH1=0; DataPort=dofly_WeiMa[i+FirstBit]; //取位码 LATCH2=1; //位锁存 LATCH2=0; DataPort=TempData[i]; //取显示数据,段码 LATCH1=1; //段锁存 LATCH1=0; i++; if(i==Num) i=0;}/*------------------------------------------------ 定时器初始化子程序------------------------------------------------*/void Init_Timer0(void){TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响//TH0=0x00; //给定初值//TL0=0x00;EA=1; //总中断打开ET0=1; //定时器中断打开TR0=1; //定时器开关打开}/*------------------------------------------------ 定时器中断子程序------------------------------------------------*/void Timer0_isr(void) interrupt 1{TH0=()/256; //重新赋值 2msTL0=()%256;Display(0,8); // 调用数码管扫描}/*------------------------------------------------ 按键扫描函数,返回扫描键值------------------------------------------------*/unsigned char KeyScan(void) //键盘扫描函数,使用行列逐级扫描法{unsigned char VKeyPort=0xf0;//高四位置高,低四位拉低if(KeyPort!=0xf0)//表示有按键按下 { DelayMs(10); //去抖if(KeyPort!=0xf0) { //表示有按键按下 KeyPort=0 //检测第一行 if(KeyPort!=0xfe) { Val=KeyPort&0xf0; Val+=0x0e; while(KeyPort!=0xfe); DelayMs(10); //去抖 while(KeyPort!=0xfe); return V } KeyPort=0 //检测第二行 if(KeyPort!=0xfd) { Val=KeyPort&0xf0; Val+=0x0d; while(KeyPort!=0xfd); DelayMs(10); //去抖 while(KeyPort!=0xfd); return V } KeyPort=0 //检测第三行 if(KeyPort!=0xfb) { Val=KeyPort&0xf0; Val+=0x0b; while(KeyPort!=0xfb); DelayMs(10); //去抖 while(KeyPort!=0xfb); return V } KeyPort=0xf7; //检测第四行 if(KeyPort!=0xf7) { Val=KeyPort&0xf0; Val+=0x07; while(KeyPort!=0xf7); DelayMs(10); //去抖 while(KeyPort!=0xf7); return V } } } return 0}/*------------------------------------------------ 按键值处理函数,返回扫键值------------------------------------------------*/unsigned char KeyPro(void){switch(KeyScan()){ case 0x7e:return 0;//0 按下相应的键显示相对应的码值 case 0x7d:return 1;//1 case 0x7b:return 2;//2 case 0x77:return 3;//3 case 0xbe:return 4;//4 case 0xbd:return 5;//5 case 0xbb:return 6;//6 case 0xb7:return 7;//7 case 0xde:return 8;//8 case 0xdd:return 9;//9 case 0xdb:return 10;//a case 0xd7:return 11;//b case 0xee:return 12;//c case 0xed:return 13;//d case 0xeb:return 14;//e case 0xe7:return 15;//f default:return 0}}
分享给小伙伴们:
我来说两句……
微信公众号二
微信公众号一51 单片机 键盘扫描 汇编程序_百度知道
51 单片机 键盘扫描 汇编程序
P2,#0F0H ;给列送高电平MOV
P2,#0FH给行送高电平但是行接的是p2.0~p2.3,列接的是p2.4~p2.7,为什么是给列送高电平,是给行送高电平?
我有更好的答案
P2口的第 7 6 5 4 3 2 1 01 1 1 1 0 0 0 0啊,高四位全1 所以是F0哈
采纳率:60%
来自团队:
矩阵就是送高低电平来确定你按下的是哪一个按键,基本就是给高四位送高,低四位送设低,读出在哪一行(或列),然后反转再确认在那一列(或行),这不就确定了第几行,第几列的按键被按下了。
本回答被网友采纳
为您推荐:
您可能关注的内容
&#xe675;换一换
回答问题,赢新手礼包&#xe6b9;
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。单片机汇编键盘扫描程序_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
单片机汇编键盘扫描程序
&&简单的单片机键盘扫描程序,P0口接显示,P1口接键盘……文档内附接线图。
阅读已结束,下载本文需要
想免费下载更多文档?
定制HR最喜欢的简历
你可能喜欢}

我要回帖

更多关于 单片机汇编程序 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信