|
; DTMFdata -- Receive the DTMF-Codes from a telephone line ; ======================================================= ; November 03, 2002 ;歌林電子制作工作室 ; 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
|