📄 mt8880
字号:
;这些是程序中MT8880相关操作的函数源代码可能一些地方需要整理一下
;I/O口使用情况:
P_DT EQU P0 ;MT8880的数据线(低4位有效)
P_CLK EQU P1.0 ;输出MT8880的时钟clock2
P_RW EQU P1.1 ;输出MT8880的读写选择(1:读,0:写)
P_CS EQU P1.2 ;输出MT8880的片选
P_RS EQU P1.3 ;输出MT8880的寄存器选择(1:控制,0:数据)
P_HOOK EQU P1.4 ;输出电话线路接入控制(0:接起线路,1:断开线路)
P_PHON EQU P1.5 ;输出电话机接入控制(0:接入话机,1:断开话机)
P_LED EQU P1.6 ;输出发光二极管控制(0:亮,1:灭)
P_RING EQU P1.7 ;输入电话线路响铃(0:有响铃)
P_BELL EQU P2.3 ;输出接电话提示铃声控制(0:响)
P_IRQ EQU P2.7 ;输入MT8880的中断
P_PHST EQU P3.6 ;输入电话机状态(0:电话机目前拿起,1:放下)
;================================================================
;ADDRESS: RAM内存地址说明:
SPADR EQU 60H ;SP Init Address 堆栈区底
DT_BUF_ EQU 5FH ;数据缓冲区顶
DT_BUF EQU 40H ;数据缓冲区底
MT_TMP EQU 34H ;MT8880临时变量
MT_8B EQU 33H ;MT8880临时变量
;----------------------------------------------------------------
;ID ADRESSES: 标志位的位地址:(字节地址对应20H-2FH)
ERRID EQU 0BH ;函数调用错误返回标志(1:错误)
RSID EQU 0AH ;读写MT8880的寄存器地址(1:控制,0:数据)
BIT7ID EQU 07H ;位变量的7位
BIT6ID EQU 06H ;位变量的6位
BIT5ID EQU 05H ;位变量的5位
BIT4ID EQU 04H ;位变量的4位
BIT3ID EQU 03H ;位变量的3位
BIT2ID EQU 02H ;位变量的2位
BIT1ID EQU 01H ;位变量的1位
BIT0ID EQU 00H ;位变量的0位
BIT_VAR EQU 20H ;位变量字节地址
;---------------------------------------------------------------
;VAR: 寄存器变量说明:
;R0: 缓冲区指针
;R1: 数据缓冲区专用指针
;R2:
;R3:
;R4:
;R5: 读写MT8880的数据(低4位有效)
;R6: 辅助计数器
;R7: 计数器
;B: 位计数器
;--------------------------------------------------------------
;CONST: 常量说明:
REDAIL EQU 10 ;重拨次数
;==============================================================
;SUB: 子程序说明:
;READMT_SUB 读MT8880函数
;WRITEMT_SUB 写MT8880函数
;SMTIN_SUB 初始化MT8880为接收函数
;SMTOUT_SUB 初始化MT8880为发送函数
;SMTCHK_SUB 初始化MT8880为检测函数
;CHKCP_SUB MT8880检测声音函数(ERRID=0则有声音)
;DAIL_SUB MT8880拨号函数
;=============================================================
;读MT8880函数:
READMT_SUB: CLR P_CLK
SETB P_CS
SETB P_RS
JB RSID,READMT_RS
CLR P_RS
READMT_RS: SETB P_RW
CLR P_CS
SETB P_CLK
NOP
MOV A,P_DT
ANL A,#0FH ;低4位有效
MOV R5,A
CLR P_CLK
SETB P_CS
RET
;-----------------------------------------------------------
;写MT8880函数:
WRITEMT_SUB: CLR P_CLK
SETB P_CS
MOV A,P_DT
ANL A,#0F0H
ORL A,#0FH ;将数据线置为输入
MOV P_DT,A
SETB P_RS
JB RSID,WRITEMT_RS
CLR P_RS
WRITEMT_RS: CLR P_RW
CLR P_CS
MOV A,R5
ANL A,#0FH ;数据只有低4位有效
MOV R5,A
MOV A,P_DT
ANL A,#0F0H
ORL A,R5
MOV P_DT,A
SETB P_CLK
NOP
CLR P_CLK
SETB P_CS
MOV A,P_DT
ANL A,#0F0H
ORL A,#0FH ;将数据线置为输入
MOV P_DT,A
RET
;-----------------------------------------------------------------
;初始化MT8880为接收函数:
SMTIN_SUB: SETB RSID
LCALL READMT_SUB ;READ STATUS REGISTER
MOV R5,#0
LCALL WRITEMT_SUB ;WRITE TO
CONTROL REGISTER:
MOV R5,#0
LCALL WRITEMT_SUB ;WRITE TO
CONTROL REGISTER
MOV R5,#8
LCALL WRITEMT_SUB ;WRITE TO
CONTROL REGISTER
MOV R5,#0
LCALL WRITEMT_SUB ;WRITE TO
CONTROL REGISTER
LCALL READMT_SUB ;READ STATUS REGISTER
CLR RSID
LCALL READMT_SUB ;READ DATA REGISTER
SETB RSID
LCALL READMT_SUB ;READ STATUS REGISTER
RET
;---------------------------------------------------------------
;初始化MT8880为发送函数:
SMTOUT_SUB: SETB RSID
MOV R5,#03H
LCALL WRITEMT_SUB
MOV R5,#03H
LCALL WRITEMT_SUB
MOV R5,#0BH
LCALL WRITEMT_SUB
MOV R5,#01H
LCALL WRITEMT_SUB
LCALL READMT_SUB ;READ STATUS REGISTER
CLR RSID
LCALL READMT_SUB ;READ DATA REGISTER
SETB RSID
LCALL READMT_SUB ;READ STATUS REGISTER
RET
;---------------------------------------------------------------
;初始化MT8880为发送函数:
SMTOUT1_SUB: SETB RSID
MOV R5,#03H
LCALL WRITEMT_SUB
MOV R5,#03H
LCALL WRITEMT_SUB
MOV R5,#0BH
LCALL WRITEMT_SUB
MOV R5,#00H
LCALL WRITEMT_SUB
LCALL READMT_SUB ;READ STATUS REGISTER
CLR RSID
LCALL READMT_SUB ;READ DATA REGISTER
SETB RSID
LCALL READMT_SUB ;READ STATUS REGISTER
RET
;------------------------------------------------------------
;初始化MT8880为检测函数:
SMTCHK_SUB: SETB RSID
MOV R5,#06H
LCALL WRITEMT_SUB
MOV R5,#06H
LCALL WRITEMT_SUB
MOV R5,#06H
LCALL WRITEMT_SUB
MOV R5,#06H
LCALL WRITEMT_SUB
LCALL READMT_SUB ;READ STATUS REGISTER
CLR RSID
LCALL READMT_SUB ;READ DATA REGISTER
SETB RSID
LCALL READMT_SUB ;READ STATUS REGISTER
RET
;-----------------------------------------------------------
;MT8880检测声音函数(ERRID=0则有声音):
CHKCP_SUB: LCALL SMTCHK_SUB
CLR ERRID ;先设为有声音
SETB P_IRQ ;设置检测中断为输入
MOV R5,#255 ;检测255次
MOV BIT_VAR,#0
CHKCP_1: JB P_IRQ,CHKCP_N
INC BIT_VAR ;为低,加低计数
CHKCP_N: DJNZ R5,CHKCP_1
JB BIT7ID,CHKCP_Y ;255次中,至少128次为低才算
SETB ERRID ;无声音
CHKCP_Y: RET
;--------------------------------------------------------
;MT8880拨号函数:
DAIL_SUB: LCALL SMTOUT1_SUB ;初始化MT8880为发送
MOV R0,#DT_BUF
DAIL_1: JNB STAID,DAIL_E ;不在拨号状态,退出
MOV A,@R0
ANL A,#0FH ;数据只有低4位有效
JZ DAIL_E ;为0,则结束
CJNE A,#0DH,DAIL_12 ;1101,短延时?
MOV N_1S,#0 ;清秒计数
DAIL_11: JNB STAID,DAIL_E ;不在拨号状态,退出
MOV A,N_1S
XRL A,SDT_VAR
JNZ DAIL_11 ;没到时间,等待
SJMP DAIL_1E ;时间到,继续
DAIL_12: CJNE A,#0EH,DAIL_14 ;1110,长延时?
MOV N_1S,#0 ;清秒计数
DAIL_13: JNB STAID,DAIL_E ;不在拨号状态,退出
MOV A,N_1S
XRL A,DDT_VAR
JNZ DAIL_13 ;没到时间,等待
SJMP DAIL_1E ;时间到,继续
DAIL_14: MOV R5,A
CLR RSID
LCALL WRITEMT_SUB ;发数据
LCALL SMTOUT_SUB ;初始化MT8880为发送
MOV D_100MS,#5 ;等待0.5秒
LCALL DELAY3_SUB ;等待发送DTMF
LCALL SMTOUT1_SUB ;初始化MT8880为发送
MOV D_100MS,#3 ;等待0.3秒
LCALL DELAY3_SUB ;等待发送DTMF
DAIL_1E: INC R0
CJNE R0,#DT_BUF_,DAIL_1 ;没到缓冲区末,则继续
DAIL_E: LCALL SMTCHK_SUB ;初始化MT8880为接收
RET
;------------------------------------------------------------
LCALL SMTCHK_SUB ;初始化MT8880为检测
;-----------------------------------------------------------
;接电话
MAIN_IN: JNB P_RING,$ ;等待铃声停
LCALL DELAY3_SUB ;等待0.1秒
LCALL DELAY3_SUB ;等待0.1秒
CLR P_HOOK ;接起电话
CLR P_LED ;发光二极管亮
MOV D_100MS,#30
LCALL DELAY3_SUB ;等待3秒
CLR JIN2ID ;第1次#号
LCALL SMTOUT1_SUB ;初始化MT8880为发送
MOV A,#0CH ;'#'号
MOV R5,A
CLR RSID
LCALL WRITEMT_SUB ;发码
LCALL SMTOUT_SUB ;初始化MT8880为发送
MOV D_100MS,#10
LCALL DELAY3_SUB ;等待1秒
LCALL SMTOUT1_SUB ;初始化MT8880为发送
LCALL DELAY3_SUB ;等待0.1秒
LCALL SMTIN_SUB ;初始化MT8880为接收
MOV N_1S,#0 ;1秒计数器清0
SETB GETMID ;接收状态标志:正在接收
MAIN_IN1: MOV A,N_1S
ANL A,#0F8H ;大于7秒?
JNZ MAIN_PH_ ;是,转接电话
SETB RSID
LCALL READMT_SUB ;读状态
MOV A,R5
ANL A,#04H
JZ MAIN_IN1 ;没有DTMF数据,继续等
CLR RSID ;有DTMF数据
LCALL READMT_SUB ;读DTMF数据
MOV A,R5
LCALL INBUF_SUB ;存入数据缓冲区
;--------------------------------------------------------
;拨号处理过程
MAIN_OUT: DEC A
MOV DTM_VAR,A ;拨号次数减1
MOV D_100MS,#20
LCALL DELAY3_SUB ;等待2秒
CLR P_HOOK ;接起电话
CLR P_LED ;发光二极管亮
MOV D_100MS,#10
LCALL DELAY3_SUB ;等待1秒
MOV N_1S,#0 ;1秒计数器清0
MAIN_OUT0: LCALL CHKCP_SUB ;检测拨号音
JNB ERRID,MAIN_OUT1 ;有拨号音
MOV A,N_1S
CJNE A,#3,MAIN_OUT0 ;不足3秒没有拨号音,继续检测
SJMP MAIN_OUTE ;大于3秒,失败
MAIN_OUT1: LCALL DAIL_SUB ;拨号
JNB DDATID,MAIN_OUTE ;拨号后要采集数据?
SETB GETMID ;接收状态标志:正在接收,以防PC机中途取走数据
LCALL SMTIN_SUB ;是,初始化MT8880为接收
MOV N_1S,#0 ;1秒计数器清0
CLR FSTID ;清第1位数据标志(临时)
MAIN_OUT2: JNB STAID,MAIN_OUTE ;不在拨号状态(PC机终止命令),退出
MOV A,N_1S
CJNE A,#5,MAIN_OUT3 ;不大于5秒,继续
SJMP MAIN_OUTE ;大于5秒,接收结束
MAIN_OUT3: SETB RSID
LCALL READMT_SUB ;读状态
MOV A,R5
ANL A,#04H
JZ MAIN_OUT2 ;没有DTMF数据,继续等
CLR RSID ;有DTMF数据
LCALL READMT_SUB ;读DTMF数据
MOV A,R5
LCALL INBUF_SUB ;存入数据缓冲区
MAIN_OUTE: SETB P_HOOK ;挂断电话
SETB P_LED ;发光二极管灭
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -