在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
芯片精品文章合集(500篇!) 创芯人才网--重磅上线啦!
查看: 1716|回复: 0

求助啊

[复制链接]
发表于 2007-10-24 18:36:11 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
本人做了一个LCD密码锁程序,但有点问题,请大哥大姐门指教
;===========电子密码锁程序==============================
;       
        KA         EQU 0AH                        ;按键定义               
        KB         EQU 0BH
        KC         EQU 0CH
        KD         EQU 0DH
        KE         EQU 0EH
        KF         EQU 0FH

        PASS         EQU 30H                        ;密码存储位置30到33H
        PASSNEW EQU 34H                        ;存放新的密码
        BUF_KEY EQU 4AH                        ;按键数据缓冲区
        KEY_NO  EQU 4BH                        ;按键编号
        CO          EQU 4CH                        ;计数变量
        LCDE        EQU 4DH                         ;LCD延迟变量
        X        EQU 53H                         ;LCD显示地址
        FKEY        EQU 20H.0                 ;按键标志
        EN         EQU P0.1                ;LCD的引脚定义
        RS        EQU P0.0
        SPK        EQU P3.6                      ;剌叭的引脚定义
        REL        EQU P3.5                ;继电器的引脚定义
        WLED         EQU P3.7                      ;工作指示灯的定义

        ORG         00H
        JMP     BEGIN                        ;程序开始
BEGIN:
        CALL        INIT_PORT
        CALL        LED_BL                        ;LED闪烁,程序开始
        CALL        BZ
        CALL        SET_LCD                        ;LCD初始化
        CALL        MLOOP                        ;执行主控程序
        JMP        $

MESS:         DB "LP1.ASM 8051 PASSWORD WITH LCD"
PASS0:         DB 1,2,3,4                        ;内设的四位密码

;延迟子程序
DELAY:
    MOV R6,#50
D1: MOV R7,#100
         DJNZ R7,$
         DJNZ R6,D1
         DJNZ R5,DELAY
        RET
;==========LED工作闪烁灯=--------------
LED_BL:
             MOV R4,#6
  LE0:
          CPL WLED                ;位取反
        MOV R5,#30                ;延迟的时间为30ms               
        CALL DELAY
        DJNZ R4,LE0
        RET
;=====键盘按键编码====================
TABLE_DIG:
   DB  0FH,0BH,0AH,00H
   DB  0EH,03H,02H,01H
   DB  0DH,06H,05H,04H
   DB  0CH,09H,08H,07H
;============键盘的扫描子程序================
SCAN:
   MOV R3,#0FEH                        ;加载扫描信号初值1111 1110
   MOV R1,#4                        ;执行一次循环四次
   CLR PSW.5                        ;psw.5=0表示没有键按下                       
L1:
            MOV A,R3                ;将扫描信号的值放入累加器中
        MOV P2,A                ;将其值由P2口输出
        MOV  A,P2
        MOV R5,#1                ;延迟10MS
        CALL DELAY
        MOV A,P2                ;读取P2数据以便判断是否有键按下
        ANL  A,#0F0H                ;取得高四位值
        MOV R2,#4                ;循环2执行四次
L2:
            JB ACC.4,N1                ;累加器A位1若为1表示没按键
        MOV KEY_NO,R4                ;加载按键编号
        SETB PSW.5                ;按键标志设为1
N1:         INC R4                        ;按键编号加1
            RR  A                        ;累加器A右移一位扫描下一个按键
        DJNZ R2,L2                ;判断行是否扫描完成,未扫描完成则继续
        MOV  A,R3                ;扫描完成则重新加载初值
        RL  A                        ;左移一位,则左移一位后变成0111,1111
        MOV R3,A                ;将变化后的的值放入R3中
        DJNZ R1,L1                ;循环1判断是否继续执行
; 按键标志
BACK:
            JNB PSW.5,NO_KEY        ;设置是否按键
        SETB FKEY                ;若有按键则设其为1
        RET
;没有按键则清标志
NO_KEY:
    CLR FKEY
        RET
;扫描键盘是否按下,然后
SCAN_KEY:
            CLR  FKEY                ;清除按键标志
        CALL SCAN                ;执行按键扫描
        JB FKEY,WAIT_OFF        ;测试按键标志
        RET
WAIT_OFF:
            CALL SCAN                ;执行按键扫描
        JB FKEY,WAIT_OFF        ;若有按键等待按键放开
        RET
;等 待按键并传回按键码
GET_KEY:
        CLR  FKEY                ;清标志
        CALL SCAN
        JB   FKEY,G1                ;测试按键标志
        JMP  GET_KEY                ;没有按下则继续扫描
G1:
            CALL SCAN                  
        JB FKEY,G1                ;按键是否放开
        MOV A,KEY_NO
        MOV DPTR,#TABLE_DIG        ;经过取表找出按键码
        MOVC A,@A+DPTR
        RET
;显示新的密码
LOOK:
        MOV CO,#4                ;显示输入的密码
        MOV R0,#PASSNEW                ;指向密码存放的变量区
L01:
            MOV A,@R0                ;取出密码值
        INC R0                        ;指向下一个变量区
        DJNZ CO,L01                ;是否完成四位
        RET
;===密码比较程序=================
CHECK_PASS:
            CALL IP_PASS                ;取得要比较的密码
        CALL LOOK                ;显示要输入的密码
        MOV  CO,#4
        MOV  R0,#PASS
        MOV  DPTR,#PASS0
CH1:
            MOV A,#0
        MOVC A,@A+DPTR
        MOV B,@R0
        CJNE A,B,CH2
        INC DPTR
        INC R0
        DJNZ CO,CH1
        CALL OK
        CALL LED_BL
        CALL LED_BL
        RET
CH2:
            JMP COMP                ;继续比较内部所设置的密码
ERROR:
        CALL ERR                ;密码错误处理
        CALL LED_BL
        RET
COMP:
        MOV CO,#4
        MOV R0,#PASS
        MOV R1,#PASSNEW
C1:
   MOV A,@R0
   MOV B,@R1
   CJNE A,B,ERROR
   INC R0
   INC R1
   DJNZ CO,C1
   CALL OK
   RET
;===输入四位密码值
IP_PASS:
   MOV DPTR,#M_IP
   MOV A,#2
   CALL LCD_PRINT                ;在LCD上执行显示信息
   MOV  B,#9                        ;设置LCD的位置
   MOV  CO,#4
   MOV  R0,#PASS
I1:         CALL GET_KEY
            MOV @R0,A
        ADD A,#30H                ;转换字符
        CALL LCDP2               
        INC  B
        INC R0
        DJNZ CO,I1
        RET

OK:         MOV DPTR,#M_OK
        MOV A,#2
        CALL LCD_PRINT
        CALL DOOR_OPEN
        RET
ERR:
            MOV DPTR,#M_ERR
        MOV A,#2
        CALL LCD_PRINT
        CALL ALARM
        RET
SLINE2:                                ;在第二行上显示信息
            MOV DPTR,#LMESS2
        MOV A,#2
        CALL LCD_PRINT
        RET
;-----设置新的密码===========
SET_PASS:
        MOV DPTR,#M_IP_NEW
        MOV A,#2
        CALL LCD_PRINT
        MOV B,#12
        MOV  CO,#4
        MOV  R0,#PASSNEW
S1:
        CALL GET_KEY
        MOV @R0,A
        ADD A,#30H
        CALL LCDP2
        INC B
        INC R0
        DJNZ CO,S1
        RET

  M_IP: DB "I/P PASS : ....  ",0
  M_OK: DB "PASSWORD OK !!!  ",0
  M_ERR: DB "PASSWORD ERROR  !",0
  M_IP_NEW: DB"I/P NEWPASS:...",0
;显示内部密码在LCD上
LOOK_PASS:
        MOV B,#0
          MOV CO,#4
            MOV R0,#PASSNEW
LL:
        MOV A,@R0
        ADD A,#30H
          CALL LCDP2
        INC R0
        INC B
        DJNZ CO,LL
        MOV R5,#100
        CALL DELAY
        CALL SLINE2
        RET
;继电器开,关
REL_ON:
        SETB REL
        RET
REL_OFF:
        CLR        REL
        RET
;初始化输入输出口
INIT_PORT:
        CALL REL_OFF
        RET
;继电器开启
DOOR_OPEN:
        MOV  R5,#200
        CALL DELAY
        CALL REL_OFF
        RET
;警告声
ALARM:
        MOV  R2,#3
AL1:
        CALL LED_BL
        CALL BZ
        DJNZ R2,AL1
        RET
;蜂鸣器响
BZ:         MOV R6,#0
B1:         CALL DEL
        CPL  SPK
        DJNZ R6,B1
        RET

DEL: MOV R7,#180
DE1: NOP
         DJNZ R7,DE1
         RET

;主程序控制
MLOOP:
        CALL GET_KEY
        CJNE A,#KA,M1
        CALL SET_PASS
        CALL SLINE2
        JMP  MLOOP
M1:         CJNE A,#KB,M2
        CALL  CHECK_PASS
        CALL  SLINE2
        JMP  MLOOP
M2:         JMP  MLOOP
        RET
;LCD初始化
SET_LCD:
        CLR EN                        ;启用失效
        CALL INIT_LCD
        MOV        R5,#10
        CALL DELAY
        MOV DPTR,#LMESS1
        MOV A,#1
        CALL LCD_PRINT
        MOV DPTR,#LMESS2
        MOV A,#2
        CALL LCD_PRINT
        RET
LMESS1: DB "8051 PASSWORD  ",0
LMESS2: DB "A OR B KEY ....",0
;初始化LCD
INIT_LCD1:
        MOV A,#28H                ;双列显示
        CALL WCOM                ;调用写命令
        MOV A,#0CH                ;光标移动不闪烁
        CALL WCOM
        MOV A,#0EH                ;每次向右移动一位,显示屏不移动
        CALL WCOM
        MOV A,#01H                ;清除LCD显示屏
        CALL WCOM
        RET
LCD_PRINT:
        CJNE A,#1,LINE2                                        ;判断第一行是否显示完
   LINE1:        
           MOV A,#80H                                        ;设置第一行显示地址
              CALL WCOM                                        ;调用写地址
              CALL CLR_LINE                                        ;清除该行字符数据
              MOV A,#80H                                        ;写入命令
              CALL WCOM
              JMP FILL                                       
                     
  LINE2:
          MOV A,#0C0H                                        ;设置第二行显示地址
          CALL WCOM
          CALL CLR_LINE                                        ;调用清除命令
          MOV A,#0C0H
          CALL WCOM
   FILL:                                                 ;填入字符
        CLR A                                                ;
        MOVC A,@A+DPTR                                        ;由消息区取出字符
        CJNE A,#0,LC1                                        ;决断是否为结束码
        RET
        
   LC1:
             CALL WDATA                                        ;写入数据
             INC DPTR                                        ;数据指针加1
            JMP FILL
            RET
   ;************************************行清除***************************************  
  CLR_LINE:
                MOV         R0,#24                                        ;清除该行LCD字符
  CL1:         MOV         A, #' '                                        ;填上空格字符
               CALL         WDATA                                        ;调用写入数据
                DJNZ         R0,CL1                                        ;判断计数器是否满
               RET
      
  DE: MOV R7,#5                                                ;短暂延迟
      DJNZ R7,$
      RET
;*************************************短暂脉冲产生启用信号****************************     
  EN1:
      SETB EN                                                ;启用E
      CALL DE
      CLR  EN
      CALL DE
      RET
  ;*********************************LCD初始化******************************************  
INIT_LCD:
            MOV P0,#30H                                ;4位数据输入输出口初始化D7_D4
            CALL EN1
            MOV P0,#30H
            CALL EN1
            MOV P0,#30H
            CALL EN1
            MOV P0,#20H
            CALL EN1
            CALL INIT_LCD1
            RET
;*******************************写入指令**********************************************   
  WCOM:
            MOV P0,A                                ;以四位从P0口输出
            CLR RS                                        ;写指令
            CALL EN1
            RLC A                                        ;左移四位
            RLC A
            RLC A
            RLC A
            MOV P0,A                                ;从P0口输出
            CLR RS
            CALL EN1
            RET
;**************************写入数据***************************************************   
  WDATA:
            MOV P0,A                                ;从P0口输出数据
            SETB RS                                        ;设置写数据
            CALL EN1
            RLC A                                        ;左移四位
            RLC A
            RLC A
            RLC A
            MOV P0,A
            SETB RS
            CALL EN1
            RET
;**********************************************************************************
;***************************在LCD第一行显示字符************************************
LCDP1:
           PUSH ACC                                        ;将A放入堆栈
           MOV A,B
           ADD A,#80H
           CALL WCOM
           POP ACC
           CALL WDATA
           RET
;****************************************************************************  
;*********************888888LCD第二行显示字符*********************************
LCDP2:
           PUSH ACC
           MOV A,B
           ADD A,#0C0H
           CALL WCOM
           POP ACC
           CALL WDATA
           RET                               



        END
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条

小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-16 19:38 , Processed in 0.014595 second(s), 9 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表