📄 clearview007.asm
字号:
; TIMEOUT flag will be set when counter reaches zero.
DELAY_ISR
BTFSC TIMEOUT ; CHECK IF NOT TIMEOUT
GOTO DELAY_ISR_END
; DECREMENT TIMEOUT COUNTER
DECF TIME0, F
BTFSS STATUS, Z
GOTO DELAY_ISR_END ; TIME0<>0
DECF TIME1, F
BTFSS STATUS, Z
GOTO DELAY_ISR_END ; TIME1<>0
BSF TIMEOUT ; SET TIMEOUT=TRUE
DELAY_ISR_END
; continue to Serial ISR
goto INT_EXIT ; skip serial
;**********************
; Serial ISR
;**********************
INT_TEST_RX_IRQ
BTFSS PIR1,RCIF ; test if serial recive irq
GOTO INT_TEST_TX_IRQ ; nope check next
; ***********************************************************************
; RX_INT_HANDLER - handles the received commands on serial com
RX_INT_HANDLER
BTFSS RCSTA,OERR ; test for overrun error
GOTO RX_CHECK_FRAMING
; when overrun, uart will stop receving the continous
; recevive bit must then be reset
BCF RCSTA,CREN ; clear continous receve bit
BSF RCSTA,CREN ; and set it again
RX_CHECK_FRAMING
BTFSS RCSTA,FERR ; check from framing errors
GOTO RX_CHECK_BUFFER
; framing error do not store this byte
; read rx reg and discard byte
GOTO RX_DISCARD_BYTE
RX_CHECK_BUFFER
MOVF RX_Buffer_Count,W ; test for space
XORLW RX_BUFFER_SIZE
BTFSC STATUS,Z
GOTO RX_BUFFER_FULL
; Place the new char in the RxBuffer
MOVF RX_Buffer_InPtr,W ; get adress for indirect dressing
MOVWF FSR ; setup fsr
MOVF RCREG,W ; get received byte
MOVWF INDF ; and store it in buffer
INCF RX_Buffer_Count,F ; inc buffer counter
; update pointers
INC_BUFFER RX_Buffer_InPtr,RX_Buffer,RX_BUFFER_SIZE
BSF GOT_ONE ; set flag
GOTO INT_RX_END
RX_BUFFER_FULL
; no room for more bytes, set overrun flag
BSF _BufferOverrun
; and clear the last byte ( no room to store it ! )
RX_DISCARD_BYTE
; optional an error flag could be set to indicate comm error.
MOVF RCREG,W ; read byte and discard
; END RX INT HANDLER
INT_RX_END
BCF PIR1,RCIF ; clear rx int flag
INT_TEST_TX_IRQ
BTFSS PIR1,TXIF ; test if serial transmit irq
GOTO INT_TEST_NXT
; ***********************************************************************
; TX_INT_HANDLER - handles the tramission of bytes on serial com
;
TX_INT_HANDLER
MOVF TX_Buffer_Count,W ; get number of bytes
BTFSC STATUS,Z ; buffer empty ?
GOTO TX_BUFFER_EMPTY
MOVF TX_Buffer_OutPtr,W ; get adress for indirect adressing
MOVWF FSR ; setup fsr
MOVF INDF,W ; get byte
MOVWF TXREG ; and put it in tx reg
DECF TX_Buffer_Count,F ; decrement buffer counter
; update pointers
INC_BUFFER TX_Buffer_OutPtr,TX_Buffer,TX_BUFFER_SIZE
GOTO INT_TX_END
TX_BUFFER_EMPTY
; no more bytes to send disable TX irq
; code is to avoid bank switching ( using FSR )
MOVLW PIE1 ; get adress for tx irq enable
MOVWF FSR ; setup fsr
BCF INDF,TXIE ; and disable tx irq
INT_TX_END
BCF PIR1,TXIF ; clear tx int flag
INT_TEST_NXT
; test whatever left :-)
;**********************
; Context Restore
;**********************
INT_EXIT
CLRF STATUS ;ENSURE BANK0 RESTORE
MOVF FSR_SAVE,W
MOVWF FSR
MOVF PCLATH_SAVE,W
MOVWF PCLATH ; RESTORE PCLATH
BCF PORTB, 1 ; reset interrupt indicator
SWAPF STATUS_TEMP,W
MOVWF STATUS
SWAPF W_TEMP,F
SWAPF W_TEMP,W
RETFIE
;**********************************************************
; Main Program
;**********************************************************
START
INIT ; INIT ROUTINE
;***************
; setup delay
;***************
BCF TIMEOUT ; KEEP DELAY COUNTER STOPPED
CLRF TIME0 ; INIT DELAY COUNTER
CLRF TIME1
;***************
; setup uart
;***************
CALL INIT_UART
; initialize buffers/pointers
CALL INIT_BUFFERS
;***************
; setup A/D
;***************
Bank1
CLRF ANSEL ; configure Port A as digital I/O
BSF ANSEL,0 ; RA0 = analog input
bsf TRISA,0 ; PORTA0 = input, AN0
movlw B'01000000' ; ADFM=0 left justified, ADCS2=1 divide clock by 2,VCFG=00 - VDD VSS reference, XXXX
movwf ADCON1
Bank0
movlw B'10000001' ; ADCS=10=fosc/64(ADCS2=1), CHS=000=RA0, GO=0, X, ADON=1 A/D ON
movwf ADCON0
;***************
; setup DTMF generator
;***************
BCF DTMF_GEN_ON ; stop dtmf generator
;***************
; setup DTMF DETECTOR
;***************
BSF DTMF_DONE ; STOP DTMF detector
movlw '-'
movwf TEMP_VAL
movlw 1
movwf TEMP_TIMES
bcf DTMF_RECOVER
;*************************
; setup timer2 and PWM and PORTB
;*************************
CLRF AccLH
CLRF AccHH ; CLEAR High Freq Generator accumulator
CLRF AccLL
CLRF AccHL ; CLEAR Low Freq Generator accumulator
BANKSEL PR2 ;(bank 1)
MOVLW B'00111111'
MOVWF PR2 ; 78.12Khz PWM with 20Mhz oscillator
BANKSEL CCPR1L ;(bank 0)
MOvLw B'00100000'
MOVLW CCPR1L ; initial PWM value = 128
BCF CCP1CON,5
BCF CCP1CON,4
clrf PORTB ; CLEAR PORTB
; 1=in, 0=out
movlw B'11000100' ;port B 7,6 in, 5TxOUT,4 out, 3 OUT,2RxIN, 1out, 0 out
BANKSEL TRISB ;(bank 1)
movwf TRISB
BANKSEL T2CON ;(bank 0)
MOVLW B'00111000' ; set Timer2 prescaler 1/1, post scaler 1/8
MOVWF T2CON
;BANKSEL CCP1CON ;(bank 0)
; configure CCP1CON for PWM
MOVLW B'00001111'
IORWF CCP1CON,F ; set last four bits
; reset TMR2IF, enable interrupts
;BANKSEL PIR1 ;(bank 0)
BCF PIR1, TMR2IF
BANKSEL PIE1 ;(bank 1)
BSF PIE1, TMR2IE
BANKSEL INTCON ;(bank 0)
; Start the interrupts
BSF INTCON,GIE ; global int
BSF INTCON,PEIE ; Peripherals int
BSF T2CON,TMR2ON ; start Timer2, bank0
;*********************************
; MAIN LOOP
;*********************************
MAIN:
; send a wellcome string to the serial port
movlw LOW linie1
movwf XcomA
movlw HIGH linie1
movwf XcomB
call ser_rom ;send str to serial
MOVLW "+"
Call DTMF_digit ; 1000hz bip
movlw LOW linie2
movwf XcomC
movlw HIGH linie2
movwf XcomB
call DTMF_rom ;send string linie2 to DTMF
ECHO_SERIAL
; echo chars received to the serial port
CALL RX_GET_BUFFER
BTFSC STATUS, Z ; or test for zero on return
GOTO ECHO_1
movwf temp1
CALL TX_ADD_BUFFER ; SEND CHAR TO SERIAL
movf temp1,W ; send char to dtmf generator
CALL DTMF_digit
ECHO_1
CALL DETECT_DTMF ; START DTMF DETECTOR
btfss DTMF_DETECTED
goto nonewdigit
; new digit detected
; 5 sec timer
;DISABLE_IRQ
MOVLW .188
MOVWF TIME0
MOVLW .190
MOVWF TIME1
BCF TIMEOUT ; start 5 sec delay
;ENABLE_IRQ
bsf Temp_Flag
; print last digit
movf DTMF_RESULT, W
call TX_ADD_BUFFER
goto ECHO_SERIAL
nonewdigit ; no new dtmf digit detected
;check timeout
btfss Temp_Flag
GOTO DTMF_digit_timeout ; wait for Temp_Flag=1
BTFSS TIMEOUT
GOTO DTMF_digit_timeout ; wait for TIMEOUT=1
; print CRLF
bcf Temp_Flag
movlw 0x0d
call TX_ADD_BUFFER
movlw 0x0a
call TX_ADD_BUFFER
DTMF_digit_timeout
goto ECHO_SERIAL ; no new dtmf digit detected
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;; Send W hex to serial port + 1 space, uses XcomB, XcomC
PRINTWHEX
; high nibble, low nibble, space
MOVWF XcomB ; save w
swapf XcomB, W
ANDLW 0x0F
movwf XcomC
sublw 9 ; test if char = ABCDEF
movf XcomC, W
btfss STATUS, C ; skip if 0-9
addlw .7 ;('A'-'0')-10
addlw '0'
call TX_ADD_BUFFER ; print high nibble
movf XcomB,W
ANDLW 0x0F
movwf XcomC
sublw 9 ; test if char = ABCDEF
movf XcomC, W
btfss STATUS, C ; skip if 0-9
addlw .7 ;('A'-'0')-10
addlw '0'
call TX_ADD_BUFFER ; print low nibble
movlw ' '
call TX_ADD_BUFFER ; print space
Return
;************************************************************************
;SUBROUTINES
;************************************************************************
;************************************************************************
; TO START DTMF DETECTOR - CALL DETECT_DTMF - this will return in ~130 timer cycles
; if DTMF_DETECTED=1 on return one NEW DTMF digit was detected in DTMF_RESULT or '-' for pause
;************************************************************************
;START DTMF DECODER
DETECT_DTMF
;BSF DTMF_DONE ; STOP DTMF INT ROUTINE
; clear the dtmf detector values
MOVF FSR,W
MOVWF FSR_SAVE_DTMF ; SAVE FSR
MOVLW (Low A697SIN)-1 ; start -1
MOVWF FSR
TEMPXX1
INCF FSR,F
CLRF INDF
MOVF FSR,W
XORLW LOW A1633COS2 ; CLEAR RAM FROM A697SIN-A1633COS2!!!
BTFSS STATUS,Z
GOTO TEMPXX1
; table read pointer
CLRF TABLECOUNTER
CLRF RESULT1 ; CLEAR RESULT DIGIT
MOVF FSR_SAVE_DTMF, W
MOVWF FSR ; RESTORE FSR
;BCF DTMF_RECOVER ;
CLRF BITCHANGES ; CLEAR THE COUNTER
BCF DTMF_DONE ; CLEAR DONE, START DTMF ISR ROUTINE
DETECT1
;wait for the ISR part to end
btfss DTMF_DONE
goto DETECT1
;got one dtmf digit or '-'
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DTMF DECISION ALGORITHM
; compute absolute value acc = ABS(acc)
; FIRST LOOK AT THE BITCHANGES COUNTER > 10
; MOVF BITCHANGES,W
; SUBLW 5 ; treshold-w--> W, carry=0 on borrow,
; W=31 carry=0, W=30 carry=1, W=29 carry=1!
; therefore the bit is 0 in RESULT for W > treshold
; BTFSS STATUS, C
; GOTO STARTTEST
; GOT A QUAIET FRAME - JUST SKIP THE REST
; MOVLW 'Q'
; GOTO SENDIT
STARTTEST
MOVLW LOW A697SIN
MOVWF FSR
TESTFORNEG
BTFSC INDF,7
GOTO NEG
GOTO NEXT
NEG
; SUBTRACT F FROM 0
MOVF INDF,W
SUBLW 0
MOVWF INDF
NEXT
INCF FSR,F
MOVF FSR,W
XORLW LOW A1633COS2+1 ; for 1X and 2X bins the end is A1633COS2
BTFSS STATUS,Z
GOTO TESTFORNEG
; add acumulator results for sin and cos, results in cos , sin=0
MOVLW LOW A697SIN
MOVWF FSR
MORERESULTS
MOVF INDF,W
CLRF INDF
INCF FSR,F
ADDWF INDF,F
MOVF FSR,W
INCF FSR,F
XORLW LOW A1633COS2 ; for 1X and 2X bins the end is A1633COS2
BTFSS STATUS,Z
GOTO MORERESULTS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; compare acc with treshold1X
; for 1X bins
MOVLW LOW A697COS ; first result
MOVWF FSR
TEMPX1L
MOVF INDF,W
SUBLW treshold1XL ; treshold-w--> W, carry=0 on borrow,
; W=31 carry=0, W=30 carry=1, W=29 carry=1!
; therefore the bit is 0 in RESULT for W > treshold
RRF RESULT,F
INCF FSR,F
INCF FSR,F
MOVF FSR,W
XORLW LOW A941COS+2
BTFSS STATUS,Z
GOTO TEMPX1L
MOVLW LOW A1209COS ; first result
MOVWF FSR
TEMPX1H
MOVF INDF,W
SUBLW treshold1XH ; treshold-w--> W, carry=0 on borrow,
; W=31 carry=0, W=30 carry=1, W=29 carry=1!
; therefore the bit is 0 in RESULT for W > treshold
RRF RESULT,F
INCF FSR,F
INCF FSR,F
MOVF FSR,W
XORLW LOW A1633COS+2
BTFSS STATUS,Z
GOTO TEMPX1H
COMF RESULT,F ; complement result>> bit is set if A...COS > TRESHOLD
; RESULT bits are 1633/1477/1336/1209/941/852/770/697 FOR VALUE>Treshold
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; compare acc with treshold2X
; for 2X bins
MOVLW LOW A697COS2 ; first result
MOVWF FSR
TEMPX2L
MOVF INDF,W
SUBLW treshold2XL ; treshold-w--> W, carry=0 on borrow,
; W=31 carry=0, W=30 carry=1, W=29 carry=1!
; therefore the bit is 0 in RESULT for W > treshold
RRF RESULT2X,F
INCF FSR,F
INCF FSR,F
MOVF FSR,W
XORLW LOW A941COS2+2
BTFSS STATUS,Z
GOTO TEMPX2L
MOVLW LOW A1209COS2 ; first result
MOVWF FSR
TEMPX2H
MOVF INDF,W
SUBLW treshold2XH ; treshold-w--> W, carry=0 on borrow,
; W=31 carry=0, W=30 carry=1, W=29 carry=1!
; therefore the bit is 0 in RESULT for W > treshold
RRF RESULT2X,F
INCF FSR,F
INCF FSR,F
MOVF FSR,W
XORLW LOW A1633COS2+2
BTFSS STATUS,Z
GOTO TEMPX2H
;COMF RESULT2X,F ; complement result>> bit is set if A...COS > TRESHOLD
movf RESULT2X, W ; 2X frequencies mask is 0 for 2X freq bin > treshold
andwf RESULT, F ; apply 2X frequencies mask over 1X RESULT
; RESULT2 bits are for 2X frequencies 1633/1477/1336/1209/941/852/770/697 FOR VALUE>Treshold
; translate to ASCII
;**********************************************
; GOT ONE CHARACTER, CONVERT IT TO ASCII....
;**********************************************
MOVF RESULT,W
XORLW B'00010001'
BTFSC STATUS,Z
GOTO GOTCHA1
MOVF RESULT,W
XORLW D'33'
BTFSC STATUS,Z
GOTO GOTCHA2
MOVF RESULT,W
XORLW D'65'
BTFSC STATUS,Z
GOTO GOTCHA3
MOVF RESULT,W
XORLW D'18'
BTFSC STATUS,Z
GOTO GOTCHA4
MOVF RESULT,W
XORLW D'34'
BTFSC STATUS,Z
GOTO GOTCHA5
MOVF RESULT,W
XORLW D'66'
BTFSC STATUS,Z
GOTO GOTCHA6
MOVF RESULT,W
XORLW D'20'
BTFSC STATUS,Z
GOTO GOTCHA7
MOVF RESULT,W
XORLW D'36'
BTFSC STATUS,Z
GOTO GOTCHA8
MOVF RESULT,W
XORLW D'68'
BTFSC STATUS,Z
GOTO GOTCHA9
MOVF RESULT,W
XORLW D'40'
BTFSC STATUS,Z
GOTO GOTCHA0
MOVF RESULT,W
XORLW D'72'
BTFSC STATUS,Z
GOTO GOTCHAPOUND
MOVF RESULT,W
XORLW D'24'
BTFSC STATUS,Z
GOTO GOTCHASTAR
MOVF RESULT,W
XORLW B'10000001'
BTFSC STATUS,Z
GOTO GOTCHAA
MOVF RESULT,W
XORLW B'10000010'
BTFSC STATUS,Z
GOTO GOTCHAB
MOVF RESULT,W
XORLW B'10000100'
BTFSC STATUS,Z
GOTO GOTCHAC
MOVF RESULT,W
XORLW B'10001000'
BTFSC STATUS,Z
GOTO GOTCHAD
; GOT ONLY TRASH...
MOVLW '-'
GOTO SENDIT
; CONVERT ASCII
GOTCHAPOUND
MOVLW H'23'
GOTO SENDIT
GOTCHASTAR
MOVLW H'2A'
GOTO SENDIT
GOTCHA1
MOVLW H'31'
GOTO SENDIT
GOTCHA2
MOVLW H'32'
GOTO SENDIT
GOTCHA3
MOVLW H'33'
GOTO SENDIT
GOTCHA4
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -