Đoạn code điều khiển, cái mà cần phải biết để chỉnh sửa lại theo ý của mình.
;================================================= ===========
; TP RELAYS ON PORT 0 DTMF ON PORT 1
; STATUS ON PORT 2
; ================================================== =========
;$MOD51
LED EQU P1.7
TONE_D EQU P3.6
TONE_B EQU P3.4
REL1 EQU P3.0 ; LINE CHANGE-OVER RELAY
REL2 EQU P3.1 ; RINGING RELAY
MELODY EQU P3.7 ; UM66T MELODY GENRATOR
ZERO EQU 10
F10 BIT 78H ; BIT FLAG
F11 BIT 79H
Ph BIT 7AH
On_Hook MACRO ; HOOK SWITCH ON P1.6
SETB P1.6
ENDM
Off_Hook MACRO ; HOOK SWITCH ON P1.6
CLR P1.6
ENDM
;================================================= ============
; INTERRUPT VECTOR TABLE
;================================================= ============
ORG 00H ; ENTRY ADDRESS FOR 89C51 RESET
AJMP MAIN ; MAIN STARTS BEYOND INTERRUPT VECTOR SPACE
ORG 1BH ; VECTOR ADDRESS FOR INTERRUPT
SETB Ph ; MARK "THIS IS A PHONE CALL"
AJMP PHONE ; JUMP TO PHONE CALL SERVICE
;================================================= ============
; M A I N
;================================================= ============
ORG 02CH ; START BEYOND THE VECTOR TABLE
MAIN:
ACALL INITIALIZE_SUB ; INITILIZE CONTRO RAGISTER(TMOD & IE)
START:
CLR LED
ACALL SCAN_TPs
JB F10,INTERCOM
SETB LED
ACALL SCAN_TPs
JB F10,INTERCOM
AJMP START
;================================================= ===========
; INTERCOM SERVICE
;================================================= ===========
INTERCOM:
CLR F10 ; RESET FLAG
Off_Hook ; DISABLE PHONE CALL
SETB TONE_D ; ON DIAL TONE
SETB TONE_B ; ON BUSY TONE
CLR LED ; ON LED PERMANENTLY
CPL A
MOV P0,A ; CONNECT SCANED No. TO SPEACH-BUS
ACALL GET_DIAL_NUM ; GET NUMBER TO CALL
CJNE A,#0FFH,INTERNAL ; IF DIAL=FF THEN PHONE CALL FROM INTERCOM
CLR REL1 ; CONNECT SPEACH-BUS TO PHONE LINE
Off_Hook ; OFF-HOOK SYSTEM
CLR LED ; ON LED PERMANENTLY
AJMP EXTERNAL_CALL
INTERNAL:
MOV R3,A ; SAVE SUBSCRIBER No. INTO R3
ANL A,P0
MOV P0,A ; CONNECT DIALED No. TO SPEACH-BUS
MOV A,R3 ; PROCESSING FOR CHECKING SUBSCRIBER
ANL A,P2 ; AND SUBCRIBER WITH CALLER
ACALL BELL ; RING THE BELL
EXTERNAL_CALL:
ACALL DELAY_HS
SPEACH: MOV A,P2
CJNE A,#255,SPEACH ; IF CALL COMPLETE THEN RESET SYSTEM
ACALL RST_SYSTEM ; ELSE WAIT HERE
AJMP START
;================================================= ===========
;THIS ROUTINE CHECKED TP'S STATUS IF ANY OFF_HOOK FOUND SERVICE
;PROVIDED HIM
;================================================= ===========
SCAN_TPs: ; FLASHING LED WITH SCANING TPs
MOV R0,#76
LOOP: MOV R1,#250
_1: MOV A,#1 ; START POINTER WITH ONE
JB P2.0,_2
SETB F10
AJMP OUT
_2: RL A
JB P2.1,_3
SETB F10
AJMP OUT
_3: RL A
JB P2.2,_4
SETB F10
AJMP OUT
_4: RL A
JB P2.3,_5
SETB F10
AJMP OUT
_5: RL A
JB P2.4,_6
SETB F10
AJMP OUT
_6: RL A
JB P2.5,_7
SETB F10
AJMP OUT
_7: RL A
JB P2.6,_8
SETB F10
AJMP OUT
_8: RL A
JB P2.7,BACK
SETB F10
AJMP OUT
BACK: DJNZ R1,_1
DJNZ R0,LOOP
OUT: RET ; RETURN FROM SUB ROUTINE
;================================================= ===========
; THIS ROUTINE RINGING THE BELL ON DIALED NUMBER
;================================================= ===========
BELL:
CLR TONE_D ; OFF DIAL TONE
CLR REL2 ; ON BELL RELAY
ACALL DELAY ; RING BELL FOR ONE MINIT
SETB REL2 ; OFF BELL RELAY
ACALL DELAY
JB F10,RET1
ACALL DELAY1
JB F10,RET1
ACALL DELAY1
JB F10,RET1
AJMP BELL
RET1: RET
;================================================= ===========
; CHECK TELEPHONE'S STATUS UPTO ONE SECOND
; IF PIKED UP THEN SET FLAG
;================================================= ===========
DELAY1: ; ONE SECOND DELAY WITH STATUS CHECKING
MOV R0,#4
LOOP11: MOV R1,#250
LOOP12: MOV R2,#250
LOOP13: CJNE A,P2,NOT_EQ
SETB F10 ; MARK SUBSCRIBER READY TO TALK
AJMP RET2
NOT_EQ: DJNZ R2,LOOP13
DJNZ R1,LOOP12
DJNZ R0,LOOP11
RET2: RET
;================================================= ===========
; ONE SECOND DELAY
;================================================= ===========
DELAY: ; ONE SECOND DELAY
MOV R0,#4
LOOP1: MOV R1,#250
LOOP2: MOV R2,#250
LOOP3: NOP
NOP
DJNZ R2,LOOP3
DJNZ R1,LOOP2
DJNZ R0,LOOP1
RET
;================================================= ===========
; READ DIALED NUMBER,RE-CHECK IF 0, * OR #
;================================================= ===========
GET_DIAL_NUM:
JNB P1.4,$ ; WAIT FOR KEY PRESS (STROB)
MOV A,P1 ; READ DIALED NUMBER
ANL A,#00001111B ; REMOVE EXTRA BITS
CJNE A,#ZERO,STERIK ;
JB Ph,GET_DIAL_NUM ; IF ZERO FROM PHONE CALL THEN READ AGAIN
MOV A,#0FFH ; TRUNK CALL FROM INTERCOM
AJMP RET3
STERIK: CJNE A,#11,HASH ; IF STERIK, READ AGAIN
AJMP GET_DIAL_NUM
HASH: CJNE A,#12,NINE ; IF HASH, READ AGAIN
AJMP GET_DIAL_NUM
NINE: CJNE A,#9,DECODE
JNB Ph,GET_DIAL_NUM ; DIAL=9 & NOT A PHONE THEN READ AGAIN
MOV A,#252 ; SELECT TO ALL (VIRTUALY 8)
AJMP RET3
DECODE: DEC A
MOV R1,A
MOV A,#1
ROTATE: RL A
DJNZ R1,ROTATE
CPL A
RET3: RET
;================================================= ============
; RESET ALL SYSTEM
;================================================= ============
RST_SYSTEM:
CLR TONE_D ; OFF DIAL-TONE
CLR TONE_B ; OFF BUSY-TONE
CLR F10 ; RESET FLAG
CLR Ph ; CLEAR PHONE CALL FLAG
CLR F11
MOV P0,#255 ; OFF ALL TPs RELAYS
SETB REL1 ; OFF CHANGE-OVER RELAY
SETB TR1 ; START TIMER/COUNTER
On_Hook ; ENABLE PHONE CALL
RET
;================================================= ===========
; INITIALIZE SYSTEM
;================================================= ===========
INITIALIZE_SUB: ; SET UP CONTROL REGISTERS
MOV TMOD, #01100000B ; TIMER 1 IS SET FOR MODE 2, COUNTER OPERATION
MOV IE, #10001000B ; ENABLE TIMER/COUNTER 1 INTERRUPT
MOV TH1, #219 ; AUTO RELOAD VALUE(INT1 TL1) EACH TIME AFTER OVERFLOW.
MOV TL1, #219 ; DEMO TIMER IS INITIALISED WITH (256-39=217)
; TO COUNT 39(2BELL)EVENTS
CLR TONE_D ; OFF DIAL-TONE
CLR TONE_B ; OFF BUSY-TONE
SETB TR1 ; START COUNTER 1
RET
;================================================= ============
; PHONE CALL SERVICE
;================================================= ============
PHONE:
CLR TR1 ; STOP TIMER1
Off_Hook ; OFF-HOOK SYSTEM
CLR LED ; ON LED PERMANENTLY
ACALL UM66 ; PLAY MELODY
CLR REL1 ; CONNECT SPEACH-BUS TO PHONE LINE
NEXT: ACALL GET_DIAL_NUM ; GET NUMBER TO CALL
SETB REL1 ; DISCONNECT FOR BELL
MOV P0,A ; CONNECT DIALED No. TO SPEACH-BUS
ACALL BELL ; RING THE BELL
CLR REL1 ; CONNECT SPEACH-BUS TO PHONE LINE
ACALL DELAY_HS ; PROVIDE HALF SECOND DELAY
BUSY: MOV A,P2
CJNE A,#255,BUSY ; IF CALL NOT COMPLETE, WAIT ARROUND HERE
JB F11,RESET ; CHECK FOR SECOND CALL
MOV P0,#255 ; DISCONNECT ALL TELEPHONES
SETB TONE_B ; ON BUSY TONE
SETB F11 ; MARK FOR SECOND PHONE CALL
CLR F10 ; RESET FLAG
AJMP NEXT ; GO FOR NEXT PHONE CALL
RESET: ACALL RST_SYSTEM ; END CALL
RETI
;================================================= ==================
; PLAY MELODY (UM66)
;================================================= ==================
UM66: CLR MELODY ; PLAY MELODY AS GREETING MESSAGE
ACALL DELAY ; FOR FIVE SECOND
ACALL DELAY
ACALL DELAY
ACALL DELAY
ACALL DELAY
SETB MELODY ; STOP MELODY
RET
;================================================= ===================
; HALF SECOND DELAY TO ESTABLISHED THE RELAY CONTECTS
;================================================= ===================
DELAY_HS: ; HALF SECOND DELAY
MOV R0,#2
LOOP21: MOV R1,#250
LOOP22: MOV R2,#250
LOOP23: NOP
NOP
DJNZ R2,LOOP23
DJNZ R1,LOOP22
DJNZ R0,LOOP21
RET
END
;================================================= ===========
; TP RELAYS ON PORT 0 DTMF ON PORT 1
; STATUS ON PORT 2
; ================================================== =========
;$MOD51
LED EQU P1.7
TONE_D EQU P3.6
TONE_B EQU P3.4
REL1 EQU P3.0 ; LINE CHANGE-OVER RELAY
REL2 EQU P3.1 ; RINGING RELAY
MELODY EQU P3.7 ; UM66T MELODY GENRATOR
ZERO EQU 10
F10 BIT 78H ; BIT FLAG
F11 BIT 79H
Ph BIT 7AH
On_Hook MACRO ; HOOK SWITCH ON P1.6
SETB P1.6
ENDM
Off_Hook MACRO ; HOOK SWITCH ON P1.6
CLR P1.6
ENDM
;================================================= ============
; INTERRUPT VECTOR TABLE
;================================================= ============
ORG 00H ; ENTRY ADDRESS FOR 89C51 RESET
AJMP MAIN ; MAIN STARTS BEYOND INTERRUPT VECTOR SPACE
ORG 1BH ; VECTOR ADDRESS FOR INTERRUPT
SETB Ph ; MARK "THIS IS A PHONE CALL"
AJMP PHONE ; JUMP TO PHONE CALL SERVICE
;================================================= ============
; M A I N
;================================================= ============
ORG 02CH ; START BEYOND THE VECTOR TABLE
MAIN:
ACALL INITIALIZE_SUB ; INITILIZE CONTRO RAGISTER(TMOD & IE)
START:
CLR LED
ACALL SCAN_TPs
JB F10,INTERCOM
SETB LED
ACALL SCAN_TPs
JB F10,INTERCOM
AJMP START
;================================================= ===========
; INTERCOM SERVICE
;================================================= ===========
INTERCOM:
CLR F10 ; RESET FLAG
Off_Hook ; DISABLE PHONE CALL
SETB TONE_D ; ON DIAL TONE
SETB TONE_B ; ON BUSY TONE
CLR LED ; ON LED PERMANENTLY
CPL A
MOV P0,A ; CONNECT SCANED No. TO SPEACH-BUS
ACALL GET_DIAL_NUM ; GET NUMBER TO CALL
CJNE A,#0FFH,INTERNAL ; IF DIAL=FF THEN PHONE CALL FROM INTERCOM
CLR REL1 ; CONNECT SPEACH-BUS TO PHONE LINE
Off_Hook ; OFF-HOOK SYSTEM
CLR LED ; ON LED PERMANENTLY
AJMP EXTERNAL_CALL
INTERNAL:
MOV R3,A ; SAVE SUBSCRIBER No. INTO R3
ANL A,P0
MOV P0,A ; CONNECT DIALED No. TO SPEACH-BUS
MOV A,R3 ; PROCESSING FOR CHECKING SUBSCRIBER
ANL A,P2 ; AND SUBCRIBER WITH CALLER
ACALL BELL ; RING THE BELL
EXTERNAL_CALL:
ACALL DELAY_HS
SPEACH: MOV A,P2
CJNE A,#255,SPEACH ; IF CALL COMPLETE THEN RESET SYSTEM
ACALL RST_SYSTEM ; ELSE WAIT HERE
AJMP START
;================================================= ===========
;THIS ROUTINE CHECKED TP'S STATUS IF ANY OFF_HOOK FOUND SERVICE
;PROVIDED HIM
;================================================= ===========
SCAN_TPs: ; FLASHING LED WITH SCANING TPs
MOV R0,#76
LOOP: MOV R1,#250
_1: MOV A,#1 ; START POINTER WITH ONE
JB P2.0,_2
SETB F10
AJMP OUT
_2: RL A
JB P2.1,_3
SETB F10
AJMP OUT
_3: RL A
JB P2.2,_4
SETB F10
AJMP OUT
_4: RL A
JB P2.3,_5
SETB F10
AJMP OUT
_5: RL A
JB P2.4,_6
SETB F10
AJMP OUT
_6: RL A
JB P2.5,_7
SETB F10
AJMP OUT
_7: RL A
JB P2.6,_8
SETB F10
AJMP OUT
_8: RL A
JB P2.7,BACK
SETB F10
AJMP OUT
BACK: DJNZ R1,_1
DJNZ R0,LOOP
OUT: RET ; RETURN FROM SUB ROUTINE
;================================================= ===========
; THIS ROUTINE RINGING THE BELL ON DIALED NUMBER
;================================================= ===========
BELL:
CLR TONE_D ; OFF DIAL TONE
CLR REL2 ; ON BELL RELAY
ACALL DELAY ; RING BELL FOR ONE MINIT
SETB REL2 ; OFF BELL RELAY
ACALL DELAY
JB F10,RET1
ACALL DELAY1
JB F10,RET1
ACALL DELAY1
JB F10,RET1
AJMP BELL
RET1: RET
;================================================= ===========
; CHECK TELEPHONE'S STATUS UPTO ONE SECOND
; IF PIKED UP THEN SET FLAG
;================================================= ===========
DELAY1: ; ONE SECOND DELAY WITH STATUS CHECKING
MOV R0,#4
LOOP11: MOV R1,#250
LOOP12: MOV R2,#250
LOOP13: CJNE A,P2,NOT_EQ
SETB F10 ; MARK SUBSCRIBER READY TO TALK
AJMP RET2
NOT_EQ: DJNZ R2,LOOP13
DJNZ R1,LOOP12
DJNZ R0,LOOP11
RET2: RET
;================================================= ===========
; ONE SECOND DELAY
;================================================= ===========
DELAY: ; ONE SECOND DELAY
MOV R0,#4
LOOP1: MOV R1,#250
LOOP2: MOV R2,#250
LOOP3: NOP
NOP
DJNZ R2,LOOP3
DJNZ R1,LOOP2
DJNZ R0,LOOP1
RET
;================================================= ===========
; READ DIALED NUMBER,RE-CHECK IF 0, * OR #
;================================================= ===========
GET_DIAL_NUM:
JNB P1.4,$ ; WAIT FOR KEY PRESS (STROB)
MOV A,P1 ; READ DIALED NUMBER
ANL A,#00001111B ; REMOVE EXTRA BITS
CJNE A,#ZERO,STERIK ;
JB Ph,GET_DIAL_NUM ; IF ZERO FROM PHONE CALL THEN READ AGAIN
MOV A,#0FFH ; TRUNK CALL FROM INTERCOM
AJMP RET3
STERIK: CJNE A,#11,HASH ; IF STERIK, READ AGAIN
AJMP GET_DIAL_NUM
HASH: CJNE A,#12,NINE ; IF HASH, READ AGAIN
AJMP GET_DIAL_NUM
NINE: CJNE A,#9,DECODE
JNB Ph,GET_DIAL_NUM ; DIAL=9 & NOT A PHONE THEN READ AGAIN
MOV A,#252 ; SELECT TO ALL (VIRTUALY 8)
AJMP RET3
DECODE: DEC A
MOV R1,A
MOV A,#1
ROTATE: RL A
DJNZ R1,ROTATE
CPL A
RET3: RET
;================================================= ============
; RESET ALL SYSTEM
;================================================= ============
RST_SYSTEM:
CLR TONE_D ; OFF DIAL-TONE
CLR TONE_B ; OFF BUSY-TONE
CLR F10 ; RESET FLAG
CLR Ph ; CLEAR PHONE CALL FLAG
CLR F11
MOV P0,#255 ; OFF ALL TPs RELAYS
SETB REL1 ; OFF CHANGE-OVER RELAY
SETB TR1 ; START TIMER/COUNTER
On_Hook ; ENABLE PHONE CALL
RET
;================================================= ===========
; INITIALIZE SYSTEM
;================================================= ===========
INITIALIZE_SUB: ; SET UP CONTROL REGISTERS
MOV TMOD, #01100000B ; TIMER 1 IS SET FOR MODE 2, COUNTER OPERATION
MOV IE, #10001000B ; ENABLE TIMER/COUNTER 1 INTERRUPT
MOV TH1, #219 ; AUTO RELOAD VALUE(INT1 TL1) EACH TIME AFTER OVERFLOW.
MOV TL1, #219 ; DEMO TIMER IS INITIALISED WITH (256-39=217)
; TO COUNT 39(2BELL)EVENTS
CLR TONE_D ; OFF DIAL-TONE
CLR TONE_B ; OFF BUSY-TONE
SETB TR1 ; START COUNTER 1
RET
;================================================= ============
; PHONE CALL SERVICE
;================================================= ============
PHONE:
CLR TR1 ; STOP TIMER1
Off_Hook ; OFF-HOOK SYSTEM
CLR LED ; ON LED PERMANENTLY
ACALL UM66 ; PLAY MELODY
CLR REL1 ; CONNECT SPEACH-BUS TO PHONE LINE
NEXT: ACALL GET_DIAL_NUM ; GET NUMBER TO CALL
SETB REL1 ; DISCONNECT FOR BELL
MOV P0,A ; CONNECT DIALED No. TO SPEACH-BUS
ACALL BELL ; RING THE BELL
CLR REL1 ; CONNECT SPEACH-BUS TO PHONE LINE
ACALL DELAY_HS ; PROVIDE HALF SECOND DELAY
BUSY: MOV A,P2
CJNE A,#255,BUSY ; IF CALL NOT COMPLETE, WAIT ARROUND HERE
JB F11,RESET ; CHECK FOR SECOND CALL
MOV P0,#255 ; DISCONNECT ALL TELEPHONES
SETB TONE_B ; ON BUSY TONE
SETB F11 ; MARK FOR SECOND PHONE CALL
CLR F10 ; RESET FLAG
AJMP NEXT ; GO FOR NEXT PHONE CALL
RESET: ACALL RST_SYSTEM ; END CALL
RETI
;================================================= ==================
; PLAY MELODY (UM66)
;================================================= ==================
UM66: CLR MELODY ; PLAY MELODY AS GREETING MESSAGE
ACALL DELAY ; FOR FIVE SECOND
ACALL DELAY
ACALL DELAY
ACALL DELAY
ACALL DELAY
SETB MELODY ; STOP MELODY
RET
;================================================= ===================
; HALF SECOND DELAY TO ESTABLISHED THE RELAY CONTECTS
;================================================= ===================
DELAY_HS: ; HALF SECOND DELAY
MOV R0,#2
LOOP21: MOV R1,#250
LOOP22: MOV R2,#250
LOOP23: NOP
NOP
DJNZ R2,LOOP23
DJNZ R1,LOOP22
DJNZ R0,LOOP21
RET
END
Comment