ljmp main1
modify:
lcall L91
setb ea
nop
nop
LJMP MAIN1
NEXT2:
CJNE A,#0BH,NEXT4 ;RECOR
LCALL RECORD
nop
nop
LJMP MAIN1
NEXT3:
NEXT4:
CJNE A,#0DH,NEXT5 ;SCAN_UP
LCALL scan_up
mov a,#10h
lcall disp_seg
MOV 21H,#0FFH
CLR LED1
MOV A,21H
mov sbuf,a
jnb ti,$
clr ti
nop
nop
LJMP MAIN1
NEXT5:
CJNE A,#0FH,next6 ;PLAY
setb ea
LCALL PLAY
nop
nop
MAIN222:
LJMP MAIN1
next6:
JNB valid,main222
jb valid1,main222
lcall testpw
LJMP MAIN1
;-------------------------------------------------
getpw:
clr right
mov count1,#00
mov position,#5ah
mov 58h,#0fh
mov 57h,#10h
mov 56h,#10h
mov 55h,#10h
mov 54h,#0ffh
mov 59h,#00h
lcall beep ;????????????????????
p92:
setb ea
clr time_out
mov 7eh,#0
mov 7fh,#0
setb tr0
p92_1:
lcall disp ;显示
lcall findkey
jb keyflag,p61
jb time_out,p92_3
ljmp p92_1
p92_3:
clr time_out
ljmp getpw_end
p61:
clr tr0
clr c
mov a,54h
subb a,#0ah
jnc p_101
mov a,position
cjne a,#5eh,save_buffle0
ljmp getpw
save_buffle0:
mov r0,position ;键值是09a之间
mov @r0,54h
inc position
inc count1
mov a,count1
cjne a,#length_pw,p92
setb right
ljmp p92
p_101:
mov a,54h
clr c
subb a,#0ah
jz p_a
mov 54h,#0ffh
ljmp p92
p_a:
mov position,#5ah
mov count1,#0
inc count2
jb right,p_3
mov a,count2
clr c
subb a,#times_pw
jz getpw_end
ljmp getpw
p_3: clr right
setb valid ;有密码
setb valid1 ;正处于密码状态
lcall beep
mov r6,#00 ;将缓存中的数存?;r6中存放页面首地址
wt_iic0:
mov r0,position
mov a,@r0
mov 36h,a
wt_iic00:
mov a,36h
clr ea
MOV MTD,A
lcall IWRNBYTE
NOP
mov MRD,#51h
LCALL IRDNBYTE
MOV A,MRD
clr c
subb a,36h ;保存r0
jnz wt_iic00
inc r6
inc position
mov a,position
cjne a,#5eh,wt_iic0
setb ea
mov position,#5ah
cmp:
mov r0,position
mov a,@r0
clr c
subb a,#0
jnz getpw_end
inc position
mov a,position
cjne a,#5eh,cmp
clr valid
getpw_end:
mov count2,#00
mov a,#10h
lcall disp_seg
setb ea
ret
;======================= 密码验证 ============================
testpw:
clr ea
mov r6,#00 ;将缓存中的数存?;r6中存放页面首地址
mov 36h,#24h
re_rd:
mov MRD,#51h
LCALL IRDNBYTE
MOV A,MRD
mov 3ch,a
clr c
subb a,#0ah
jnc re_rd
mov a,3ch
mov r0,36h
mov @r0,a
inc 36h
inc r6
cjne r6,#04,re_rd
setb ea
reapt:
clr right
mov count1,#00
mov position,#5ah
mov 58h,#12h
mov 57h,#10h
mov 56h,#10h
mov 55h,#10h
mov 59h,#00h
mov 54h,#0ffh
tp92:
setb ea
clr time_out
mov 7eh,#0
mov 7fh,#0
setb tr0
tp92_1:
lcall disp ;显示
lcall findkey
jb keyflag,tp61
jb time_out,tp92_3
ljmp tp92_1
tp92_3:
clr time_out
ljmp testpw_end
tp61:
clr tr0
clr c
mov a,54h
subb a,#0ah
jnc tp_101
mov a,position
cjne a,#5eh,save_buffle01
ljmp reapt
save_buffle01:
mov r0,position ;键值是09a之间
mov @r0,54h
inc position
inc count1
mov a,count1
cjne a,#length_pw,tp92
setb right
totp92:
ljmp tp92
tp_101:
mov a,54h
clr c
subb a,#0ah
jz test_a
mov 54h,#0ffh
ljmp tp92
test_a:
mov position,#5ah
mov count1,#0
inc count2
jb right,tp_3
mov a,count2
cjne a,#times_pw,times_no
ljmp testpw_end
times_n
ljmp reapt
tp_3:
clr right
mov r0,#24h
cmpagain:
mov 29h,@r0
mov a,r0
add a,#36h
mov r0,a
mov a,@r0
cjne a,29h,tryagain
mov a,r0
clr c
subb a,#36h
mov r0,a
inc r0
cjne r0,#28h,cmpagain
setb valid1
lcall beep
ljmp testpw_end
tryagain:
clr valid1
mov a,count2
cjne a,#times_pw,times_no
testpw_end:
mov count2,#00
lcall beep
mov a,#10h
lcall disp_seg
ret
;==============================
rd_valid:
mov r6,#05
mov MRD,#51h
LCALL IRDNBYTE
MOV A,MRD
cjne a,#0,valid_1
clr valid
ajmp rd_valid_out
valid_1:
cjne a,#0ffh,rd_valid
setb valid
rd_valid_out: ret
;===============================保存valid 于eeprom===================
save_valid:
jb valid,iic05_1
mov a,#0
mov 3ch,a
ljmp save_valid1
iic05_1:
mov a,#0ffh
mov 3ch,a
clr ea
save_valid1:
mov MTD,3ch
mov r6,#05
lcall IWRNBYTE
NOP
mov MRD,#51h
LCALL IRDNBYTE
MOV A,MRD
cjne a,3ch,save_valid1
setb ea
ret
;------------------------清EEPROM----------------------------------
clrEEPR0M:
clr ea
MOV MTD,#00H
mov r6,#06
WR24WCXXS:
LCALL IWRNBYTE
NOP ;在此设置断点,观察ACK位,ACK为1时操作正确\
RD24WCXXS:
mov MRD,#51h
LCALL IRDNBYTE
mov a,MRD
cjne a,MTD,WR24WCXXS
djnz r6,WR24WCXXS
clr valid
mov 37h,#1
clr_phone:
mov a,37h
mov b,#18
mul ab
mov R6,a
MOV MTD,#0AH
clr_iic1:
lcall IWRNBYTE
NOP
mov MRD,#51h
LCALL IRDNBYTE
mov a,MRD
cjne a,MTD,clr_iic1
INC 37H
MOV A,#MAX
INC a
cjne a,37H,clr_phone ;是#号键吗;清密码
lcall beeplong
setb ea
RET
;==================录音==========================
RECORD:
LCALL BEEP
mov 7fh,#00h
mov 7eh,#00h
clr 03h
setb tr0
CLR p_record
CLR p_play
RECORD1:
lcall findkey
jb 03h,record_end
mov a,54h
cjne a,#0ffh,record_end
ljmp RECORD1
record_end:
clr tr0
setb firstflag1
SETB p_record
ret
play:
LCALL BEEP
MOV 21H,#0FFH
CLR LED4
MOV A,21H
mov sbuf,a
jnb ti,$
clr ti
clr es
clr 03h
mov 7fh,#00h
mov 7eh,#00h
setb tr0
clr mute ;放音
setb p_play
SETB p_record
play1:
setb ex1
lcall findkey
jb 03h,play_end
mov a,54h
cjne a,#0ffh,play_end
ljmp play1
play_end:
clr p_play
clr tr0
setb mute
mov 30h,#30
lcall delay5ms
setb firstflag1
setb ex1
lcall beep
jnb relax_flag,play_end1
clr ex1
play_end1:
ret
;===================== 进入存储状态 ========================
STORE:
MOV 21H,#0FFH
CLR LED2 ;预置灯
MOV A,21H
mov sbuf,a
jnb ti,$
clr ti
L90:
mov addresspoint,#1
setb firstflag1
L91:
lcall beep
setb a_flag
mov position,#40h
mov 40h,#0ah
mov 58h,addresspoint
mov 57h,#10h
mov 56h,#10h
mov 55h,#10h
mov 54h,#0ffh
mov 59h,#00h
L92:
mov 7eh,#00h
mov 7fh,#00h
setb ea
clr time_out
setb tr0
L92_1:
lcall disp ;显示
lcall findkey
jb keyflag,L61
jb time_out,L92_3
ljmp L92_1
L92_3:
clr time_out
ljmp store_end
L61:
clr tr0
clr c
mov a,54h
subb a,#0ah
jnc store_101 ;键值是0~a之间
ljmp store_1
store_101:
mov a,54h
cjne a,#0ah,L62
jnb a_flag,store_3
ljmp store_end
store_3:
mov r0,position ;将 # 存入缓存
mov @r0,#0ah
mov position,#40h ;将缓存中的数存入IIC
mov a,addresspoint
mov b,#18
mul ab
mov r6,a ;r6中存放页面首地址
wt_iic1:
mov r0,position
mov a,@r0
mov 36h,a
wt_iic:
mov a,36h
clr ea
MOV MTD,A
lcall IWRNBYTE
NOP
mov MRD,#51h
LCALL IRDNBYTE
MOV A,MRD
clr c
subb a,36h ;保存r0
jnz wt_iic
mov a,36h
cjne a,#0ah,goon_wt
clr a_flag ;退出标志
setb ea
mov a,addresspoint
cjne a,#max,addresspoint_inc
ljmp L90
addresspoint_inc:
inc addresspoint
setb firstflag1
ljmp L91
goon_wt:
inc r6
inc position
ljmp wt_iic1
L62:
cjne a,#0dh,L63 ;上翻
lcall scan_up
nop
nop
nop
nop
Ljmp L91
L63:
cjne a,#0eh,L64 ;删除
lcall delete
nop
Ljmp L91
L64:
cjne a,#0ch,L65 ;修改
mov 58h,#10H
mov 57h,#10h
mov 56h,#10h
mov 55h,#10h
mov 59h,#00h
mov 54h,#0ffh
nop
setb firstflag1
Ljmp L91
L65:
mov 54h,#0ffh
ljmp L92
;===============进入存储号码状态7==5==5==========================
store_1:
clr a_flag
mov a,position
cjne a,#52h,save_buffle
ljmp L91
save_buffle:
mov r0,position
mov @r0,54h
inc position
ljmp L92
; ==================== 关显示 ========================
store_end:
setb ea
lcall beeplong
setb firstflag1
mov 54h,#0ffh
mov 55h,#10h
mov 56h,#10h
mov 57h,#10h
mov 58h,#10h
mov 59h,#00h
mov a,#10h
lcall disp_seg
ret
;===================================== 上翻 ===========================
scan_up:
mov a,addresspoint
cjne a,#max,scan_cycle
mov addresspoint,#1
ljmp cycle
scan_cycle:
inc addresspoint
cycle:
clr firstflag1
mov a,addresspoint ;循环显示
mov b,#18
mul ab
mov 3Ah,a
mov 58h,addresspoint
mov 57h,#10h
mov 56h,#10h
mov 55h,#10h
mov 54h,#0ffh
mov 59h,#00h
againi000:
mov 2fh,#40
disp_goon:
lcall disp
lcall findkey
jb keyflag,cycle_end
djnz 2fh,disp_goon
re_rdiic:
MOV r6,3AH
INC 3AH
clr ea
mov MRD,#51h
LCALL IRDNBYTE
MOV A,MRD
mov 54h,a ;保存 a 里面为键值
cjne a,#0ah,againi000 ;是#号键吗
ljmp scan_end2
cycle_end:
mov a,54h
cjne a,#0dh,cycle_out ;scan
ljmp scan_up
cycle_out:
cjne a,#0ah,recify
ljmp scan_end2
recify:
JNB valid,morefunc
ljmp re_rdiic
morefunc:
cjne a,#0ch,delt ;modify
ljmp L91
delt:
cjne a,#0eh,re_rdiic ;delete
lcall delete
scan_end2:
lcall beep ;修改完成
setb ea
MOV 21H,#0FFH
mov 54h,#0ffh
mov 55h,#10h
mov 56h,#10h
mov 57h,#10h
mov 58h,#10h
mov 59h,#00h
ret
;===================================== 删除 ===========================
delete:
lcall beep
mov 58h,addresspoint
mov 57h,#10h
mov 56h,#10h
mov 55h,#11h
; mov 59h,#00h
mov 54h,#0ffh
mov 2fh,#20
disp_del1:
lcall disp
djnz 2fh,disp_del1
mov 30h,#50
lcall delay5ms
mov 2fh,#20
disp_del2:
lcall disp
djnz 2fh,disp_del2
mov 2fh,#20
disp_del3:
lcall disp
djnz 2fh,disp_del3
mov a,addresspoint
mov b,#18
mul ab
mov r6,a
clr ea
wtiic_a:
MOV MTD,#0AH
lcall IWRNBYTE
NOP
mov MRD,#51h
LCALL IRDNBYTE
MOV A,MRD
clr c
subb a,#0ah
jz addresspoint_11
ajmp wtiic_a
addresspoint_11: setb ea
mov a,addresspoint
cjne a,#max,addp_inc
addp_1:
mov addresspoint,#1
ljmp delete_out
addp_inc:
inc addresspoint
delete_out:
setb firstflag1
MOV 21H,#0FFH
mov 54h,#0ffh
mov 55h,#10h
mov 56h,#10h
mov 57h,#10h
mov 58h,#10h
mov 59h,#00h
;setb es
setb ea
mov a,#10h
lcall disp_seg
RET
;===================================定时器0中断程序==============================
time0:
push 00h
push acc
push psw
CLR C
MOV A,7fh
ADD A,#01H
MOV 7fh,A
MOV A,7eh
ADDC A,#00H
MOV 7eh,A
MOV R0,7fh
CJNE R0,#00H,OVER000
MOV R0,7eh
CJNE R0,#01H,OVER000
setb time_out
mov 7eh,#00h
mov 7fh,#00h
mov th0,#3ch
mov tl0,#0b0h
clr tr0
ljmp tout
OVER000:
mov th0,#3ch
mov tl0,#0b0h
clr time_out
setb tr0
tout: pop psw
pop acc
pop 00h ;保存r0
cpl p3.6 ;清看门?
reti
;===================================定时器0中断程序==============================
time1:
push 00h
push acc
push psw
CLR C
MOV A,7dh
ADD A,#01H
MOV 7dh,A
MOV R0,7dh
CJNE R0,#09H,OVER222
SETB time_out1
mov 7dh,#00h
mov th1,#3ch
mov tl1,#0b0h
clr tr1
ljmp tout1
OVER222:
mov th1,#3ch
mov tl1,#0b0h
clr time_out1
setb tr1
tout1: pop psw
pop acc
pop 00h ;保存r0
reti
;===============================int1 中断===========================================
INTPT1:
cpl p3.6 ;清看门狗
lcall beep
MOV 21H,#0FFH
CLR LED3
MOV A,21H
mov sbuf,a
jnb ti,$
clr ti
;=========================================================
mov a,37h
mov b,#18
mul ab
mov 3Ah,a
clr ea
MOV r6,3AH
;mov 30h,#60
;lcall delay10ms
mov MRD,#51h
LCALL IRDNBYTE
setb ea
MOV A,MRD
cjne a,#0ah,again1
mov a,37h
cjne a,#max,dailnext
lcall handfree
ljmp int1out
dailnext:
inc 37h
lcall beeplong
ljmp INTPT1
again:
INC 3AH
MOV r6,3AH
clr ea
mov MRD,#51h
LCALL IRDNBYTE
MOV A,MRD
setb ea
cpl p3.6 ;清看门狗
cjne a,#0ah,next ;是#号键吗
ljmp again_out
;========================开始拨号==========================
again1:
;MOV 30H,#30
;LCALL delay10ms
SETB mute
SETB ON_LINE
MOV 30H,#50
LCALL delay10ms
MOV 2dH,#00H
mov 39h,#64h
agains:
mov 30h,#01h
lcall delay10ms
jb p_int0,nexti
inc 2dh
nexti:
cpl p3.6 ;清看门狗
djnz 39h,agains
mov a,2dh
subb a,#90
jnc next
nop
nop
ljmp localwarning ;非低点评拨号因
next:
clr dtmf_ce
mov a,MRD
lcall out_dtmf
mov 30h,#20
lcall delay10ms
setb dtmf_ce
mov 30h,#30
lcall delay10ms
cpl p3.6 ;清看门狗
LJMP again
;=========语音监测======================================================
again_out:
cpl p3.6 ;清看门狗
mov 38h,#00h
mov 39h,#064h
mov 35h,#00h
int00:
mov 34h,#00h
againi0:
mov 30h,#0ah
lcall delay10ms
jnb P3.2,adcount
inc 35h
ljmp out
adcount:
inc 34h
mov 35h,#00h
cpl p3.6 ;清看门狗
djnz 39h,againi0
ljmp handfree1
;------------------------------
out: mov a,34h
subb a,#0eh
jnc oncemore
mov a,34h
subb a,#4
jnc ackvoice
cpl p3.6 ;清看门狗
mov a,34h
subb a,#4
jnc oncemore
mov a,34h
subb a,#2
jc onceagain
inc 38h
mov a,38h
CLR C
subb a,#02h ;03h
jz gohandfree ;检测到忙音
onceagain:
mov a,35h
clr c
subb a,#45
jnc gohandfree
oncemore:
JNB p_relax,rept0
MOV 30H,#16H
LCALL delay10ms
JNB p_relax,rept0
MOV 30H,#16H
LCALL delay10ms
JNB p_relax,rept0
setb relax_flag
lcall handfree
ljmp int1out
rept0:
cpl p3.6 ;清看门狗
ljmp int00
gohandfree:
ljmp handfree1
;===============================================================================================================
ackvoice:
lcall beep
MOV 2dH,#00H
mov 2eh,#00H
mov 39h,#0a0h
againss:
mov 30h,#0ah
lcall delay10ms
jnb P3.2,nextii
inc 2dh ;检测高电平
mov 2eh,#00h
mov a,2dh
clr c
subb a,#45
jnc playmusic
ljmp oncemore1
nextii: ;检测低电平
mov 2dh,#00h
inc 2eh
mov a,2eh
clr c
subb a,#3 ;3d 2d
jc oncemore1
mov 30h,#15 ;100d 250d ; 15d
lcall delay10ms
jb P3.2,handfree1 ;检测到忙音
mov 2eh,#00h
oncemore1:
JNB p_relax,rept1
MOV 30H,#16H
LCALL delay10ms
JNB p_relax,rept1
MOV 30H,#16H
LCALL delay10ms
JNB p_relax,rept1
setb relax_flag
lcall handfree
ljmp int1out
rept1:
cpl p3.6 ;清看门狗
djnz 39h,againss
ljmp handfree1
playmusic:
nop
clr mute
setb p_play
SETB p_record
mov r2,#00h
mov r0,#64h
busyloop1:
mov r1,#0ah
busyloop:
mov 30h,#1
lcall delay10ms
jb P3.2,oncemore3
inc r2
mov a,r2
clr c
subb a,#20 ;30d
jc oncemore2
mov 30h,#25 ;06d
lcall delay10ms
jb P3.2,handfree1
oncemore3:
mov r2,#00h
oncemore2:
JNB p_relax,rept2
MOV 30H,#16H
LCALL delay10ms
JNB p_relax,rept2
MOV 30H,#16H
LCALL delay10ms
JNB p_relax,rept2
setb relax_flag
lcall handfree
ljmp int1out
rept2:
cpl p3.6 ;清看门狗
djnz r1,busyloop
djnz r0,busyloop1
handfree1:
clr p_play
lcall handfree
CPL P3.6
;37h中存放电话个数
mov a,37h
cjne a,#max,int1next
ljmp int1out
int1next:
inc 37h
ljmp INTPT1
localwarning:
setb P3.4
mov 39h,#60
localw1:
mov r4,#0ah
localw:
mov 30h,#0ah
lcall delay10ms
JNB p_relax,repeat0
MOV 30H,#16
LCALL delay10ms
JNB p_relax,repeat0
MOV 30H,#16
LCALL delay10ms
JNB p_relax,repeat0
setb relax_flag
lcall handfree
ljmp int1out
repeat0:
djnz r4,localw
CPL P3.6
djnz 39h,localw1
int1out:
setb p1.1
clr P3.4
SETB EX1
RETI
handfree:
lcall beeplong
clr on_line
MOV A,#0FFH
mov sbuf,a
jnb ti,$
clr ti
mov 30h,#50
lcall delay10ms
ret
;==================================显示子程序===============================
disp:
push acc
push psw
push 00h
mov a,54h
cjne a,#0ffh,mout1 ;if keyflag=1
ljmp mout
mout1:
cjne a,#0ah,mout2
mov 54h,#10h
mout2:
inc 59h
mov r0,59h
cjne r0,#1,disp2
mov 58h,57h
mov 55h,54h
ljmp mout
disp2:
cjne r0,#2,disp3
mov 56h,55h
mov 55h,54h
ljmp mout
disp3:
cjne r0,#3,disp4
mov 57h,56h
mov 56h,55h
mov 55h,54h
ljmp mout
disp4:
mov 58h,57h
mov 57h,56h
mov 56h,55h
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