?? dtmf cm8770 雙音頻解碼程序.txt
字號:
; DTMFdat -- Receive the DTMF-Codes from a telephone line
; =======================================================
; November 03, 2002
;www.nbglin.com 電話:0574-88464538
;歌林電子制作工作室
; Structure of the program:
; The processing works with a cycle of 1 ms. A counter counts from 0 to
; 895 or with prescaler of 4 from 0 to 223. This makes a cycle of 1.0012 ms
; or a deviation per day of 107 seconds.
;
;A phase counter counts the cycles of 1 ms. After 10 cycles it is reset to 0,
; making 10 ms. This cycle consists of 10 phases each being 1 ms.
; we have a good division of the tasks over the
; processing time.
;
; PIC 16C54
; 3.579545 MHz; 1 cycle = 1.117us
; 0x0D (Watchdog enabled, XT-Oszillator)
; watchdog timeout: 18 ms
;
; LCD-Display: single line with 16 characters, Hitachi-controller HD44780 compatible
;
; Inputs:
; Port A Bit 0 dtmf-char bit 0
; Port A Bit 1 dtmf-char bit 1
; Port A Bit 2 dtmf-char bit 2
; Port A Bit 3 dtmf-char bit 3
;
; Port B Bit 6 reset display
; Port B Bit 7 dtmf-char is ready
;
; Connection of the LCD-Display:
; Port B Bit 0 DB4
; Port B Bit 1 DB5
; Port B Bit 2 DB6
; Port B Bit 3 DB7
; Port B Bit 4 E (Clock zum Datenspeichern)
; Port B Bit 5 RS
; R/W is always 0 (connect to GND)
;
;
LIST p=16c54b
include <p16c5x.inc>
midpos equ 0x08 ; after mid pos of display
lastpos equ 0x48 ; after last pos of display
;
phase equ 0x07 ; phase (0..9) of the 10 ms-cycle
dlycnt equ 0x08 ; delay
tmpData equ 0x09 ; temp data for display send and delay
cnt10ms equ 0x0A ; 10 ms-counter (dec every 10 ms)
cursPos equ 0x0B ; place of cursor for next display update
state equ 0x0C ; bit 0 = 1: STD was high last time
; bit 1 = 1: write points
; bit 2 = 1: unused
; bit 3 = 1: unused
; bit 4 = 1: unused
; bit 5 = 1: unused
ptcount equ 0x0D ; counter for writing points
unuse0E equ 0x0E ;
unuse0F equ 0x0F ;
unuse10 equ 0x10 ;
unuse11 equ 0x11 ;
unuse12 equ 0x12 ;
unuse13 equ 0x13 ;
unuse14 equ 0x14 ;
unuse15 equ 0x15 ;
unuse16 equ 0x16 ;
unuse17 equ 0x17 ;
unuse18 equ 0x18 ;
unuse19 equ 0x19 ;
unuse1A equ 0x1A ;
unuse1B equ 0x1B ;
unuse1C equ 0x1C ;
unuse1D equ 0x1D ;
unuse1E equ 0x1E ;
unuse1F equ 0x1F ;
;
;
org 0x00
;
goto startall
;
; Delay_ms
; --------
; Makes a delay of xx *100 microseconds when the
; processor frequency is 3.579545 MHz.
; Input: W; delay = W * 100 microseconds
delay_ms
movwf dlycnt
goto dly2
dly1
clrwdt ; clear watchdog
goto $+1
goto $+1
goto $+1
dly2
movlw .26 ; setup inner loop
movwf tmpData ; save in internal delay counter
dly3
decfsz tmpData,F ; dec
goto dly3 ; end inner loop
;
decfsz dlycnt,F ; dec
goto dly1 ; end outer loop
retlw 0x00 ; return with 0
;
;
; Send a command to the display (RS = 0)
; --------------------------------------
cmdDisp
movwf tmpData ; save value
;
bcf PORTB,5 ; clear RS
cmdDisp1
movlw b'11110000' ; load mask
andwf PORTB,F ; clear low order bits
; zuerst high order bits transfer
swapf tmpData,W ; swap byte
andlw b'00001111' ; clear high order bits
iorwf PORTB,F ; put low order bits to port
bsf PORTB,4 ; set E
nop ; wait
bcf PORTB,4 ; clear E
;
movlw b'11110000' ; load mask
andwf PORTB,F ; clear low order bits
; now low order bits transfer
movf tmpData,W ; load value
andlw b'00001111' ; clear high order bits
iorwf PORTB,F ; put low order bits to port
bsf PORTB,4 ; set E
nop ; wait
bcf PORTB,4 ; clear E
;
; delay of 150 microsec
movlw .44 ; setup loop
movwf tmpData ; save in internal delay counter
cmdds3
decfsz tmpData,F ; dec
goto cmdds3 ; loop
;
retlw 0x00 ; return with 0
;
;
; Send a special init command to the display (RS = 0)
; ---------------------------------------------------
spcDisp
movwf tmpData ; save value
;
bcf PORTB,5 ; clear RS
;
movlw b'11110000' ; load mask
andwf PORTB,F ; clear low order bits
; zuerst high order bits transfer
swapf tmpData,W ; swap byte
andlw b'00001111' ; clear high order bits
iorwf PORTB,F ; put low order bits to port
bsf PORTB,4 ; set E
nop ; wait
bcf PORTB,4 ; clear E
;
; delay of 150 microsec
movlw .44 ; setup loop
movwf tmpData ; save in internal delay counter
spcds3
decfsz tmpData,F ; dec
goto spcds3 ; loop
;
retlw 0x00 ; return with 0
;
;
; Send a char to the display (RS = 1)
; -----------------------------------
; A wait of 150 microsec is automatically done.
charDisp
movwf tmpData ; save value
;
bsf PORTB,5 ; set RS
goto cmdDisp1 ; goto command send routine
;
;
; Convert from binary value to ascii
; ----------------------------------
; Input: W = 0..15
; Output: W = corresponding ascii-char
binasc
addwf PCL,f
retlw 'D'
retlw '1'
retlw '2'
retlw '3'
retlw '4'
retlw '5'
retlw '6'
retlw '7'
retlw '8'
retlw '9'
retlw '0'
retlw '*'
retlw '#'
retlw 'A'
retlw 'B'
retlw 'C'
;
;
;
; Start main program
; ------------------
; init all
startall
clrf PORTA ; clear all bits of port A
movlw b'00001111' ; 4 bits input
tris PORTA ; set i/o direction
movlw b'00000000' ; init value port B
movwf PORTB ; set bits of port B
movlw b'11000000' ; 6 bits output
tris PORTB ; set i/o direction
movlw b'00000001' ; prescaler 1:4; all others 0
option ; set option reg.
;
clrf phase ; init phase
clrf cursPos ; init cursor position
movlw .100 ; 100 * 10 ms
movwf cnt10ms ; init
;
movlw .200 ; 200 * 100 microsec
call delay_ms ; delay 20 ms
;
; init LCD-Display
;
movlw b'00110000' ; command 'function set'
call spcDisp
movlw .50 ; 50 * 100 microsec
call delay_ms ; delay
;
movlw b'00110000' ; command 'function set'
call spcDisp
;
movlw b'00110000' ; command 'function set'
call spcDisp
;
movlw b'00100000' ; command 'function set'
call spcDisp
; ; now it is 4 bit interface
movlw b'00101000' ; command 'function set'
call cmdDisp ; send to display
;
movlw b'00001000' ; command 'display off'
call cmdDisp ; send to display
;
movlw b'00000001' ; command 'clear display'
call cmdDisp ; send to display
movlw .20 ; 20 * 100 microsec
call delay_ms ; delay 2 ms
;
movlw b'00000110' ; command 'set entry mode'
call cmdDisp ; send to display
;
movlw b'00001100' ; command 'on-off control'
call cmdDisp ; send to display
;
clrf TMR0 ; init timer 0
;
bsf state,1 ; must write points
;
;
; start of main loop
; ------------------
start
;
; wait until 1 ms gone
;
loop1
movf TMR0,W ; check if equal
btfss STATUS,Z ; skip if time reached
goto loop1 ; goto loop3
;
movlw .33
movwf TMR0 ; set timer startvalue
;
;
; jump to processing of actual phase in the 10-ms-cycle
;
movf phase,W ; load phase
addwf PCL,f ; calc entry in jump table
; jump table
goto prcPhas0
goto prcPhas1
goto prcPhas2
goto prcPhas3
goto prcPhas4
goto prcPhas5
goto prcPhas6
goto prcPhas7
goto prcPhas8
goto prcPhas9
; end of jump table
; process phase 0
; ---------------
; count time in seconds; actually not used
prcPhas0
decfsz cnt10ms,F ; dec 10 ms-counter
goto pp090 ; exit if not zero
; counter zero
movlw .100 ; 100 * 10 ms
movwf cnt10ms ; init
pp090
goto phasEEE ; end
;
;
; process phase 1
; ---------------
; check the dtmf-receiver-ic and display if digit ready
prcPhas1
btfsc PORTB,7 ; test if data, skip if no data ready
goto pp120 ;
; no data ready
bcf state,0 ; no data last time
goto pp190 ; --> exit!
; data are ready
pp120
btfsc state,0 ; test if data last time, skip if no data last time
goto pp190 ; --> exit!
; no data last time
bsf state,0 ; data last time
;
movlw lastpos ; compare with lastpos
subwf cursPos,W ;
btfsc STATUS,Z ; skip if not lastpos
goto pp190 ;
;
movf cursPos,W ; load pos
iorlw b'10000000' ; command 'DD-RAM'
call cmdDisp ; send to display
;
movf PORTA,W ; load char
andlw b'00001111' ; clear high order bits
call binasc ; convert to ascii
call charDisp ; display char
;
incf cursPos,F ; inc pos
movlw midpos ; compare with midpos
subwf cursPos,W ;
btfss STATUS,Z ; skip if =midpos
goto pp190 ; --> exit!
; it is midpos
movlw 0x40 ; cursor pos
movwf cursPos ; set cursor position
;
pp190
goto phasEEE ; end
;
;
; process phase 2
; ---------------
prcPhas2
btfsc state,1 ; test if must write points
goto pp210 ;
;
btfsc PORTB,6 ; test if reset-switch, skip if reset
goto pp290 ; --> exit!
;
; reset switch active
clrf cursPos ; init cursor position
;
; fill points in display
pp210
movlw 0x00 ; curs pos
iorlw b'10000000' ; command 'DD-RAM'
call cmdDisp ; send to display
;
movlw .8 ; setup loop
movwf ptcount ; save in counter
pp220
movlw '.' ; char
call charDisp ; display char
decfsz ptcount,F ; dec
goto pp220 ; loop
;
movlw 0x40 ; curs pos
iorlw b'10000000' ; command 'DD-RAM'
call cmdDisp ; send to display
;
movlw .8 ; setup loop
movwf ptcount ; save in counter
pp230
movlw '.' ; char
call charDisp ; display char
decfsz ptcount,F ; dec
goto pp230 ; loop
;
bcf state,1 ; not write points
;
pp290
goto phasEEE ; end
;
;
; process phase 3
; ---------------
prcPhas3
;
pp390
goto phasEEE ; end
;
;
; process phase 4
; ---------------
prcPhas4
goto phasEEE ; end
;
;
; process phase 5
; ---------------
prcPhas5
goto phasEEE ; end
;
;
; process phase 6, 7, 8
; ---------------------
prcPhas6
prcPhas7
prcPhas8
clrwdt ; clear watchdog
goto phasEEE ; end
;
;
; process phase 9
; ---------------
prcPhas9
movlw .255
movwf phase ; init phase
; goto phasEEE ; end
;
;
phasEEE
incf phase,F ; increment phase
goto start
;
;
;
end
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -