请教关于单片机按键扫描的汇编语言
DA A指令,是专门用于BCD码加法计算调整的,例如,计算十进制数26+17,用指令:
MOV A ,#26H
ADD A ,#17H
这样计算的结果是3DH,这不是十进制数,在加法指令后加上DA A,则进行十进制数调整,调整后的结果就是43了。
这个是蜂鸣器在响
选择蜂鸣器的频率 (尖锐到平和)
制作成子程序
set BZ(蜂鸣器) 打开
call delay 50MS
call delay 50MS
clr BZ
call delay 50MS
call delay 50MS
重复使用 依次减少延时
扫描是否按键:按键有效就进入子程序就OK了
扫描是一次把一个IO置0,其它的IO均为输入状态(51是准双向IO,没有输入输出概念,把输出高当输入即可)。比如说,现在是扫描P00,那么把P00写0,其它的IO写1,然后把所有的IO读取回来,把值赋给一个临时变量用来判断,eg key_buffer_temp =P0; 把扫描(写0的相应)位强制性写上1, 即
key_buffer_temp=key_buffer_temp|0x01;这时看这个key_buffer_temp的值,有没有位是0的,即这个值是不是0xff,如果是0xff,则和P00接的按键都没有按键。如果不是0xff,则有几位是0就有几个按键。这样循环下去,一直扫到P06(不用扫P07)。
程序的注意点:
1扫描P00时,只看读回来key_buffer_temp的位1--位7,扫描P01时,只看读回来key_buffer_temp的位2--位7,……扫描P06时,只看读回来key_buffer_temp的位7,不用扫描P07
2每扫描一个就判断一次key_buffer_temp的值,一个个位来判断,同时把计数加1,如果有按键则把计数的值赋给key_value0,key_value1……
3扫描结束后看key_value0,key_value1……里面的值,有几个就几个按键
4比如说key_value0为1,key_value为10,那么就是S1,和S10有按键
至于消抖,这一般的做法就是多采样几次
逐行置0,扫描列,如何防抖和避免两个按键同时按下键值异常呢?
----
什么是:避免两个按键同时按下键值异常?
两个按键同时按下,能扫描出来吗?
扫描到一个零,即返回了,而并不理会其他键是否同时按下。
使用扫描法,是不会得出多个按键按下的键值的。
防抖:一般就是延时约 10ms,再次读出,两者不相同,就不予理会,这就是防抖。
----
针对这个电路,和 4*4 矩阵键盘的编程思路相同,用汇编语言来编写,十几行即可。
SCANCODE EQU 30H
SCANCNT EQU 31H
KEYVAL EQU 32H
ORG 0000H
LJMP MAIN
ORG 000BH
LJMP T0ISR
ORG 0030H
MAIN:
MOV TMOD,#01H
MOV TH0,#HIGH(65536-10000) ;10毫秒扫描一次键盘
MOV TL0,#LOW(65536-10000)
SETB TR0
SETB ET0
SETB EA
MOV SCANCODE,#0FEH ;扫描码
MOV SCANCNT,#3 ;扫描次数,当3次键值相同时,确认该键值
SJMP $
T0ISR:
CLR TR0
MOV TH0,#HIGH(65536-10000)
MOV TL0,#LOW(65536-10000)
SETB TR0
T000:
MOV P0,SCANCODE ;扫描码送P0口
NOP
MOV A,P0 ;读入P0口值
CJNE A,SCANCODE,T001 ;如果与扫描码不同则有键按下
RL A ;否则下一行
MOV SCANCODE,A
SJMP T000
T001:
CJNE A,KEYVAL,T002 ;如果本次和上次值不一致转
DJNZ SCANCNT,T0E ;一致则看是否3次一致
MOV SCANCNT,#3 ;重赋初值
LCALL KEYDEAL ;处理键值
MOV P1,KEYVAL ;键值送显示,这里假设是P1.0口
SJMP T0E
T002:
MOV KEYVAL,A
MOV SCANCNT,#3
T0E:
RETI
KEYDEAL:
MOV R2,#0
MOV A,SCANCODE
KLP:
CLR C
RRC A
INC R2
JNC KLP
MOV R3,#0
MOV A,KEYVAL
KLP1
CLR C
RRC A
INC R3
JNC KLP1
MOV DPTR,#KTAB
MOV A,R2
DEC A
MOVC A,@A+DPTR
MOV B,A
MOV A,R3
CLR C
SUBB A,R2
ADD A,B
MOV KEYVAL,A
RET
KTAB:
DB 0,7,13,18,22,27
END
1防抖是在一开始判断有没有键按下时就软件延时去抖了,在逐列扫描时不用去抖了。
2多键按下时,由于逐列判断,先判断出来的那个键有效。
5.4.2 按键扫描(单片机最简洁的键盘扫描程序详解)
理解按键值的二进制表示:五个按键对应0x01到0x10,这是因为它们是按键状态的二进制位表示,便于程序处理。运用全局变量:图形化代码虽然初始值为空,但实际运行时会被编译器自动初始化为0。构建键盘扫描函数:这是程序的核心部分,通过定义函数来检测按键输入。局部变量与表达式:在函数内部,局部变量和创...
单片机行列式键盘扫描原理?
单片机行列式键盘扫描原理如下:1、行线P10~P13为输出线,列线P14~P17为输入线。一开始单片机将行线(P10~P13)全部输出低电平,此时读入列线数据,若列线全为高电平则没有键按下,当列线有出现低电平时调用延时程序以此来去除按键抖动。2、延时完成后再判断是否有低电平,如果此时读入列线数据还是有...
单片机汇编矩阵键盘实验(扫描法)
这里只需要在程序里做下判断,先判断下是不是K05按下,若不是就是K51,因为按键K01、K02、K03、K04、K05在5个IO口都为读取的情况下,就可以识别,不需要扫描识别处理,相当于这5个按键优先级高与其他按键。
单片机键盘扫描怎么实现一键多用
1:键值记录 2:时间记录 3:是不是同一个键。以上三个条件组合,一个条件用一个变量。
给单片机编程为什么要编写一个按键扫描的程序啊?
其实按键可以有好几种工作方式,比如用中断,这个是不用扫描的,还有就是扫描方式,其实扫描就是不时的检查按键所对应的寄存器的值有没有改变,如果改变,说明按键有动作,没变说明按键没动作,为了做到及时反应按键的状态,就得不停地对按键进行扫描。。。
关于单片机键盘扫描问题(行列转换)
P3 = key_l | 0x0f; \/\/重置P3口使其显示出按键后的状态 key_h = P3 & 0x0f; \/\/读入行 \/\/--- key_h = key_l + key_h; \/\/保存到key_h \/\/--- P3 = 0xf0; \/\/将行全部置为0 while(key_l != 0xf0) \/\/只有处于按下状态 key_l = P3 & 0xf0; \/\/...
求解释单片机键盘扫描的一段程序(关键是松手那块不明白)
松手检测也就是消抖嘛,在你这程序中就是 if (key==0xff){ \/\/如果读取不到P0口的值,比如是干扰,我们不做键值处理,返回 SPK=1;\/\/按键有松开,停止蜂鸣器响 return;} 主要作用就是防止其他干扰信号误判成按键信号。另一个就是假如你长按不放的话就要使它在那等待你放开才会执行程序,所以这在...
单片机什么是用键值的方式解决按键扫描问题,简单解说下 单解说下_百度...
键值,顾名思义就是按键的数值;是在矩阵键盘扫描中用到的。简单来说其实现过程就是先对行赋值,然后读取端口状态,得到一个数值;然后再给列赋值,读取端口数值;行与列数值的交点,即为当前所按上的按键。C语言代码如下:void keyscan (){ uchar tem,temp;P3=0xfe;temp=P3;tem=temp&0xf0;if...
关于51单片机很小,键盘扫描问题
解决这个问题,你的程序用延时来产生方波,这样就势必造成大量的CPU资源被浪费到延时程序上。建议改用定时器来产生方波。这样,你的CPU可以全时地处理键盘扫描问题了,做一个软件消抖,就可以解决好这个问题。最简单的办法,当你的计时器位数不够的时候,设一个全局变量。比如要实现1HZ,那么就用这个全局...
单片机矩阵按键扫描为什么用if判断两次?
好好看书,这是延时消抖,按键刚按下时会有一个不稳定过程,似接非接,会出现高低电平的几次跳变,如果只检测一次低电平就认为按键按下了,会出现两种情况,一是按一次被当作多次,二是某些偶尔的干扰也可能被当作按键按下。延时10到20ms,真正按下按键就稳定了,如果是干扰第二次判断不可能仍是低...
圣志胃舒: MAIN: ACALL KS JZ MAIN SCAN: ACALL DELAY MOV R7,#0 MOV R4,#0 MOV R2,#0FEHLOOP: MOV P1,R2 MOV A,P1 JB ACC.4,ONE MOV R6,#0 LJMP GETZH ONE: JB ACC.5,TWO MOV R6,#1 LJMP GETZH TWO: JB ACC.6,THREE ...
浮梁县18351662944: 用汇编语言写一个用8255扩展的8051单片机4*6键盘扫描程序 - ?
圣志胃舒: P1口接4根线作为检测时输出,p2口接6跟线作为检测输入,键盘接上拉电阻,首先往p1口上送数据,检测p2口,无变化则检测下行,有变化直接读取键值表(键值表自设),送入内存变量,大概就是这个样子,很简单的
浮梁县18351662944: 单片机用汇编语言编写一个.用十个按钮分别控制十个灯.比如:按下按钮K1 LED1灯亮.按下" - ?
圣志胃舒: 检测是否有按键按下,相应的指示灯点亮,并熄灭其它的指示灯.至于10S锁住其他按钮,如果程序不做其它的事情,最简单的方法就是点亮指示灯后延时10S,再回到主函数扫描其它按键即可
浮梁县18351662944: 51 单片机 汇编 语言 按键扫描的部分,求解释下面什么功能?一定采纳.求详细注释 - ?
圣志胃舒: rd_key: lcall getk //re_key是行号,lcall是长调用指令,跳转到行号getk JNB key_push,rdk1 //判断按键是否按下,按下则跳转到rdk1. KEY_PUSH是你设定的单片机管脚上的按键 Jnz RDK0 lcall DELAY10MS //延时 lcall getk jnz rdk9 CLR KEY_...
浮梁县18351662944: 单片机用汇编语言的按键检测问题? - ?
圣志胃舒: 对,这两处,都应该是JB P3.7 REL.
浮梁县18351662944: 单片机汇编按键程序 - ?
圣志胃舒: loop:jnb key1,tokey1 jnb key2,tokey2 jnb key3,tokey3 jnb key4,tokey4...ljmp loop tokey1:lcall d10ms ;按键去抖动 jb key1,loop lcall display ;数码管扫描程序 ajmp loop
浮梁县18351662944: 请帮忙看一下单片机C语言设计4x4矩阵键盘扫描按键的程序 - ?
圣志胃舒: void keyscan()//矩阵键盘扫描程序 { P0=0x0f;if(P0!=0x0f) //这里条件0,不会执行后面的程序吧 {delay (10);if(P0!=0x0f){ a=P0; P0=0xf0; b=P0; a= a|b; }; }; }
浮梁县18351662944: 请写出程序当键盘按键被按下和放开按键时的扫描码程序,能显示出来?? - ?
圣志胃舒: 4X4键盘,假设接在P1口上, void Key_ScanAndAnswer(void) {unsigned char data commonVariable = 0;unsigned char data keyValue = 0; P1 = 0xf0;//置P1高4位为输入口if( P1 != 0xf0 ) {Delay(20);//msif( P1 != 0xf0 ) {commonVariable = ...
浮梁县18351662944: 51单片机键盘矩阵扫描代码的理解?
圣志胃舒: 本人是学C的,但还看得懂汇编语言. MOV P2,A 是把扫描码赋给P2口,其实是赋给P2口的低四位,进行扫描; MOV A,P2 是读取P2口的值,后面一句把低四位屏蔽了,最终还是读取了高四位
浮梁县18351662944: 单片机扫键盘程序代码 - ?
圣志胃舒: uchar keyboard_Scan[]={0xef,0xdf,0xbf,0x7f}; /*矩阵键盘扫描松手检测用*/.................................do { P1=0x0f; /*扫描P1口之前赋值*/ delay(3); /*延时,消抖*/ if(P1!=0x0f) /* 检测看是否有按键按下 如果按下则需要检测一次*/ { key=Keyboard(); } } ...