📄 alarm.txt
字号:
mov 55h,54h
mout:
lcall display
mov 54h,#0ffh
pop 00h
pop psw
pop acc
ret
;55,56,57,58 // 按下键59H++ 按下#时清零 54H为键值
display:
mov a,58h
lcall disp_seg
MOV 21H,#7FH
CLR LED2
MOV A,21H
mov sbuf,a
mov 30h,#1 ;1 5
lcall delay1ms
clr ti
mov a,57h
lcall disp_seg
MOV 21H,#0fFH
clr LED7
CLR LED2
MOV A,21H
mov sbuf,a
mov 30h,#1 ;1 5
lcall delay1ms
clr ti
mov a,56h
lcall disp_seg
MOV 21H,#0FFH
CLR LED6
CLR LED2
MOV A,21H
mov sbuf,a
mov 30h,#1 ;1 5
lcall delay1ms
clr ti
mov a,55h
lcall disp_seg
MOV 21H,#0FFH
CLR LED5
CLR LED2
MOV A,21H
mov sbuf,a
mov 30h,#1 ;1 5
lcall delay1ms
clr ti
;关显示
mov a,#10h
lcall disp_seg
mov 30h,#2
lcall delay5ms
ret
;=====================================================================
disp_seg:
push acc
push 00h
push psw
mov dptr,#tab_led
movc a,@a+dptr
mov r0,#8
rep8:
rlc a ;?????????????????
mov seg_dat,c
nop
nop
clr seg_clk
setb seg_clk
djnz r0,rep8
pop psw
pop 00h
pop acc
ret
tab_led:
db 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h
; 0 1 2 3 4 5 6 7
db 80h,90h,81h,0f7h,0f7h,0f7h,0f7h,0f7h
; 8 9 #/a b c d e f
db 0ffh,0a1h,8ch
; 10 11 12
;=================================
;启动I2C总线子程序
START: SETB SDA
NOP
SETB SCL ;起始条件建立时间大于4.7us
NOP
NOP
NOP
NOP
NOP
CLR SDA
NOP ;起始条件锁定时大于4us
NOP
NOP
NOP
NOP
CLR SCL ;钳住总线,准备发数据
NOP
RET
;结束总线子程序
STOP: CLR SDA
NOP
SETB SCL ;发送结束条件的时钟信号
NOP ;结束总线时间大于4us
NOP
NOP
NOP
NOP
SETB SDA ;结束总线
NOP ;保证一个终止信号和起始信号的空闲时间大于4.7us
NOP
NOP
NOP
RET
;发送应答信号子程序
MACK: CLR SDA ;将SDA置0
NOP
NOP
SETB SCL
NOP ;保持数据时间,即SCL为高时间大于4.7us
NOP
NOP
NOP
NOP
CLR SCL
NOP
NOP
RET
;发送非应答信号
MNACK: SETB SDA ;将SDA置1
NOP
NOP
SETB SCL
NOP
NOP ;保持数据时间,即SCL为高时间大于4.7us
NOP
NOP
NOP
CLR SCL
NOP
NOP
RET
;检查应答位子程序
;返回值,ACK=1时表示有应答
CACK: SETB SDA
NOP
NOP
SETB SCL
CLR ACK
NOP
NOP
MOV C,SDA
JC CEND
SETB ACK ;判断应答位
CEND: NOP
CLR SCL
NOP
RET
;发送字节子程序
;字节数据放入ACC
;每发送一字节要调用一次CACK子程序,取应答位
WRBYTE: MOV R0,#08H
WLP: RLC A ;取数据位
JC WR1
SJMP WR00 ;判断数据位
WLP1: DJNZ R0,WLP
NOP
RET
WR1: SETB SDA ;发送1
NOP
SETB SCL
NOP
NOP
NOP
NOP
NOP
CLR SCL
SJMP WLP1
WR00: CLR SDA ;发送0
NOP
SETB SCL
NOP
NOP
NOP
NOP
NOP
CLR SCL
SJMP WLP1
;读取字节子程序
;读出的值在ACC
;每取一字节要发送一个应答/非应答信号
RDBYTE: MOV R0,#08H
RLP: SETB SDA
NOP
SETB SCL ;时钟线为高,接收数据位
NOP
NOP
MOV C,SDA ;读取数据位
MOV A,R2
nop
nop
CLR SCL ;将SCL拉低,时间大于4.7us
nop
nop
RLC A ;进行数据位的处理
MOV R2,A
NOP
NOP
NOP
DJNZ R0,RLP ;未够8位,再来一次
RET
;========================================================================================
;========================================================================================
; 以下是用户接口子程序
;向器件指定子地址写N字节数据
;入口参数: 器件从地址SLA、器件子地址SUBA 、发送数据缓冲区MTD、发送字节数NUMBYTE
; 占用: A 、R0 、R1 、R3 、CY
IWRNBYTE: MOV A,#1
MOV R3,A
LCALL START ;起动总线
MOV A,#0a0h
LCALL WRBYTE ;发送器件从地址
LCALL CACK
JNB ACK,RETWRN ;无应答则退出
MOV A,r6 ;指定子地址
LCALL WRBYTE
LCALL CACK
MOV R1,#MTD
WRDA: MOV A,@R1
LCALL WRBYTE ;开始写入数据
LCALL CACK
JNB ACK,IWRNBYTE
INC R1
DJNZ R3,WRDA ;判断写完没有
RETWRN: LCALL STOP
RET
;向器件指定子地址读取N字节数据
;入口参数: 器件从地址SLA、器件子地址SUBA、接收字节数NUMBYTE
;出口参数: 接收数据缓冲区MRD
;占用:A、 R0、 R1、 R2、 R3、 CY
IRDNBYTE: MOV R3,#1
LCALL START
MOV A,#0a0h
LCALL WRBYTE ;发送器件从地址
LCALL CACK
JNB ACK,RETRDN
MOV A,r6 ;指定子地址
LCALL WRBYTE
LCALL CACK
LCALL START ;重新起动总线
MOV A,#0a0h
INC A ;准备进行读操作
LCALL WRBYTE
LCALL CACK
JNB ACK,IRDNBYTE
MOV R1,#MRD
RDN1: LCALL RDBYTE ;读操作开始
MOV @R1,A
DJNZ R3,SACK
LCALL MNACK ;最后一字节发非应答位
RETRDN: LCALL STOP ;并结束总线
RET
SACK: LCALL MACK
INC R1
SJMP RDN1
;================拨号================
out_dtmf:
mov dptr,#dialtable
movc a,@a+dptr
mov r0,#5
rep5:
rrc a
mov dtmf_dat,c
clr dtmf_clk
setb dtmf_clk
djnz r0,rep5
ret
dialtable: db 0ah,01h,02h,03h,04h,05h,06h,07h,08h,09h,0ch
; 0 1 2 3 4 5 6 7 8 9 #/a
;==============================================
delay10ms:
MOV R3,#30H
delay2:
mov R7,#32H
delay1:
DJNZ R7,delay1
DJNZ R3,delay2
DJNZ 30H,delay10ms
RET
delay5ms:
push 01h
push 02h
delay5:
MOV R2,#50
delay21:
mov R1,#25
delay11:
DJNZ R1,delay11
DJNZ R2,delay21
DJNZ 30H,delay5
pop 02h
pop 01h
RET
delay1ms:
push 01h
push 02h
delay6:
MOV R2,#20
delay3:
mov R1,#25
delay4:
DJNZ R1,delay4
DJNZ R2,delay3
DJNZ 30H,delay6
pop 02h
pop 01h
RET
;==========================================================
beep:
clr P3.5
mov 30h,#10
lcall delay5ms
setb P3.5
mov 30h,#20
lcall delay5ms
ret
beeplong:
clr P3.5
mov 30h,#50
lcall delay5ms
setb P3.5
ret
;==============================================
findkey: CPL P3.6
mov p0,#0ffh
MOV 54H,#0FFH
clr keyflag ;无键按下为 0 ; 有键按下清 1
mov P0,#0f0h
mov a,P0
cjne a,#0f0h,check
ljmp findkey_out
check:
mov 30h,#4
lcall delay5ms
mov a,P0
cjne a,#0f0h,keydown
ljmp findkey_out
keydown:
mov p0,#0f0h ;行啦低 列啦高
mov a,P0 ;主要想保存p0的 低四位
jb p0.4,findkey_0
setb keyflag
mov dptr,#tab_0
ljmp findkey_end
findkey_0:
jb p0.5,findkey_1
setb keyflag
mov dptr,#tab_1
ljmp findkey_end
findkey_1:
jb p0.6,findkey_2
setb keyflag
mov dptr,#tab_2
ljmp findkey_end
findkey_2:
jb p0.7,findkey_out
setb keyflag
mov dptr,#tab_3
findkey_end:
mov p0,#0fh
mov a,p0
cpl a
anl a,#0fh
movc a,@a+dptr ;得到键值
mov 54h,a ;拨号后 键值保存在54h
setb ea
clr time_out1
mov 7dh,#00
setb tr1
findkey_wait:
CPL P3.6
mov p0,#0f0h
nop
mov a,p0
jnb time_out1,out2003
jb leavehand,out2003
lcall beep
setb leavehand
out2003:
cjne a,#0f0h,findkey_wait
findkey_out:
mov a,54h
clr leavehand
clr tr1
ret
tab_0:
db 00h,01h,04h,00h,07h,00h,00h,00h,00h
tab_1:
db 00h,02h,05h,00h,08h,00h,00h,00h,0bh
tab_2:
db 00h,03h,06h,00h,09h,00h,00h,00h,0fh
tab_3:
db 00h,0ch,0dh,00h,0eh,00h,00h,00h,0ah
org 0f00h
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
ljmp main
end
太长了!
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -