📄 01-15.asm
字号:
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 + -