📄 打电话1.asm
字号:
;;; 打电话实验
;;; 打电话.ASM
;;; MCU:89S51 COLCK:11.0592MHZ
;;; 实验目的:结合DTMF拨号实验,按键检测实验和继电器实验,拨打电话.
;;; 电话号码从键盘输入,挂机和摘机也从键盘上完成.
;;; 用LCD显示拨出的号码 。
;;; F键是摘机,E键是挂机
;;; 要把电话线插入J11的电话接口中.
;****************************************************************
;;;* 接线说明: *
;;;* 16*2的字符LCD插到LCD插座上 *
;;;* J10(25x2双排插针)第19脚(LCD-RS)和第20脚(CPU的P1.2)连 *
;;;* J10(25x2双排插针)第17脚(LCD-RW)和第18脚(CPU的P1.1)连 *
;;;* J10(25x2双排插针)第15脚(LCD-E)和第16脚(CPU的P1.0)连 *
;;;* J10(25x2双排插针)第21脚(LS)和第22脚(CPU的P1.3)连 *
;;;* J10(25x2双排插针)第43脚(DAT)和第40脚(CPU的P3.4)连 *
;;;* J10(25x2双排插针)第45脚(HCL)和第42脚(CPU的P3.5)连 *
;;;* J10(25x2双排插针)第47脚(CE1)和第44脚(CPU的P3.6)连 *
;;;* J10(25x2双排插针)第49脚(JK)和第46脚(CPU的P3.7)连 *
;;;* 注意JP的短路帽不要接 *
;****************************************************************
KEYOK BIT 20H
LS BIT P1.3;声音提示
TDATA EQU P3.4 ;数据输入
CLK EQU P3.5 ;同步时钟输入
CE EQU P3.6 ;片选
COUNT EQU 30H ;要发送DTMF信号的数量(如要发送10个DTMF的信号那30H=0AH)
DTMFDATA EQU 31H ; 要发送DTMF数据的缓冲区
K EQU P3.7 ;高电平为挂机,低电平为摘机可进行拨号
RXD1 EQU P3.0
RS EQU P1.2 ;LCD
RW EQU P1.1 ;LCD
E EQU P1.0 ;LCD
TELOK BIT 21H
ORG 0000H
AJMP MAIN
ORG 0080H
MAIN: ;LCD初始化
MOV P2,#01H;清除屏幕
ACALL ENABLE
MOV P2,#38H;8位点阵方式
ACALL ENABLE
MOV P2,#0FH;开显示
ACALL ENABLE
MOV P2,#06H;移动光标
ACALL ENABLE
MOV P2,#01H;清除屏幕
ACALL ENABLE
MOV P2,#80H;第一行显示位置
ACALL ENABLE
mov dptr,#tabl1;送数据表1: TEL:
call write1
;ACALL DISPLA
MOV A,#0FFH
MOV A,#13
MOV R1,#50H
MOV R0,#16
MAINN: MOV @R1,A
INC R1
DJNZ R0,MAINN
SETB K ;挂机
SETB TELOK
SETB RXD1
ACALL A200MS ; 延时200MS
ACALL A200MS ; 延时200MS
ACALL A200MS ; 延时200MS
ACALL A200MS ; 延时200MS
ACALL A200MS ; 延时200MS
ACALL A200MS ; 延时200MS
MAIN0: ACALL KEY ;按键检测
MOV R1,A ; 保存
XRL A,#0FH ;如是F键摘机
JNZ MAIN0 ;不是返回
CLR K ;摘机
CLR RXD1
CLR TELOK
ACALL A200MS ; 延时200MS
ACALL A200MS ; 延时200MS
ACALL A200MS ; 延时200MS
MAIN1: ACALL KEY ;按键检测
MOV R1,A ; 保存
XRL A,#0EH
JZ MAIN ;E键挂机
MOV A,R1
CLR C
SUBB A,#12;#0AH
JNC MAIN1 ;按键不在0-9,*,#内从新检测;0-9内从新检测
CLR C
MOV A,R1
JNZ MAIN2
MOV A,#0AH ;"0AH"是0的DTMF码
AJMP MAIN4 ;
MAIN2:SUBB A,#0AH ;判断按键是不是为"#,* " ,如是数值加一
JC MAIN3 ;
MOV A,R1 ;
INC A ;
AJMP MAIN4
MAIN3:MOV A,R1
MAIN4:CLR CE ;片选,使HT9200工作
SETB CLK
CALL A200MS ;使HT9200的晶振稳定工作
ACALL DTMFASM1 ; ;发送DTMF数据
ACALL A200MS
ACALL A200MS
MOV A,#0FFH ;关闭DTMF
ACALL DTMFASM1 ;发送DTMF数据
ACALL A200MS
SETB CE
AJMP MAIN1
;;;;;;;发送一个DTMF数据
DTMFASM1: MOV R1,#05H ;发送5位数据
SETB CLK
DTMFASM2: RRC A
JC DTMFASM3
CLR TDATA ;发送0
AJMP DTMFASM4
DTMFASM3: ;发送1
SETB TDATA
DTMFASM4: CLR CLK ;CLK下降沿发送数据
NOP
NOP
SETB CLK
DJNZ R1,DTMFASM2
RET
A200MS: ;200MS延时
MOV R6,#00
A200MS1: MOV R7,#0EFH
A200MS2: NOP
DJNZ R7,A200MS2
DJNZ R6,A200MS1
RET
;;;;;;;按键检测子程序
;;;;;;;入口参数:无
;;;;;;;返回值 :A(按键的数据),KEYOK(没按则KEYOK=1,有按则KEYOK=0)
;;;;;;; 占用 :A,P0,R7,KEYOK ,LS
;;;;;;;注意:KEYOK,LS要预先定义
KEY: SETB KEYOK ; 设KEYOK=1
MOV P0,#0F0H ;
NOP
NOP
MOV A,P0 ;读按键
XRL A,#0F0H ;判断是否有键按下?
JNZ KEY00 ;有转
KEY0: AJMP KEY;RET ;没有返回
KEY00: ACALL A10MS ;延时10MS
MOV A,P0 ;键盘去抖动
XRL A,#0F0H
JZ KEY0
;;;;判断是哪个键按下,为了直观一点程序就直接判断引脚的电平
KEY1: MOV P0,#11101111B;判断第一列是否有键按下?
NOP
JB P0.0,KEY2 ;K1没按下转
MOV A,#01H
AJMP KEYW ;转等待判按键释放
KEY2: JB P0.1,KEY3
MOV A,#04H
AJMP KEYW
KEY3: JB P0.2,KEY4
MOV A,#07H
AJMP KEYW
KEY4: JB P0.3,KEY5
MOV A,#0AH
AJMP KEYW
;判断第2列是否有键按下?
KEY5: MOV P0,#11011111B ;
NOP
JB P0.0,KEY6 ;K1没按下转
MOV A,#02H
AJMP KEYW ;转等待判按键释放
KEY6: JB P0.1,KEY7
MOV A,#05H
AJMP KEYW
KEY7: JB P0.2,KEY8
MOV A,#08H
AJMP KEYW
KEY8: JB P0.3,KEY9
MOV A,#00H
AJMP KEYW
;判断第3列是否有键按下?
KEY9: MOV P0,#10111111B ;
NOP
JB P0.0,KEY10 ;K1没按下转
MOV A,#03H
AJMP KEYW ;转等待判按键释放
KEY10: JB P0.1,KEY11
MOV A,#06H
AJMP KEYW
KEY11: JB P0.2,KEY12
MOV A,#09H
AJMP KEYW
KEY12: JB P0.3,KEY13
MOV A,#0BH
AJMP KEYW
;判断第4列是否有键按下?
KEY13: MOV P0,#01111111B
NOP
JB P0.0,KEY14 ;K1没按下转
MOV A,#0CH
AJMP KEYW ;转等待判按键释放
KEY14: JB P0.1,KEY15
MOV A,#0DH
AJMP KEYW
KEY15: JB P0.2,KEY16
MOV A,#0EH
AJMP KEYW
KEY16: MOV A,#0FH
KEYW :; 等待判按键释放
CLR LS ;声音提示
MOV R2,A
PUSH 0e0h ;键值进行保护
JB TELOK,KEYW3;未攒机不显示按键的数值
CLR C
SUBB A,#12;#0AH
JNC KEYW3 ;按键不在0-9,*,#内则不显示
;;;;更新LCD显示寄存器
MOV R3,#0FH
MOV R1,#50H
MOV R0,#51H
KEYW2:MOV A,@R0
MOV @R1,A
INC R0
INC R1
DJNZ R3,KEYW2
MOV A,R2
MOV @R1,A
KEYW1: ACALL DISPLA ;调用显示子程序,这是防止键长期按住不放时以免影响LED或LCD的正常显示
KEYW3: MOV P0,#0F0H
NOP
NOP
MOV A,P0 ;读按键
XRL A,#0F0H ;判断是否有按键释放
JNZ KEYW3 ;
ACALL A10MS
MOV A,P0 ;读按键
XRL A,#0F0H ;判断是否有按键释放
JNZ KEYW3
POP 0e0h
CLR KEYOK
SETB LS ;关闭提示音
RET ;返回
A10MS: MOV R6,#09
A10MS1: MOV R7,#0FFH
A10MS2: NOP
NOP
DJNZ R7,A10MS2
DJNZ R6,A10MS1
RET
write1: ;写数据
mov r1,#00h
a1: mov a,r1
movc a,@a+dptr
call write2
inc r1
cjne a,#00h,a1
ret
write2:
mov P2,a
setb rs
clr rw
clr e
call delay
setb e
ret
ENABLE:
CLR RS
CLR RW
CLR E
ACALL DELAY
SETB E
RET
delay: ;写延时,等待写完成
mov r7,#30
d1: mov r6,#25
d2: djnz r6,d2
djnz r7,d1
ret
DISPLA: mov P2,#0c0h;第二行的位置
call enable
MOV R1,#50H ;LCD显示子程序
MOV R0,#10H
MOV DPTR,#TABL2
A2: MOV A,@R1
MOVC A,@A+DPTR
ACALL WRITE2
INC R1
DJNZ R0,A2
RET
TABL1:DB 20H,20H,20H,20H,20H,20H,54h,45h,4Ch,3Ah, 20H,20H,20H,20H,20H,20H,00H
TABL2:DB 30H,31H,32H,33H,34H,35H,36H,37H,38H,39H,"*","#",20H,20H,20H,20H,20H,20H
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -