我是个新手,刚接触单片机不久,学的是汇编,也都听说用C编的话灵活性更强,但是我头脑不好用,现在正在编一个密码锁程序,各路好手请帮个忙,先在这谢过了。
;密码缓存区 PS1 EQU 6FH PS2 EQU 6EH PS3 EQU 6DH PS4 EQU 6CH ;输入密码缓存区 MM1 EQU 6BH MM2 EQU 6AH MM3 EQU 69H MM4 EQU 68H
FL_EN BIT P3.0 ;开锁标志位 EL_CL BIT P3.1 ;闭锁标志位
FLAG1 BIT 26H ;功能键标志位,为一表示功能按键 PSW_F BIT 27H ;密码是否正确标志位 TIMERS EQU 28H ;输入回车次数 ;发光二极管 L1 BIT P2.0 ;开锁指示灯 L2 BIT P2.1 ;闭锁指示灯 L3 BIT P2.2 ;密码错误指示灯 BAOJ BIT P2.3 ;三次错误,给报警脉冲 ORG 0000H AJMP START ORG 0100H
;初始化程序 START: MOV SP,#60H CLR MM1 CLR MM2 CLR MM3 CLR MM4 CLR L1 SETB L2 ;闭锁灯亮 CLR L3 CLR PSW_F ;清密码正确标志位 CLR FL_EN ;清开锁状态标志位 CLR BAOJ ;清报警信号 SETB EL_CL ;置闭锁标志位 MOV PS1,#01H MOV PS2,#02H MOV PS3,#03H MOV PS4,#04H ;密码初始化为1234 MOV TIMERS,#03H ;错误次数定为3次
MAIN: LCALL KEYEN ;检测功能键 LCALL DISPLAY ;调用显示 LCALL BIJIAO ;调用比较 AJMP MAIN
; 扫描功能键子程序
KEYEN: MOV SP,#60H ;SP初始化 MOV P3,#0FFH ;端口初始化
WORK: MOV A,P3 JB ACC.0,CL ;检测开锁键没有被按下,跳到闭锁键检测 EN: ACALL YS20ms ;消前沿抖动延时,实现软件去抖动 JB ACC.0,WORK ;再次检测按键,如果为高电平,则是抖动 JNB ACC.0,$ ;等待按键K1释放 LCALL KEYSET AJMP WORK ;返回重新检测按键 CL: ACALL YS20ms JB ACC.1,WORK JNB ACC.1,$ CLR EL_CL SETB L2 CLR L1 AJMP MAIN
;密码比较子程序
BIJIAO: PUSH PSW PUSH ACC MOV R2,#04H ;比较四位密码 MOV R0,#PS1 ;内部密码初始地址给R0 MOV R1,#MM1 ;输入的密码给R1 C_P: CLR C MOV A,@R0 SUBB A,@R1 ;内部密码与输入密码相减 JNZ RETURN ;密码错误转移 DEC R0 ;指向下一单元 DEC R1 DJNZ R2,C_P ;继续比较下一位密码 NOP SETB PSW_F ;密码正确,将标志位置1 SETB L1 ;置开锁指示灯为高电平 AJMP EXIT7 RETURN: CLR PSW_F ;清密码正确标志位 DJNZ TIMERS,KEYSET SETB P2.3 ;报警 JMP ENDS EXIT7: NOP POP ACC POP PSW RET
;扫描键盘子程序 KEYSET: MOV R1,#06BH ;扫描结果存放的缓存起始地址 MOV R6,#0FEH ;扫描的列选码的初始值 MOV R4,#00H ;扫描的列序号 KEY: MOV A,R6 SWAP A MOV P0,A ;置扫描某一列为0 LCALL YS20ms ;延时消抖 MOV A,P0 ;读行扫描信息 JB ACC.0,KNEXT1 ;不是P2.0行的键被按下 WKEY1: MOV A,P0 ;是P2.0行的键被按下 JNB ACC.0,WKEY1 ;等待键释放 MOV A,R4 MOV DPTR,#INDEXT1 MOVC A,@A+DPTR ;按扫描列序号查表得到扫描的键值 MOV @R1,A ;扫描键值存到显示缓存 DEC R1 LJMP PANDUAN KNEXT1: JB ACC.1,KNEXT2 ;不是P2.1被按下 WKEY2: MOV A,P0 JNB ACC.1,WKEY2 MOV A,R4 MOV DPTR,#INDEXT2 MOVC A,@A+DPTR MOV @R1,A DEC R1 LJMP PANDUAN KNEXT2: JB ACC.2,KNEXT3 WKEY3: MOV A,P0 JNB ACC.2,WKEY3 MOV A,R4 MOV DPTR,#INDEXT3 MOVC A,@A+DPTR MOV @R1,A DEC R1 LJMP PANDUAN KNEXT3: JB ACC.3,PANDUAN WKEY4: MOV A,P0 JNB ACC.3,WKEY4 MOV A,R4 MOV DPTR,#INDEXT4 MOVC A,@A+DPTR MOV @R1,A DEC R1 PANDUAN:CJNE R1,#067H,SKIP2 ;四个缓存存放一个循环否? MOV R1,#06FH ;四个显示缓存存放一个循环结束,显示缓存初始化 LJMP BIJIAO SKIP2: MOV A,R6 RL A MOV R6,A INC R4 CJNE R6,#0EFH,KEY ;四个列扫描完毕否? MOV R6,#0FEH ;四个列扫描完毕,扫描的列选码的初始化 MOV R4,#00H ;扫描列序号初始化
;显示子程序
DISPLAY:MOV R0,#6BH MOV R2,#0EFH DIS: MOV A,P2 ANL A,#0F0H SWAP A MOV 40H,A ;40H中存放P2口低四位状态 MOV A,R2 RL A MOV R2,A ANL A,#0F0H ORL A,40H MOV P2,A MOV A,@R0 MOV DPTR,#ZXM MOVC A,@A+DPTR MOV P0,A ACALL YS20ms DEC R0 CJNE R2,#7FH,DIS MOV R2,#0EFH MOV R0,#6BH RET
YS20ms: MOV R7,#40 ;延时20ms子程序 YS1: MOV R6,#229 DJNZ R6,$ DJNZ R7,YS1 RET
INDEXT1:DB 0CH,08H,04H,0H INDEXT2:DB 0DH,09H,05H,01H INDEXT3:DB 0EH,0AH,06H,02H INDEXT4:DB 0FH,0BH,07H,03H ZXM: DB 0C0H,0F9H,0A4H,0B0H,99H,92H,82H,0F8H,80H,90H DB 77H,83H,0C6H,0A1H,86H,81H
ENDS: NOP END
|