朋友们帮忙写个51单片机的按键小程序?汇编的

一个按键控制一个灯,要求按一下按键,灯亮一直亮,再按一下按键灯灭,要带按键的去抖程序。

(1);P3.3小键盘按下P1.3亮再按0.5秒灭。
org 0000h
ajmp main0
org 0080h
MAIN0:
CLR 21H ;清标志
main:
mov c,p3.3 ;检测按键
jc main
MOV R6,#200 ;设定延时
MOV R7,#200
TT0:
JNB 21H,TT2 ;检测灯状态
tt:
mov c,p3.3 ;检测按键
jnc tt1

JNB 20H,MAIN ;检测时间标志
CLR 20H
AJMP TT3
TT2:
mov c,p3.3 ;检测按键
jnc tt2
TT3:
CPL 21H ;改变灯状态
cpl p1.3
ajmp main
TT1: NOP ;延时但不是子程序
NOP
NOP
NOP
NOP
NOP
DJNZ R6,TT
MOV R6,#200
DJNZ R7,TT
MOV R7,#200
SETB 20H
AJMP TT
end
(2)数码管数据 p0,数码管控制p2 独立按键p1口 ,;对独立键进行按键次数计数,三位数码管显示。 *
;K1按下后,进行加1计数 *
;K2按下后,进行减1计数。 *
;K3按下后,进行加5计数。 *
;K4按下后,清计数单元,数码管显示0。 *
;按住键可以快速计数。
K1 BIT P1.4
K2 BIT P1.5
K3 BIT P1.6
K4 BIT P1.7
K_OLD EQU 30H
K_NEW EQU 31H
K_COUNT EQU 32H
DISSTART EQU 40H ;显示单元首地址
LED_DATA EQU P0 ;数码管数据口定义
;---------------------------------------------------------
ORG 0000H
JMP MAIN
ORG 0080H
;---------------------------------------------------------
MAIN:
MOV SP,#60H
MOV P1,#0FFH
MOV P0,#0FFH
MOV K_OLD,#00H
MOV K_COUNT,#00H
MAIN1:
CALL CONVT
CALL PLAY
CALL KEY_PROG
JMP MAIN1

KEY_PROG:
CALL K_SCAN ;键扫描
MOV A,K_NEW
CJNE A,K_OLD,KEY_P1
JMP KEY_P_END
KEY_P1:
MOV R4,#20
KEY_P2:
CALL CONVT ;用显示程序来进行键延时
CALL PLAY
DJNZ R4,KEY_P2

CALL K_SCAN ;再判断键是否按下
MOV A,K_NEW
CJNE A,K_OLD,KEY_P3
JMP KEY_P_END
KEY_P3:
JB ACC.0,LOOP1 ;K1按下
JB ACC.1,LOOP2 ;K2按下
JB ACC.2,LOOP3 ;K3按下
JB ACC.3,LOOP4 ;K4按下
JMP KEY_P_END
LOOP1:
INC K_COUNT ;键计数加1
JMP KEY_P_END
LOOP2:
DEC K_COUNT ;键计数减1
JMP KEY_P_END
LOOP3:
INC K_COUNT ;键计数加5
INC K_COUNT
INC K_COUNT
INC K_COUNT
INC K_COUNT
JMP KEY_P_END
LOOP4:
MOV K_COUNT,#00H ;键计数单元清零
KEY_P_END:
RET
;---------------------------------------------------------
;代码变换 (HEX TO BCD)
;---------------------------------------------------------
CONVT:
MOV A,K_COUNT
MOV B,#100
DIV AB
MOV DISSTART+2,A ;百位存放在DISSTART+2
MOV A,#10
XCH A,B
DIV AB
MOV DISSTART+1,A ;十位存放在DISSTART+1
MOV DISSTART,B ;个位存放在DISSTART
RET
;---------------------------------------------------------
; 键扫描子程序
;---------------------------------------------------------
K_SCAN:
MOV P1,#0FFH
MOV K_NEW,#00H
MOV A,P1
CPL A
ANL A,#0F0H
SWAP A
MOV K_NEW,A
RET
;---------------------------------------------------------
;延时子程序
;---------------------------------------------------------
DELAY:
MOV R6,#200
DEL:
MOV R7,#0FFH
DJNZ R7,$
DJNZ R6,DEL
RET
;---------------------------------------------------------
PLAY:
MOV R0,#DISSTART ;获得显示单元首地址
MOV R1,#07FH ;从第一个数码管开始
MOV R2,#03H ;共显示3位数码管
DISP1:
MOV A,@R0 ;获得当前位地址
MOV DPTR,#TAB_NU ;获得表头
MOVC A,@A+DPTR ;查表获得显示数据
MOV LED_DATA,A ;显示数据
MOV P2,R1 ;开始显示当前位
MOV A,R1 ;准备显示下一位
RR A
MOV R1,A ;下一位
INC R0 ;取下一个单元地址
LCALL DELAY2MS ;延时 2 MS
DJNZ R2,DISP1 ;重复显示下一个
MOV P2,#0FFH ;关闭显示
RET ;显示完成,返回
;---------------------------------------------------------
;延时子程序
;---------------------------------------------------------
DELAY2MS:
MOV R6,#10
DEL1:
MOV R7,#100
DJNZ R7,$
DJNZ R6,DEL1
RET
TAB_NU:
db 28h,7eh,0a2h,62h,74h,61h,21h,7ah,20h,60h ;字形代码表
;**********************************************************
END

两个例子我想够你明白的了。详细的解释,代表性的例子,可慢慢学习
温馨提示:答案为网友推荐,仅供参考
第1个回答  推荐于2017-12-15
试一下这个,灯接在p1.2,按键接在p3.3
ORG 00H;
MOV P3,#0FFH ;
SETB P1.2 ;
START:JNB P3.3,TT0;
AJMP START ;
TT0:LCALL D1MS ;
JNB P3.3,TT0;
CPL P1.2;
AJMP START;
D1MS: MOV R7, #10 ;
D1:MOV R6, #250;
DJNZ R6,$;
DJNZ R7,D1 ;
RET ;
END本回答被提问者采纳
第2个回答  2010-08-11
程序如下:
ORG 00H
START:
JB P3.3, $ ;高电平,就是没有键按下,原地等待.
CALL D20MS ;延时.
JB P3.3, START ;消抖.
JNB P3.3, $ ;等待释放.
CPL P1.2; ;外接LED亮灭.
SJMP START ;继续.
;-------------------------------
D20MS: ;延时子程序.
MOV R7, #20
D1: MOV R6, #250
DJNZ R6, $
DJNZ R7, D1
RET
;-------------------------------
END
第3个回答  2010-08-23
很完美的按键控制可调时钟。消抖都在里面包含。好好研究~~~~~~~

R_QH EQU 44H
R_BZ BIT 18H
R_1 EQU 26H
R_2 EQU 27H
R_3 EQU 28H
B_DEBOUNCE EQU 65H
B_HASKEY EQU 66H
ORG 0000H
LJMP L_MAIN
ORG 000BH
LJMP I_T0
ORG 001BH
LJMP I_T1
ORG 0030H

L_MAIN:
MOV SP,#62H
MOV TMOD,#11H
MOV TH0,#HIGH(62536)
MOV TL0,#LOW(62536)
MOV TH1,#HIGH(15536)
MOV TL1,#LOW(15536)
MOV IE,#10001010B
SETB TR0
SETB TR1
SETB PT1
SETB R_BZ
MOV 40H,#59H
MOV 41H,#58H
MOV 42H,#23H
MOV R_1,#20
MOV R_2,#0
MOV R_3,#55H
MOV 55H,#0
MOV 56H,#0
MOV 57H,#0
MOV 58H,#0
MOV 59H,#0
MOV 5AH,#0
MOV B_HASKEY,#00H
MOV B_DEBOUNCE,#00H
LCALL F_CHAIFEN

L_LOOP:

JB B_DEBOUNCE,L_JSJZ
MOV P1,#0FH
MOV A,P1
ANL A,#0FH
CJNE A,#0FH,L_PRESS
JNB B_HASKEY ,L_WAJ
LCALL F_KEYRELEASE
CLR B_HASKEY
L_WAJ: LJMP L_FANHUI

L_JSJZ:

CLR B_DEBOUNCE
LCALL F_KEYSCAN
LCALL F_KEYservice
SETB B_HASKEY
LJMP L_FANHUI

L_PRESS:
JNB B_HASKEY,L_GAX
LCALL F_XDYS200ms
LCALL F_KEYHOLD
LJMP L_FANHUI

L_GAX:
SETB B_DEBOUNCE
LCALL F_XDYS20ms
LJMP L_FANHUI
F_KEYRELEASE:
CPL P2.0
RET

F_KEYHOLD:
MOV A,75H
CJNE A,#02H,L_NEXT3
LJMP KEY2
RET
L_NEXT3:
CJNE A,#03H,L_FANHUI0
LJMP KEY3
L_FANHUI0:
RET

L_FANHUI:
LJMP L_LOOP

F_KEYSCAN:
MOV P1,#0FH
MOV A,P1
MOV R4,#0FFH
L_LOOP1:
INC R4;计算移动次数,得到第几位为0
RRC A
JC L_LOOP1
MOV P1,#0F0H
MOV A,P1
MOV R5,#0FFH
L_LOOP2:
INC R5;计算移动次数,得到第几位为0
RLC A
JC L_LOOP2

MOV B,#4
MOV A,R4
MUL AB
ADD A,R5
MOV 75H,A
RET
F_KEYservice:
MOV A,75H
MOV DPTR,#T_LJMP
MOV B,#3
MUL AB
JMP @A+DPTR
T_LJMP:
LJMP KEY0
LJMP KEY1
LJMP KEY2
LJMP KEY3
LJMP KEY0
LJMP KEY1
LJMP KEY2
LJMP KEY3
LJMP KEY0
LJMP KEY1
LJMP KEY2
LJMP KEY3
LJMP KEY0
LJMP KEY1
LJMP KEY2
LJMP KEY3
KEY0:
CPL R_BZ
MOV R_QH,#40H
LJMP L_D

KEY1:
JB R_BZ,L_D

MOV A,R_QH
ADD A,#1
MOV R0,A
MOV R_QH,R0
CJNE R0,#43H,L_D
MOV R_QH,#40H
LJMP L_D

KEY2:
JB R_BZ,L_D
MOV R1,R_QH
MOV A,@R1
ADD A,#1
DA A
MOV @R1,A
CJNE R1,#42H,L_LL
CJNE @R1,#24H,L_D
MOV @R1,#00H
LJMP L_D
L_LL:
CJNE @R1,#60H,L_D
MOV @R1,#00H
LJMP L_D

KEY3: JB R_BZ,L_D
MOV R0,R_QH
CJNE R0,#42H,L_FENMIAO
DEC @R0
CJNE @R0,#0FFH,L_JJ
MOV @R0,#23H

LJMP L_D

L_FENMIAO:
MOV R0,R_QH
DEC @R0
CJNE @R0,#0FFH,L_JJ
MOV @R0,#59H
LJMP L_D
L_JJ:
MOV A,@R0
ANL A,#0FH
MOV R1,A
MOV R0,R_QH
MOV A,@R0
ANL A,#0F0H
CJNE R1,#0FH,L_D
ADD A,#09H
MOV @R0,A

L_D: LCALL F_CHAIFEN
RET

F_CHAIFEN:
MOV R0,#40H
MOV R1,#55H

L_DD: MOV A,@R0
ANL A,#0FH
MOV @R1,A
INC R1
MOV A,@R0
ANL A,#0F0H
SWAP A
MOV @R1,A
INC R0
INC R1
CJNE R0,#43H,L_DD
RET

;中断T0

I_T0: PUSH PSW
PUSH ACC
SETB RS0
MOV TH0,#HIGH(62536)
MOV TL0,#LOW(62536)

MOV A,R_2
SWAP A
MOV R0,R_3
ORL A,@R0
MOV P0,A
INC R_2
INC R_3
MOV R0,R_2
CJNE R0,#06H,L_EXIT
MOV R_3,#55H
MOV R_2,#0
L_EXIT:
POP ACC
POP PSW
RETI
;中断T1
I_T1:

PUSH ACC
PUSH PSW

SETB RS1
MOV TH1,#HIGH(15536)
MOV TL1,#LOW(15536)
DJNZ R_1,L_EXIT2
MOV R_1,#20
JNB R_BZ,L_EXIT2
MOV A,40H
ADD A,#1
DA A
MOV 40H,A
CJNE A,#60H,L_LCHAIFEN
MOV 40H,#00H
MOV A,41H
ADD A,#1
DA A
MOV 41H,A
CJNE A,#60H,L_LCHAIFEN
MOV 41H ,#00H
MOV A,42H
ADD A,#1
DA A
MOV 42H,A
CJNE A,#24H,L_LCHAIFEN
MOV 42H,#00H

L_EXIT2 :

L_LCHAIFEN:

LCALL F_CHAIFEN
POP PSW
POP ACC
RETI

F_XDYS20ms:

MOV R6,#100
L_LOOP9:

MOV R5,#100

DJNZ R5,$

DJNZ R6,L_LOOP9

RET

F_XDYS200ms:

MOV R6,#50
L_LOOP11:
MOV R7,#100
L_LOOP10:

MOV R5,#40

DJNZ R5,$

DJNZ R7,L_LOOP10
DJNZ R6,L_LOOP11
RET

END
第4个回答  2010-08-12
用中断好。
相似回答