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

📄 an_008.asm

📁 One of the most important issues affecting the implementation of microcontroller software deals wi
💻 ASM
📖 第 1 页 / 共 3 页
字号:
        BCF     STATUS, RP1     	; Select Bank0
        CLRF    PORTC			; Clear output data latches
        CLRF    PORTB        		; Clear output data latches
        BSF     STATUS, RP0     	; Select Bank1
        MOVLW   0x08            	; PORTC: Pin 0, 1 og 2 as output
					; (PDATA, CLOCK and STROBE)
        MOVWF   TRISC           	; PORTC: Pin 3 as input (DIO)
        MOVLW   0X32            	; PORTB: Pin 0 og 2 as output
					; (CLK_OUT and DATA_OUT)
        MOVWF   TRISB           	; PORTB: Pin 1, 4 og 5 as input
					; (DATA_IN, RX/TX and PD)
        BCF     STATUS, RP0     	; Select Bank0
        GOTO    mode_decision   	; Go to mode_decision


;*****************************************************************************
; Interrupt handler
;*****************************************************************************

ServiceInterrupt:
        BTFSC   INTCON, RBIF    	; Check if external interrupt 
					; (PD or RX/TX)
        GOTO    mode_decision   	; If external interrupt ->
					; go to mode_decision
        

                      
interrupt_internal:
        BTFSC   MODE, RXTX   		; Check if system was in RX/TX-mode
					; before interrupt
        GOTO    mode_RX_routine		; If RXTX=1 ->go to mode_RX_routine
        GOTO    mode_TX_routine		; If RXTX=0 ->go to mode_TX_routine 
                   
mode_decision:        
        MOVF    PORTB, 0  		; Read PORTB
        MOVWF   TEMP   			; Store PORTB in TEMP
        BTFSC   TEMP, 4   		; Check PD
        GOTO    mode_PD  		; If PD=1 -> go to mode_PD               
        BTFSC   TEMP, 5   		; Check RX_TX
        GOTO    mode_RX   		; If RX_TX=1 ->go to mode_RX
        GOTO    mode_TX   		; If RX_TX=0 ->go to mode_TX
  	


;*****************************************************************************
;******************* RX-MODE *************************************************
;*****************************************************************************
; Initialisation of the RX-mode. The CC700/CC900 is configured and registers
; used in MCU are initialised. The TMR0-interrupt is scaled for the correct
; data-rate, and enabled. Waits for interrupt.
;*****************************************************************************
           
mode_RX:                            
        BSF     STATUS, RP0   		; Select Bank1
        BSF     TRISC, DIO    		; PORTC: Set DIO-pin as input
        BCF     STATUS, RP0 		; Select Bank0


CCX00_config_RX:   			; Download configuration to CCX00 with
					; CLOCK, PDATA og STROBE (table 
					; look-up: TABLE_RX) 

	MOVLW	TABLE_PT_val		; TABLE_PT initialy set to 0 ->
	MOVWF	TABLE_PT		; Shows where in the table to look up
					; (From 0 to 15).
	CLRF	REG_COUNTER		; Counts the registers configured in
					; CC700/CC900 (8 16bit registers).
					; Initially 0.
	BCF	CONTROL, CONF_LOOP	; Two loops are used. 
					; CONF_LOOP=0 -> loop_inner_RX_1
					; CONF_LOOP=1 -> loop_inner_RX_2
	BCF 	PORTC, STROBE  		; Set STROBE=0
        BSF 	PORTC, CLOCK   		; Set CLOCK=1


loop_outer_RX:				; This loop reads values from TABLE_RX
					; and stores them in CONFIG_REG.
	CLRF	BIT_COUNTER		; Clear BIT_COUNTER. Counts the bits
					; read from CONFIG_REG.
	CALL 	Table_RX		; Look-up table
	MOVWF	CONFIG_REG		; Value read from TABLE_RX is
					; stored in CONFIG_REG
	INCF	TABLE_PT, 1		; Increment table pointer. Read next
					; register next time.
	BTFSC	CONTROL, CONF_LOOP	; Checks which loop to execute
	GOTO 	loop_inner_RX_2		; CONF_LOOP=0 -> loop_inner_RX_1. 
					; CONF_LOOP=1 -> loop_inner_RX_2


loop_inner_RX_1:            		; Used for _H regisers from table.
					; MSB of CC700/CC900 registers
	RLF	CONFIG_REG, 1		; Rotate CONFIG_REG. 
					; Most significant bit moves to CARRY
	BTFSC   STATUS, CARRY 		; Check if PDATA should be high
	BSF     PORTC, PDATA   		; If high -> Set PDATA=1
	BTFSS   STATUS, CARRY   	; Check if PDATA should be low
	BCF     PORTC, PDATA    	; If low -> Set PDATA=0
	BCF     PORTC, CLOCK    	; Set CLOCK=0. For 50% duty cycle
					; configuration clock -> Include 4 NOP
	INCF	BIT_COUNTER, 1		; Increase BIT_COUNTER. Another bit is
					; read.
	BSF     PORTC, CLOCK    	; Set CLOCK=1
	BTFSS	BIT_COUNTER, 3		; Check if all 8 bits in register
					; CONFIG_RX have been read.
	GOTO 	loop_inner_RX_1		; If not all 8 bits have been read ->
					; Go to loop_inner_RX_1
	BSF	CONTROL, CONF_LOOP	; This loop is done. Execute
					; loop_inner_RX_2 next time.
	GOTO	loop_outer_RX		; If all 8 bits have been read ->
					; Go to loop_outer_RX
					

loop_inner_RX_2:			; Used for _L regisers from table.
					; LSB of CC700/CC900 registers
	RLF	CONFIG_REG, 1		; Rotate CONFIG_REG.
					; Most significant bit moves to CARRY
	BTFSC   STATUS, CARRY 		; Check if PDATA should be high
	BSF     PORTC, PDATA    	; If high -> Set PDATA=1
	BTFSS   STATUS, CARRY   	; Check if PDATA should be low
	BCF     PORTC, PDATA    	; If low -> Set PDATA=0
	BCF     PORTC, CLOCK    	; Set CLOCK=0.
	INCF	BIT_COUNTER, 1		; Increase BIT_COUNTER. Another bit is
					; read.
	BTFSC	BIT_COUNTER, 3		; Check if all 8 registers have
					; been read.
	GOTO	set_strobe_RX		; If all 8 bits have been read ->
					; Go to set_strobe_RX.
	BSF     PORTC, CLOCK    	; Set CLOCK=1
	GOTO 	loop_inner_RX_2		; If not all 8 bits are read ->
					; Go to loop_inner_RX_2

	
set_strobe_RX:			
	BSF     PORTC, STROBE   	; Set STROBE=1
	BSF     PORTC, CLOCK   		; Set CLOCK=1
	BCF     PORTC, STROBE   	; Set STROBE=0
	INCF	REG_COUNTER, 1		; Increase REG_COUNTER. An entire 16
					; bit register in the CC700/CC900 has
					; been configured.
	BCF	CONTROL, CONF_LOOP	; Do loop_inner_RX_1 next time
	BTFSS	REG_COUNTER, 3 		; Check if all 8 registers in
					; CC700/C900 have been configured
	GOTO	loop_outer_RX		; If not-> Go to loop_outer_RX
	BCF     PORTC, STROBE		; Set STROBE=0
        BCF     PORTC, CLOCK 		; Set CLOCK=0
              

init_RX:       				; Give registers initial values
        CLRF    X    			; X=00000000
        MOVLW   0x08            
        MOVWF   A  			; A=1000 (LSB)
        MOVWF   An1  			; An1=1000 (LSB)
        MOVWF   An2 			; An2=1000 (LSB)
        CLRF    R 			; R=000 (LSB)
        CLRF    COUNT			; COUNT=000 (LSB)
        CLRF    CONTROL			; CONTROL=00 (LSB)
        MOVLW   A_LIMIT_val
        MOVWF   A_LIMIT			; A_LIMIT=A_LIMIT_val
        MOVLW   A_LIMIT_val2
        MOVWF   A_LIMIT2		; A_LIMIT2=A_LIMIT_val2
					; (>4, Must not sync on 000..)
	MOVLW   COUNT_LIMIT_val  
        MOVWF   COUNT_LIMIT		; COUNT_LIMIT=COUNT_LIMIT_val 
        CLRF    INPUT			; INPUT=0 (LSB)
        BSF     MODE, RXTX		; Set RXTX=1 -> shows RX-mode after
					; TMR0-interrupt
        


enable_interrupt_RX:			; Enables interrupt in RX-mode
        MOVLW	0xFD		
	MOVWF	TMR0			; Change TMR0 register value (first
					; interrupt after just a short while)
        BSF     STATUS, RP0		; Select Bank1
        MOVLW   Rate_RX		
        MOVWF   OPTION_REG		; Set TIMER0 Rate
        BCF     STATUS, RP0		; Select Bank0
        MOVLW   0xA8         
        MOVWF   INTCON			; Enables interrupts (external and
					; internal) -> GIE=1, T0IE=1, RBIE=1,
					; others=0 (incl RBIF OG T01F)


wait_for_interrupt:

					; Update sync pin
	
	BTFSS	CONTROL,SYNC		; If SYNC bit is set,
	BCF	PORTC, 4		; set SYNC pin
	BTFSC	CONTROL,SYNC		; If SYNC bit is cleared,
	BSF	PORTC, 4		; clear SYNC pin
 	
	GOTO wait_for_interrupt		; Loop. Wait for interrupt.
					; Return here after TMR0-interrupt



;*****************************************************************************
;*********** TMR0-INTERRUPT IN RX-MODE ***************************************
;*****************************************************************************
; Each time an interrupt occurs, the DIO-pin is sampled.
; 8 interrupts (samples) per bit. Resynchronisation is done after each bit.
;*****************************************************************************

mode_RX_routine:			; TMR0-interrupt routine in RX-mode
        MOVLW	TIMING_RX	
	MOVWF	TMR0			; TMR0=TIMING_TX
        BCF     INPUT, DI		; Clear DI bit in INPUT-register
	BTFSC   PORTC, DIO		; Check DIO-pin
        BSF     INPUT, DI		; If DIO=1 -> DI=1


       
store_two_last_A: 			; Store two last values of A
        MOVF    An1, 0		
        MOVWF   An2 			; An2=An1
        MOVF    A, 0
        MOVWF   An1			; An1=A
               


calculate_A:				; Calculate new A
        BCF     STATUS, CARRY		; Clear CARRY    
        BTFSC   INPUT, DI		; Check DI (DIO-pin)
        BSF     STATUS, CARRY		; If DIO was 1 -> CARRY=1
        RRF     X, 1			; Shift DIO value into X (from right)
        MOVLW   0X08	
        XORWF   X, 1			; Inverts bit nr 4 in X
	BTFSS   X, 7			; If X7=0 -> Increment A
        INCF    A, 1            	
	BTFSS   STATUS, CARRY		; If CARRY=0 -> Decrement A
        DECF    A, 1		
        BTFSC   X, 3			; If X3=1 -> Decrement A
        DECF    A, 1        
        BTFSS   X, 3			; If X3=0 -> Increment A
        INCF    A, 1 
        

sample_number:	
        BTFSC   CONTROL, R_ENABLE   	; Check if R_ENABLE=1
        GOTO    resync              	; If R_ENABLE=1 -> Go to resync
        MOVF    R, 0               	
        XORLW   SAMPLE_ALL		; R xor 00000111
        BTFSC   STATUS, Z		; Check if R=111
        GOTO    sync			; If R=111 -> Go to sync
        MOVF    R, 0
        XORLW   SAMPLE_HALF		; R xor 00000011
        BTFSC   STATUS, Z		; Check if R=011
        BSF     PORTB, CLK_OUT		; If R=011 -> Set CLK_OUT =1
        INCF    R, 1			; R=R+1       
        GOTO    end_interrupt_RX


sync:   							
        BTFSC   CONTROL, SYNC		; Check SYNC-bit in CONTROL-register
        GOTO    sync_ok			; If SYNC=1 -> Go to sync_ok 
        MOVF    A_LIMIT2, 0
        SUBWF   A, 0			; A-A_LIMIT2
        MOVWF   TEMP			; Store difference in TEMP
        BTFSS   TEMP, 7			; Check if TEMP is pos/neg
					; (A>/<A_LIMIT)
        GOTO    sync_A_upper		; If A>=A_LIMIT2 (DIO=1) -> Go to
					; sync_A_upper
        CLRF    COUNT			; If A<A_LIMIT -> clear COUNT
        CLRF    R			; Clear R
        BSF     CONTROL, R_ENABLE	; Set R_ENABLE=1
        GOTO    end_interrupt_RX



sync_ok:				; Detect loss of sync
	MOVF	A, 0
	SUBLW	A_SYNC_LIMIT_hi	    	; W=A_SYNC_LIMIT_hi-A
	MOVWF	TEMP		    	; Store difference in TEMP
	BTFSC	TEMP,7		    	; Skip if result positive
	GOTO	signal_OK           	; Result is negative, signal is OK
	MOVF	A,0
	SUBLW	A_SYNC_LIMIT_lo	    	; W=A_SYNC_LIMIT_lo-A
	MOVWF	TEMP		    	; Store difference in TEMP
	BTFSS	TEMP,7		    	; Skip if result negative
	GOTO    signal_OK   	    	; Result is positive, signal is OK
	
					; Signal is not OK
	INCF	BIT_ERRORS,1	    	; Increase number of detected errors
	MOVF	BIT_ERRORS,0
	SUBLW	BIT_ERROR_LIMIT_val 	; W=BIT_ERROR_LIMIT_val-BIT_ERRORS
	BTFSS	STATUS,Z	    	; Skip if zero
	GOTO	sync_ok2	    	; Continue

					; Reached error limit
	BCF	CONTROL,SYNC		; Clear sync bit
	
signal_OK:
	CLRF	BIT_ERRORS	    	; Clear errors

sync_ok2:								
        SUBWF   A, 0			; A-A_LIMIT
        MOVWF   TEMP			; Store difference in TEMP
        BTFSS   TEMP, 7			; Check if TEMP is pos/neg
					; (A>/<A_LIMIT)
        GOTO    data_out_high		; If A>=A_LIMIT (DIO=1) ->
					; Go to data_out_high
        BCF     PORTB, DATA_OUT		; If A<A_LIMIT (DIO=1) ->
					; Set DATA_OUT=0
        BCF     PORTB, CLK_OUT		; Set CLK_OUT=0     
        CLRF    R			; Clear R
        BSF     CONTROL, R_ENABLE	; Sett R_ENABLE=1
        GOTO    end_interrupt_RX



data_out_high:		
        BSF     PORTB, DATA_OUT		; Set DATA_OUT=1
        BCF     PORTB, CLK_OUT		; Set CLK_OUT=0       
        CLRF    R			; Clear R
        BSF     CONTROL, R_ENABLE	; Set R_ENABLE=1 
					; (resync next interrupt)
	NOP			
        GOTO    end_interrupt_RX


sync_A_upper:				; Synchronise; bit received is a 1
        MOVF    COUNT_LIMIT, 0  
        SUBWF   COUNT, 0		; COUNT-COUNT_LIMIT
        BTFSC   STATUS, Z		; Z=0 if COUNT=COUNT_LIMIT 
        BSF     CONTROL, SYNC		; If COUNT=COUNT_LIMIT -> Set SYNC=1
        INCF    COUNT, 1		; COUNT=COUNT+1        
        CLRF    R			; Clear R
        BSF     CONTROL, R_ENABLE	; Set R_ENABLE=1
	NOP									
        GOTO    end_interrupt_RX
 
 
        
resync:		
        MOVF    An1, 0	
        SUBWF   An2, 0			; An2-An1
        MOVWF   TEMP1			; Store difference in TEMP1
        BTFSS   TEMP1, 7		; Check if TEMP1 is pos/neg
					; (An2>/<An1)
        GOTO    resync_1 		; If An2>=An1 -> Go to resync_1
        MOVF    A, 0	
        SUBWF   An1, 0			; An1-A
        MOVWF   TEMP2			; Store difference in TEMP2
        BTFSC   TEMP2, 7		; Check if TEMP2 is pos/neg (An1>/<A)
        GOTO    resync_2		; If An1<A -> Go to resync_2
        INCF    R, 1			; R=R+1 (no resync)
        GOTO    end_interrupt_RX2
  


resync_1:
        MOVF    A, 0	
        SUBWF   An1, 0			; An1-A
        MOVWF   TEMP2			; Store difference in TEMP2
        BTFSS   TEMP2, 7		; Check if TEMP2 is pos/neg (An1>/<A)
        GOTO    resync_3		; If An1>=A -> Go to resync_3
        BTFSC   CONTROL, SYNC		; Check SYNC-bit in CONTROL-register
        INCF    R, 1			; If SYNC=1 -> R=R+1 (no resync)
        GOTO    end_interrupt_RX2	



resync_2:
        NOP
	BTFSS   CONTROL, SYNC		; Check SYNC-bit in CONTROL-register
        GOTO 	end_interrupt_RX2  	; If SYNC=0 -> Go to end_interrupt_RX
  	MOVF    A_LIMIT, 0
        SUBWF   An1, 0			; A-A_LIMIT
        MOVWF   TEMP			; Store difference in TEMP
        BTFSC   TEMP, 7			; Check if TEMP is pos/neg
					; (An1>/<A_LIMIT)
        GOTO    r_add_2			; If not An1>=A_LIMIT -> Go to r_add_2
        GOTO    end_interrupt_RX2
        
        
        
resync_3:								
        MOVF    TEMP1, 1		; TEMP1 written to itself 
					; (Z is affected)
        BTFSC   STATUS, Z		; Check if An2=An1
        GOTO    no_resync		; If An2=An1 -> Go_to no_resync
        MOVF    TEMP2, 1		; TEMP2 written to itself
					; (Z is affected)
        BTFSC   STATUS, Z		; Check if An1=A
        GOTO    no_resync		; If An1=A -> Go_to no_resync
        MOVF    A_LIMIT, 0 
        SUBWF   An1, 0			; A-A_LIMIT
        MOVWF   TEMP			; Store difference in TEMP
        BTFSS   TEMP, 7			; Check if TEMP is pos/neg
					; (An1>/<A_LIMIT)
        GOTO    r_add_2			; If An1>=A_LIMIT -> Go to r_add2

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -