⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 01-15.asm

📁 基于51的多功能电子钟,多闹钟,温度测试
💻 ASM
📖 第 1 页 / 共 4 页
字号:
    CLR SDA       ;发送应答信号的数据信号
    SETB SCL      ;发送应答信号的时钟信号
    NOP           ; 等待》4.0US(即应答信号建立的时间大于4.0US)
    NOP
    NOP
    NOP
    NOP
                 ;发送应答信号完毕,数据线和时钟线复位
    CLR SCL
    RET
END



;================================================================

;名称:MNACK
;描述:发送反应答确认信号/ACK---读完所有字节后发,这样才能产生
;停止条件
;================================================================
PROC MNACK
MNACK:
     SETB SDA      ;发送反应答信号的数据信号

     SETB SCL
     ;发送应答信号的时钟信号
     NOP           ;等待》4.0US(即非应答信号建立的时间大于4.0US)
     NOP
     NOP
     NOP
     NOP           ;
     CLR SCL
     RET
END




;================================================================
;名称:CHECKACK
;描述:检查是否有应答位---本程序,是单片机产生额外的第九个时钟脉
;冲 ,在脉冲高电平时读应答位,有正常ACK置F0为0,否则为1
;================================================================
PROC CHECKACK
CHECKACK:
     SETB SDA       ;拉高数据线
     NOP
     NOP
     SETB SCL       ;拉高时钟线,第九个时钟脉冲开始
     NOP
     NOP
     MOV C,SDA      ;读数据线的状态
     MOV FINISH,C   ;转存到F0中(应答信号SDA为0,即F0=0有应答信号,F0=1没应答信号)
     NOP
     NOP
     CLR SCL        ;拉低时钟线,第九个时钟脉冲结束
     RET
END




;--------------------------------------------------------------
;            星期显示子程序
;--------------------------------------------------------------
PROC CONVER
CONVER:MOV A,#8DH       ; //星期显示地址
       LCALL WRITE_COM
       MOV R7,#00H

GODIS: CLR A
       MOV A,R7
       MOVC A,@A+DPTR
       JZ LOOP
       LCALL WRITE_DATA
       INC DPTR
       CJNE A,#04H,GODIS
LOOP:  RET
       END

;===========================
;LCD显示程序
;===========================
PROC DISP
DISP:
      MOV 60H,#20H
      MOV 65H,#3AH  ; //':'ASCII代码
      MOV 67H,#3AH  ; //':'ASCII代码
      MOV A,46H
      MOV 61H,A
      MOV A,45H
      MOV 62H,A
      MOV A,43H
      MOV 63H,A
      MOV A,42H
      MOV 64H,A
      MOV A,41H
      MOV 66H,A
      MOV A,40H
      MOV 68H,A
      MOV A,44H
      MOV 69H,A
;--------------------------------------------------------------
;             RT1602C开始显示程序
;--------------------------------------------------------------
      MOV A,#81H   ;//年显示地址,第一行第二位置开始
      LCALL WRITE_COM
      MOV R5,60H    ;//'20'送R5
      LCALL  BREAK
;--------------------------------------------------------------
      MOV A,#83H   ;//年显示地址
      LCALL WRITE_COM
      MOV R5,61H    ;//'06'
      LCALL BREAK
;--------------------------------------------------------------
      MOV A,#85H        ;显示"/"
      LCALL WRITE_COM
      MOV A,#02FH
      LCALL WRITE_DATA
;-------------------------------------------------------------
      MOV A,#86H   ;//月显示地址
      LCALL WRITE_COM
      MOV R5,62H    ;//'09'
     LCALL BREAK
;--------------------------------------------------------------
      MOV A,#88H        ;显示"/"
      LCALL WRITE_COM
      MOV  A,#02FH
      LCALL WRITE_DATA
;--------------------------------------------------------------
      MOV A,#89H   ;//日显示地址
      LCALL WRITE_COM
      MOV R5,63H    ;//'09'
      LCALL BREAK
;--------------------------------------------------------------
      MOV A,#0C4H   ;//时显示地址
      LCALL WRITE_COM
      MOV R5,64H    ;//'00'
      LCALL BREAK
;--------------------------------------------------------------
      MOV A,#0C6H   ;//":"显示地址
      LCALL WRITE_COM
      MOV A,65H    ;//':'
      LCALL WRITE_DATA
;--------------------------------------------------------------
      MOV A,#0C7H   ;//分显示地址
      LCALL WRITE_COM
      MOV R5,66H    ;//'00'
      LCALL BREAK
;--------------------------------------------------------------
      MOV A,#0C9H   ;//":"显示地址
      LCALL WRITE_COM
      MOV A,67H    ;//':'
      LCALL WRITE_DATA
;--------------------------------------------------------------
      MOV A,#0CAH   ;//秒显示地址
      LCALL WRITE_COM
      MOV R5,68H    ;//'00'
      LCALL BREAK
;--------------------------------------------------------------
       MOV R6,69H  ;=========星期显示,转换成字母显示
SUNDAY:CJNE R6,#00H,MONDAY
       MOV DPTR,#TAB0
       LCALL CONVER
MONDAY:CJNE R6,#01H,TUESDAY
       MOV DPTR,#TAB1
       LCALL CONVER
TUESDAY:CJNE R6,#02H,WEDSDAY
       MOV DPTR,#TAB2
       LCALL CONVER
WEDSDAY:CJNE R6,#03H,THURSDAY
       MOV DPTR,#TAB3
       LCALL CONVER
THURSDAY:CJNE R6,#04H,FRIDAY
       MOV DPTR,#TAB4
       LCALL CONVER
FRIDAY:CJNE R6,#05H,SATURDAY
       MOV DPTR,#TAB5
       LCALL CONVER
SATURDAY:CJNE R6,#06H,ENDDISP
       MOV DPTR,#TAB6
       LCALL CONVER
ENDDISP:
       RET
END

;--------------------------------------------------------------
;         把要显示的内容拆开分别送LCD显示子程序
;--------------------------------------------------------------
PROC BREAK
BREAK:MOV A,R5
      SWAP A        ;//=====显示十位
      ANL A,#0FH
      ADD A,#30H
      LCALL WRITE_DATA
      MOV A,R5       ; //=====显示个位
      ANL A,#0FH
      ADD A,#30H
      LCALL WRITE_DATA
      RET
END




;---------------------------------------------
;键盘输入子程序
;---------------------------------------------

PROC KEY
KEY:
     LCALL KEYCHECK          ;读键盘状态
                             ;检查键盘有无输入
     MOV A, KEYNAME
     JNB ACC.7, NEXT         ;ACC.7为0,键盘按键无效,就返回主程序
                             ;ACC.7为1,进入按键处理子程序
     MOV A, KEYNAME          ;读按键值
     ANL A, #1FH             ;保留
     MOV KEYNAME, A          ;清除按键处理标志
     LCALL KEYDO             ;进入按键处理子程序

NEXT:RET
END

;-----------------------------------------------
;键盘检测子程序
;-----------------------------------------------
PROC KEYCHECK
KEYCHECK:
    MOV DPTR, #PORTD         ;U105口地址送DPTR
    MOV A, PORTDR            ;读U105口在内存中的映象地址
    ANL A, #0E0H             ;输出全为低电平的扫描信号
    MOVX @DPTR, A            ;数据送U105输出口,将PD4~PD0置为低电平

    MOV DPTR, #PORTB         ;8255(U107)B口地址送DPTR
    MOVX A, @DPTR            ;读出B口
    ANL A, #0FH              ;屏蔽高4位
    CJNE A, #0FH, NEXT1
                             ;等于0F,说明没有按键被按下
    SETB C                   ;将C标志置1
    SJMP NEXT21
NEXT1:
    CLR C                    ;C标志清0
NEXT21:
    MOV A, KEYSTU
    RLC A                    ;左移一位,记录最新的按键状态
    ANL A, #07H              ;保留按键状态
    MOV KEYSTU, A            ;保存按键状态
                             ;判别按键状态,决定是否执行按键扫描
    CJNE A, #2, NEXT3
                             ;处于010态,视为按键过程中的无意松动,应作000态处理
    ANL KEYSTU, #0F8H
    SJMP NEXT4
NEXT3:
    CJNE A, #4, NEXT4
                             ;处于100态,说明按键已稳定闭合,可进行按键扫描
    LCALL KEYSCAN            ;执行键盘扫描,确定哪一按键被按下
NEXT4:
                             ;将PD4~PD0置为高电平,使74HC273输出级截止,降低功耗。
    MOV DPTR, #PORTD         ;U105口地址送DPTR
    MOV A, PORTDR            ;读U105口在内存中的映象地址
    ORL  A, #1FH
    MOVX @DPTR, A            ;数据送U105输出口
    RET
END


;------------------------------------------------
;键盘扫描子程序
;-------------------------------------------------

PROC KEYSCAN                 ;键盘扫描程序
KEYSCAN:
    MOV R7, #5               ;定义扫描次数
    MOV R1, #0               ;初始化列地址
    MOV R3, #01111111B       ;扫描码初值

LOOP1:
    ;生成扫描码
    MOV A, R3
    RL A                     ;左移一位(从PD0开始扫描)
    MOV R3, A                ;保存扫描码
    ANL A, #00011111B        ;保留扫描码
    MOV B, A                 ;暂时保存在B寄存器中

    MOV DPTR, #PORTD         ;U105口地址送DPTR
    MOV A, PORTDR            ;读U105口在内存中的映象地址
    ANL A, #0E0H             ;保留与键盘扫描无关的b7~b5位。
    ORL A, B                 ;与扫描码或
    MOVX @DPTR, A            ;数据送U105输出口,将PD4~PD0置为低电平
    NOP                      ;延迟一个机器周期等待输出口状态稳定

    MOV DPTR, #PORTB         ;B口地址送DPTR
    MOVX A, @DPTR            ;读B口
    ANL A, #0FH              ;屏蔽高4位
    XRL A, #0FH              ;与0FH异或
    JNZ NEXT1                ;不为0,说明该列上有键被按下
    ;反之,该列上没有按键被按下
    INC R1                   ;列地址加+1,继续扫描
    DJNZ R7, LOOP1
    ;已扫描了所有列,均没发现有键被按下,本次扫描无效
    SJMP EXIT

NEXT1:
    JNB ACC.0, NEXT22
    ;ACC.0位为1,说明0行有按键被按下
    MOV R2, #0               ;行地址为0
    SJMP NEXT5
NEXT22:
    JNB ACC.1, NEXT3
    ;ACC.1位为1,说明1行有按键被按下
    MOV R2, #1               ;行地址为1
    SJMP NEXT5
NEXT3:
    JNB ACC.2, NEXT4
    ;ACC.2位为1,说明2行有按键被按下
    MOV R2, #2               ;行地址为2
    SJMP NEXT5
NEXT4:
    ;Acc.2~Acc.0均为0,则可肯定是Acc.3为1
    MOV R2, #3               ;行地址为3
NEXT5:
    ;计算行列地址,查表取得键名
    MOV A, R1
    RL A
    RL A                   ;列地址乘4(每列对应4行)
    ADD A, R2              ;加行地址
    MOV DPTR, #KEYTAB
    MOVC A, @A+DPTR        ;查表获取键值
    MOV KEYNAME, A         ;按键值送键名寄存器
    ORL KEYNAME, #80H      ;按键有效标志置1
    ;开蜂鸣器,响一短声
    MOV DPTR, #8000H       ;开蜂鸣器
    MOV A, #0FFH
    MOVX @DPTR, A
    LCALL DEL10MS          ;响10ms,即250Ms
    MOV A,#0FFH
    MOVX @DPTR,A
EXIT:
    RET
END


;****** 启动LCM子程序******
PROC INITIAL
INITIAL:
        MOV A,#01H
        LCALL WRITE_COM
        MOV A,#00111000B
	LCALL WRITE_COM
	MOV A,#00001100B
	LCALL WRITE_COM
	MOV A,#00000110B
	LCALL WRITE_COM
	RET
END

;******查询忙碌标志信号子程序******
PROC CHECK_BUSY
CHECK_BUSY: 	PUSH ACC
BUSY_LOOP:
        MOV P2,#0FFH
	CLR E
	SETB R_W
	CLR RS
	SETB E
	MOV A, DB0_DB7
	CLR E
	JB ACC.7,BUSY_LOOP
	POP ACC
        RET
END

;****** 写指令到LCM子程序******
PROC WRITE_COM
WRITE_COM:
 	LCALL CHECK_BUSY
	CLR E
	CLR RS
	CLR R_W
	SETB E
	MOV DB0_DB7,A
	CLR E
	RET
        END


;****** 写数据到LCM子程序******
PROC WRITE_DATA
WRITE_DATA:
	LCALL CHECK_BUSY
	CLR E
	SETB RS
	CLR R_W
	SETB E
	MOV  DB0_DB7,A
	CLR E
	RET
        END


;===========================
;延时子程序
;==========================
PROC DEL10MS
DEL10MS:MOV R3,#10H
TX1:	MOV R4,#0FFH
        DJNZ R4,$
       	DJNZ R3,TX1
	RET
        END

PROC DEL5S
DEL5S: MOV DPTR ,#8000H
       MOV A,#01FH
       MOVX @DPTR,A
       MOV R7,#100
TX2:   LCALL KEYWAIT
       MOV A,KEYNAME
       CJNE A,#00H,EXIT
       LCALL DEL10MS
       DJNZ R7,TX2

EXIT:
       MOV DPTR,#8000H
       MOV A,#0FFH
       MOVX @DPTR,A
       MOV A,KEYNAME
       RET
END

PROC DEL2S
DEL2S:MOV R7,#50
TX3:  LCALL KEYCHECK
      MOV A,KEYNAME
      CJNE A,#00H,EXIT
      LCALL DEL10MS
      DJNZ R7,TX3
EXIT: MOV A,KEYNAME
      RET
END

TAB0:DB"Sun.",00H
TAB1:DB"Mon.",00H
TAB2:DB"Tue.",00H
TAB3:DB"Wed.",00H
TAB4:DB"Thu.",00H
TAB5:DB"Fri.",00H
TAB6:DB"Sat.",00H



;***********按键扫描码、键值对应关系******************
KEYTAB:
DB 0FH		;扫描码为0,即PD0与PB0交叉点对应数字键"F"
DB 0EH		;扫描码为1,即PD0与PB1交叉点对应数字键"E"
DB 0DH		;扫描码为2,即PD0与PB2交叉点对应数字键"D"
DB 0CH		;扫描码为3,即PD0与PB3交叉点对应数字键"C"

DB 09H		;扫描码为4,即PD1与PB0交叉点对应数字键"9"
DB 06H		;扫描码为5,即PD1与PB1交叉点对应数字键"6"
DB 03H		;扫描码为6,即PD1与PB2交叉点对应数字键"3"
DB 0BH		;扫描码为7,即PD1与PB3交叉点对应数字键"B"

DB 08H		;扫描码为8,即PD2与PB0交叉点对应数字键"8"
DB 05H		;扫描码为9,即PD2与PB1交叉点对应数字键"5"
DB 02H		;扫描码为A,即PD2与PB2交叉点对应数字键"2"
DB 15H		;扫描码为B,即PD2与PB3交叉点对应数字键"0"

DB 07H		;扫描码为C,即PD3与PB0交叉点对应数字键"7"
DB 04H		;扫描码为D,即PD3与PB1交叉点对应数字键"4"
DB 01H		;扫描码为E,即PD3与PB2交叉点对应数字键"1"
DB 0AH		;扫描码为F,即PD3与PB3交叉点对应数字键"A"

DB 13H		;扫描码为10,即PD4与PB0交叉点对应"↑"
DB 12H		;扫描码为11,即PD4与PB1交叉点对应"Enter"
DB 11H		;扫描码为12,即PD4与PB2交叉点对应"ESC"
DB 10H		;扫描码为13,即PD4与PB3交叉点对应"↓"



;-----------------------------------------------------
;字符串
;----------------------------------------------------
LINE1:DB "ENTER:SETTING", 00H
LINE2:DB "ESC:EXIT",00H
LINE3:DB "ERROR INPUT",00H

LINE4:DB "1:TIME",00H
LINE5:DB "2:CLOCK ",00H
LINE6:DB "ESC:EXIT ",00H

LINE7:DB "TIME OUT" ,00H
LINE8:DB " ANY KEY TO EXIT",00H
LINE9:DB"ALARM(  )",00H
LINE10:DB"OK",00H
LINE11:DB"NO",00H


LINE12:DB"1:SET",00H
LINE13:DB"2:DEL  ESC:EXIT",00H

LINE14:DB"1:WEAKLY",00H
LINE15:DB"2:ONCE  3:DAILY",00H

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -