📄 clearview007.asm
字号:
MOVLW H'34'
GOTO SENDIT
GOTCHA5
MOVLW H'35'
GOTO SENDIT
GOTCHA6
MOVLW H'36'
GOTO SENDIT
GOTCHA7
MOVLW H'37'
GOTO SENDIT
GOTCHA8
MOVLW H'38'
GOTO SENDIT
GOTCHA9
MOVLW H'39'
GOTO SENDIT
GOTCHA0
MOVLW H'30'
GOTO SENDIT
GOTCHAA
MOVLW 'A'
GOTO SENDIT
GOTCHAB
MOVLW 'B'
GOTO SENDIT
GOTCHAC
MOVLW 'C'
GOTO SENDIT
GOTCHAD
MOVLW 'D'
GOTO SENDIT
SENDIT
MOVWF RESULT1 ; PLACE RECEIVED CHAR IN RESULT1
; print results
; results in cos , sin=0
goto newline
MOVLW LOW A697COS2
MOVWF FSR
PrintRESULTS
; Save FSR
MOVF FSR, W
MOVWF XcomA
MOVF INDF,W
Call PRINTWHEX
;restore FSR
MOVF XcomA, W
MOVWF FSR
INCF FSR,F
INCF FSR,F
movf FSR, W
XORLW LOW A1633COS2+2
BTFSS STATUS,Z
GOTO PrintRESULTS
;newline
movf RESULT, W
call PRINTWHEX
movf RESULT2X, W
call PRINTWHEX
movf RESULT1, W
call TX_ADD_BUFFER
movlw 0x0d
call TX_ADD_BUFFER
movlw 0x0a
call TX_ADD_BUFFER
; wait to transmit all chars
WAIT_TX_BUFFER_EMPTY
MOVF TX_Buffer_Count,W ; get number of bytes
BTFSC STATUS,Z ; buffer empty ?
GOTO WAIT_TX_BUFFER_EMPTY
newline
; movf RESULT1, W
; call TX_ADD_BUFFER
;newline
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; DECISION ALGORITHM : A VALUE MUST BE DETECTED AT LEAST 2 TIMES
; BEFORE IS CONSIDERED VALID
; a missing value is accepted if it was detected at lest 2 times before
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
MOVF RESULT1, W ; use RESULT1 ASCII result
XORWF TEMP_VAL,W ; COMPARE RESULT WITH TEMP_VAL
BTFSC STATUS, Z
GOTO DECI1 ; ==
; RESULT1<>TEMP_VAL
decf TEMP_TIMES, F
btfss STATUS, Z
goto keepvalue ;<>0
; reset value
goto resetvalue
keepvalue ; keep old RESULT1 value, but temp_times=1 - this will allow 1 missing value
; reset temp times to 1
movlw 1
movwf TEMP_TIMES
bsf DTMF_RECOVER ; signal recover
; exception when temp_val='-' ==> reset to RESULT1
movlw '-'
xorwf TEMP_VAL, W ; compare '-' with result1
BTFSS STATUS, Z
GOTO keepvalue1 ; ==0
; reset value
resetvalue
movlw 1
movwf TEMP_TIMES
movf RESULT1, W
movwf TEMP_VAL
bcf DTMF_RECOVER ; no recover
keepvalue1
; no new digit detected
bcf DTMF_DETECTED
RETURN
; RESULT1==TEMP_VAL
DECI1
INCF TEMP_TIMES, F ; INC TEMP_TIMES
BTFSC STATUS,Z
DECF TEMP_TIMES, F ; if temp_times=0 decrement to 255
; check if TEMP_VAL='-'
movlw '-'
xorwf RESULT1, W ; compare '-' with result1 - if so temp_times=1 and return
BTFSS STATUS, Z
GOTO DECI3 ; <>0
movlw 1
movwf TEMP_TIMES
GOTO keepvalue1
DECI3
MOVLW .2 ; NUMBER OF TIMES DETECTED BEFORE DECIDE FOR A DIGIT!
XORWF TEMP_TIMES,W
BTFSS STATUS,Z
GOTO keepvalue1 ; <> no new digit
; GOT ONE VALUE MORE TIMES !!!!!!!!!!!
BTFSS DTMF_RECOVER ; test for recover
GOTO DECI2 ; no recover
bcf DTMF_RECOVER ; reset recover bit and return with no new digit
GOTO keepvalue1 ; no new digit
DECI2 ; exit with new digit
; return result
movf RESULT1, W
movwf DTMF_RESULT
bsf DTMF_DETECTED
RETURN
;************************************************************************
; send digit in W to DTMF GENERATOR 0-9, ",", #, *, A, B, C, D, +=1000hz, use XcomA
;************************************************************************
DTMF_digit:
movwf XcomA
;W = value
;addlw 255 - Hi
;addlw (Hi - Lo) + 1
;Carry is set if W is in range Lo - Hi
addlw 255-"9"
addlw ("9"-"0")+1
btfss STATUS,C ; bnc getvalues
goto DTMF_digit1
; it is a digit
movf XcomA,W ; w=digit
movlw 0x30
subwf XcomA,W ; w-f=w, 0-9 index in the table
; multiply index by 4
movwf XcomA
bcf STATUS,C
rlf XcomA,F
bcf STATUS,C
rlf XcomA,W
goto getvalues
DTMF_digit1 ; test A-D
movf XcomA,W
addlw 255-"D"
addlw ("D"-"A")+1
btfss STATUS,C ; bnc getvalues
goto DTMF_digit2
; it is A-D
movf XcomA,W ; w=digit
movlw 0x41
subwf XcomA,W ; w-f=w, A-D index in the table
; multiply index by 4
movwf XcomA
bcf STATUS,C
rlf XcomA,F
bcf STATUS,C
rlf XcomA,W
addlw 12*4 ; A index = 12
goto getvalues
DTMF_digit2
movf XcomA,W ; w=digit
SUBLW "," ; it is a comma?
BTFSC STATUS,Z
GOTO comma
movf XcomA,W
SUBLW "*" ; it is a *?
movlw 10*4
BTFSC STATUS,Z
GOTO getvalues
movf XcomA,W
SUBLW "#" ; it is a #?
movlw 11*4
BTFSC STATUS,Z
GOTO getvalues
movf XcomA,W
SUBLW "+" ; it is a #?
movlw 16*4
BTFSC STATUS,Z
GOTO getvalues
; it is something else...skip it
RETURN
getvalues:
movwf XcomA ; store index
MOVLW HIGH DTMF_GEN_TAB
MOVWF PCLATH
MOVF XcomA,W ; get index
CALL DTMF_GEN_TAB
MOVWF XAddHL ; lo freq hi
INCF XcomA,F ; increment index
MOVF XcomA,W ; get index
CALL DTMF_GEN_TAB
MOVWF XAddLL ; lo freq lo
INCF XcomA,F ; increment index
MOVF XcomA,W ; get index
CALL DTMF_GEN_TAB
MOVWF XAddHH ; Hi freq hi
INCF XcomA,F ; increment index
MOVF XcomA,W ; get index
CALL DTMF_GEN_TAB
MOVWF XAddLH ; Hi freq lo
; set 200 ms delay
;BSF TIMEOUT ; stop delay routine
MOVLW 161
MOVWF TIME0
MOVLW 7
MOVWF TIME1
; start DTMF Generator and delay routine
;DISABLE_IRQ
BSF DTMF_GEN_ON
BCF TIMEOUT ; start 200ms delay
;ENABLE_IRQ
DTMF_digit3:
BTFSS TIMEOUT
GOTO DTMF_digit3 ; wait for TIMEOUT=1
; stop DTMF
DISABLE_IRQ
BCF DTMF_GEN_ON
; continue from previous point, do not clear acc and PWM value
MOvLw B'00100000'
MOVLW CCPR1L ; initial PWM value = 128
BCF CCP1CON,5
BCF CCP1CON,4
CLRF AccLH
CLRF AccHH ; CLEAR High Freq Generator accumulator
CLRF AccLL
CLRF AccHL ; CLEAR Low Freq Generator accumulator
ENABLE_IRQ
; 100 ms pause
;DISABLE_IRQ
MOVLW 208
MOVWF TIME0
MOVLW 3
MOVWF TIME1
BCF TIMEOUT ; start 200ms delay
;ENABLE_IRQ
DTMF_digit4:
BTFSS TIMEOUT
GOTO DTMF_digit4 ; wait for TIMEOUT=1
RETURN
comma
; 500 ms pause
;DISABLE_IRQ
MOVLW 18
MOVWF TIME0
MOVLW 19
MOVWF TIME1
BCF TIMEOUT ; start 500ms delay
;ENABLE_IRQ
DTMF_digit5:
BTFSS TIMEOUT
GOTO DTMF_digit5 ; wait for TIMEOUT=1
RETURN
;************************************************************************
; send the string located at (XcomB:XcomC) in program memory to DTMF generator
DTMF_rom:
; set dtmf on
Bank2
movf XcomC, W ;Write the
movwf EEADR ;address bytes
movf XcomB, W
movwf EEADRH
bsf STATUS, RP0 ;Bank3
bsf EECON1, EEPGD ;Point to program memory
bsf EECON1, RD ;start read operation
nop ;required two nop's
nop
bcf STATUS, RP0 ;Bank2
movf EEDATA, W ;char in W
andlw 0xFF ;compare 0
btfsc STATUS, Z
goto DTMF_rom2
Bank0
; DTMF char in W
call DTMF_digit ; send char in w to DTMF generator
incfsz XcomC, F
goto DTMF_rom
incf XcomB, F
goto DTMF_rom
DTMF_rom2:
Bank0
; set PWM to 128
return
;************************************************************************
ser_ram: ;send from RAM to SERIAL buffer, string located at (IRP:W)
movwf FSR
ser_ram1: movlw 0
subwf INDF, w ; compare 0
btfsc STATUS, Z
return ; char = zero
movf INDF, W
CALL TX_ADD_BUFFER
incf FSR, F
goto ser_ram1
;************************************************************************
; send the string located at (XcomB:XcomA) in program memory to serial buffer
ser_rom:
Bank2
movf XcomA, W ;Write the
movwf EEADR ;address bytes
movf XcomB, W
movwf EEADRH
bsf STATUS, RP0 ;Bank3
bsf EECON1, EEPGD ;Point to program memory
bsf EECON1, RD ;start read operation
nop ;required two nop's
nop
bcf STATUS, RP0 ;Bank2
movf EEDATA, W ;char in W
andlw 0xFF ;compare 0
btfsc STATUS, Z
goto ser_rom2
Bank0
call TX_ADD_BUFFER ; print char in w
incfsz XcomA, F
goto ser_rom
incf XcomB, F
goto ser_rom
ser_rom2:
Bank0
movlw CR
call TX_ADD_BUFFER
movlw LF
call TX_ADD_BUFFER
return
; ***********************************************************************
;
; INIT_UART - Initialises UART
; enables recevier and transmitter
; Make sure to be at bank0
INIT_UART
; make sure pins are setup before calling this routine
; TRISC:6 and TRISC:7 must be set ( as for output, but operates as input/output -RB2 and RB5 for 16F88)
; furthermore its advised that interrupts are disabled during this routine
; setup baudrate
MOVLW SPBRG ; get adress for serial baud reg
MOVWF FSR ; setup fsr
MOVLW CALC_HIGH_BAUD(9600) ; calculate baudrate is this example 9600 with brgh=1
MOVWF INDF ; and store it
; enable transmitter
MOVLW TXSTA ; get adress for serial enable reg
MOVWF FSR ; setup fsr
MOVLW (1<<TXEN)|(1<<BRGH); preset enable transmitter and high speed mode
MOVWF INDF ; and set it
; enable recevier
MOVLW (1<<SPEN)|(1<<CREN) ; preset serial port enable and continous recevie
MOVWF RCSTA ; set it
; enable reciever interrupt
MOVLW PIE1 ; get adress for periphial irq's
MOVWF FSR ; setup fsr
BSF INDF,RCIE ; enable reciever irq
BSF INTCON,PEIE ; and periphial irq must also be enabled
RETURN
; ***********************************************************************
;
; INIT_BUFFERS - Initialises all buffers and pointers
; Make sure to be at bank0
INIT_BUFFERS
; setup receive buffer
CLRF RX_Buffer_Count ; clear counter
MOVLW RX_Buffer ; get base adress for buffer
MOVWF RX_Buffer_InPtr ; save as in adress
MOVWF RX_Buffer_OutPtr; and out adress
; setup transmit buffer
CLRF TX_Buffer_Count ; clear counter
MOVLW TX_Buffer ; get base adress for buffer
MOVWF TX_Buffer_InPtr ; save as in adress
MOVWF TX_Buffer_OutPtr; and out adress
BCF GOT_ONE ; no char in RxBuffer
RETURN
; ***********************************************************************
;
; TX_ADD_BUFFER - Puts one byte in serial tx buffer, blocks until room available
; Make sure to be at bank0 ( buffer pointers in bank0, buffers in bank1 )
;
; To be discussed - wait or return Z and discard
TX_ADD_BUFFER
MOVWF TX_Temp ; store byte temporarily
TX_ADD_TST
MOVF TX_Buffer_Count,W ; get count
XORLW TX_BUFFER_SIZE
BTFSC STATUS,Z ; test if any room
GOTO TX_ADD_TST ; nope no room, wait until there is
MOVF TX_Buffer_InPtr,W ; get adress to store byte
MOVWF FSR ; setup fsr
MOVF TX_Temp,W ; get byte
MOVWF INDF ; and store it
; update buffer pointers
INC_BUFFER TX_Buffer_InPtr,TX_Buffer,TX_BUFFER_SIZE
INCF TX_Buffer_Count,F ; increment byte count
; MUST not be GOT_ONEs until after byte is stored in buffer
; and pointers updated
MOVLW PIE1 ; get adress for periphial irq
MOVWF FSR ; setup fsr
BSF INDF,TXIE; and enable tx irq
RETURN
; ***********************************************************************
;
; RX_GET_BUFFER - Gets one byte from in serial rx buffer, if available
;
; Return Z is no data is available, GOT_ONE reset
RX_GET_BUFFER
MOVF RX_Buffer_Count,F ; check if anything available ?
BTFSC STATUS,Z ;
RETURN ; nope, nothing there, NOTE zero flag set !
MOVF FSR,W
MOVWF FSRSAVE
; get pointer
MOVF RX_Buffer_OutPtr,W
MOVWF FSR ; setup FSR
; update buffer pointers
INC_BUFFER RX_Buffer_OutPtr,RX_Buffer,RX_BUFFER_SIZE
; get byte to W
MOVF INDF,W
MOVWF Temp
MOVF FSRSAVE,W
MOVWF FSR
MOVF Temp,W
; decrement counter
DECF RX_Buffer_Count,F
BTFSC STATUS,Z ;
BCF GOT_ONE ; nope, nothing there, NOTE zero flag set, GOT_ONE reset
BCF STATUS,Z ; make sure zero flag is clear
RETURN
;************************************************************************
;EEprom routines by Tony Kubek
; ***********************************************************************
; EE_WRITE_BYTE - Routine to write a byte to ee ram
; Adress in W, byte MUST be in EE_Byte
EE_WRITE_BYTE
Bank2 ; select bank2
MOVWF EEADR ; setup adress
Bank0 ;
MOVF EE_Byte,W ; get byte
Bank2
MOVWF EEDATA ; setup byte to write
BSF STATUS,RP0 ; bank3 !!
BCF EECON1,EEPGD ; set to data ee ram
BSF EECON1,WREN ; enable writes
DISABLE_IRQ ; disable irq's
MOVLW H'55' ; required sequence !!
MOVWF EECON2
MOVLW H'AA'
MOVWF EECON2
BSF EECON1,WR ; begin write procedure
ENABLE_IRQ ; enable irq's again
BCF EECON1,WREN ; disable writes ( does not affect current write cycle )
Bank0 ; reset to bank0
; wait for the write to complete before we return
BTFSS PIR2,EEIF ; wait for interrupt flag to be set
GOTO $-1
; clear interupt bit and write enable bit
BCF PIR2,EEIF ;clear eewrite irq flag
RETURN
; ***********************************************************************
; EE_READ_BYTE - Routine to read a byte from ee ram
; Adress in W, byte will be delivered in W
EE_READ_BYTE
Bank2
MOVWF EEADR ; put in adress reg.
BSF STATUS,RP0 ; bank3 !!
BCF EECON1,EEPGD ; set to read data memory
BSF EECON1,RD ; set bit to read
BCF STATUS,RP0 ; bank2 !!
MOVF EEDATA,W ; move data to W
Bank0 ; Reset to BANK0 !
RETURN ; and return
;***************************************************************************
;***************************************************************************
; test strings
linie1: DE 10,13,"ClearView007 (c) 2004 Radu Constantinescu",10,13,0
linie2: DE "1234567890*#ABCD,,+++",0
linie3: DE "",0
linie4: DE "",0
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -