⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 clearview007.asm

📁 DTMF decoder using pic16f
💻 ASM
📖 第 1 页 / 共 3 页
字号:
	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 + -