📄 an_008.asm
字号:
GOTO end_interrupt_RX2
no_resync:
INCF R, 1 ; R=R+1 (no resync)
GOTO end_interrupt_RX2
r_add_2:
INCF R, 1
INCF R, 1 ; R=R+2 (resync)
NOP
end_interrupt_RX2:
BCF CONTROL, R_ENABLE ; Set R_ENABLE=0
end_interrupt_RX:
NOP ; Use only NOP when datarate= 9.6 kbps
BCF INTCON, T0IF ; Set T0IF=0 -> Ready for next
; TMR0-interrupt
RETFIE ; Return from interrupt
;*****************************************************************************
;******************* TX-MODE *************************************************
;*****************************************************************************
; Initialisation of the TX-mode. CCX00 is configured and registers used in
; the MCU are initialised. The TMR0-interrupt is scaled for the correct data-
; rate, and enabled. Waits for interrupt.
;*****************************************************************************
mode_TX:
BSF STATUS, RP0 ; Select Bank1
BCF TRISC, DIO ; PORTC: Set DIO-pin as output
BCF STATUS, RP0 ; Select Bank0
CCX00_config_TX: ; Download configuration to
; CC700/CC900 using CLOCK, PDATA
; and STROBE (table look-up: TABLE_TX)
MOVLW TABLE_PT_val ; TABLE_PT is initially set to 0 ->
MOVWF TABLE_PT ; Shows where in the table to look up
; (From 0 to 15).
CLRF REG_COUNTER ; Counts the regisers configured
; in the CC700/CC900 (8 16bit
; registers). Initially 0.
BCF CONTROL, CONF_LOOP ; Two loops are used.
; CONF_LOOP=0 -> loop_inner_TX_1
; CONF_LOOP=1 -> loop_inner_TX_2
BCF PORTC, STROBE ; Set STROBE=0
BSF PORTC, CLOCK ; Set CLOCK=1
loop_outer_TX: ; This loop reads values from TABLE_TX
; and stores them in CONFIG_REG.
CLRF BIT_COUNTER ; Clears BIT_COUNTER. Counts the bits
; read from CONFIG_REG.
CALL Table_TX ; Look-up table
MOVWF CONFIG_REG ; Value read from TABLE_TX 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_TX_2 ; CONF_LOOP=0 -> loop_inner_TX_1
; CONF_LOOP=1 -> loop_inner_TX_2
loop_inner_TX_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_TX have been read.
GOTO loop_inner_TX_1 ; If not all 8 bits have been read ->
; Go to loop_inner_TX_1
BSF CONTROL, CONF_LOOP ; This loop is done. Execute
; loop_inner_RX_2 next time.
GOTO loop_outer_TX ; If all 8 bits have been read ->
; Go to loop_outer_TX
loop_inner_TX_2: ; Used for _L registers 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_TX ; If all 8 bits have been read ->
; Go to set_strobe_TX.
BSF PORTC, CLOCK ; Set CLOCK=1
GOTO loop_inner_TX_2 ; If not all 8 bits have been read ->
; Go to loop_inner_TX_2
set_strobe_TX:
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_TX_1 next time
BTFSS REG_COUNTER, 3 ; Check if all 8 registers in the
; CC700/CC900 has been configured
GOTO loop_outer_TX ; If not-> Go to loop_outer_TX
BCF PORTC, STROBE ; Set STROBE=0
BCF PORTC, CLOCK ; Set CLOCK=0
init_TX: ; Gives registers initial values
BCF MODE, RXTX ; Set RXTX=0 -> shows TX-mode
; after TMR0-interrupt
BCF MODE, NUMBER ; Set NUMBER=0 (Decides which (of 2)
; interrupt to execute in TX-mode)
CLRF PORTB ; Clear PORTB
enable_interrupt_TX: ; Enables interrupt in TX-mode
MOVLW 0xFC
MOVWF TMR0
BSF STATUS, RP0 ; Select Bank1
MOVLW Rate_TX
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 and T01F)
GOTO wait_for_interrupt
;*****************************************************************************
;*********** TMR0-INTERRUPT IN TX-MODE ***************************************
;*****************************************************************************
; Two interrups occur per bit, one for each baud of the outgoing Manchester
; coded signal at the DIO-pin.
;*****************************************************************************
mode_TX_routine: ; TMR0-interrupt routine in TX-mode
MOVLW TIMING_TX
MOVWF TMR0 ; TMR0=TIMING_TX
BTFSC MODE, NUMBER ; Check which interrupt to execute
GOTO second_TX ; If NUMBER=1 -> Go to second_TX
GOTO first_TX ; If NUMBER=0 -> Go to first_TX
first_TX: ; First baud
BSF PORTB, CLK_OUT ; Set CLK_OUT=1
BCF MODE, READ ; Set READ=0 in MODE-register
BTFSC PORTB, DATA_IN ; Check DATA_IN-pin
BSF MODE, READ ; If DATA_IN=1 -> Set READ=1
BTFSC MODE, READ ; Check READ
BSF PORTC, DIO ; If READ=1 (DATA_IN=1) ->
; Set DIO=1 (First baud)
BTFSS MODE, READ ; Check READ
BCF PORTC, DIO ; If READ=0 (DATA_IN=0) ->
; Set DIO=0 (First baud)
BSF MODE, NUMBER ; Set NUMBER=1
GOTO end_interrupt_TX
second_TX: ; Second baud
BCF PORTB, CLK_OUT ; Set CLK_OUT=0
BTFSC MODE, READ ; Check READ
BCF PORTC, DIO ; If READ=1 (DATA_IN=1) ->
; Set DIO=0 (Second baud)
BTFSS MODE, READ ; Check READ
BSF PORTC, DIO ; If READ=0 (DATA_IN=0) ->
; Set DIO=1 (Second baud)
BCF MODE, NUMBER ; Set NUMBER=0
end_interrupt_TX:
NOP
BCF INTCON, T0IF ; Set T0IF=0 ->
; Ready for next TMR0-interrupt
RETFIE ; Return from interrupt
;*****************************************************************************
;******************* PD-MODE *************************************************
;*****************************************************************************
; Initialisation of the PD-mode. The CC700/CC900 is configured and the MCU
; enters sleep mode. Only the external interrupt is enabled (mode change)
;*****************************************************************************
mode_PD:
CCX00_config_PD: ; Download configuration to CCX00
; using CLOCK, PDATA og STROBE
; (table look-up: TABLE_PD)
MOVLW TABLE_PT_val ; TABLE_PT initially 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
; the CC700/CC900 (8 16bit registers)
; Initially 0.
BCF CONTROL, CONF_LOOP ; Two loops are used.
; CONF_LOOP=0 -> loop_inner_PD_1
; CONF_LOOP=1 -> loop_inner_PD_2
BCF PORTC, STROBE ; Set STROBE=0
BSF PORTC, CLOCK ; Set CLOCK=1
loop_outer_PD: ; This loop reads values from TABLE_PD
; and stores them in CONFIG_REG.
CLRF BIT_COUNTER ; Clears BIT_COUNTER. Counts the bits
; read from CONFIG_REG.
CALL Table_PD ; 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_PD_2 ; CONF_LOOP=0 -> loop_inner_PD_1
; CONF_LOOP=1 -> loop_inner_PD_2
loop_inner_PD_1: ; Used for _H registers from table.
; MSB of CC700/CC900 register
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_PD have been read.
GOTO loop_inner_PD_1 ; If not all 8 bits have been read ->
; Go to loop_inner_PD_1
BSF CONTROL, CONF_LOOP ; This loop is done. Execute
; loop_inner_PD_2 next time.
GOTO loop_outer_PD ; If all 8 bits have been read ->
; Go to loop_outer_PD
loop_inner_PD_2: ; Used for _L registers from table.
; LSB of CC700/CC900 register
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_PD ; If all 8 bits have been read ->
; Go to set_strobe_PD.
BSF PORTC, CLOCK ; Set CLOCK=1
GOTO loop_inner_PD_2 ; If not all 8 bits have been read ->
; Go to loop_inner_PD_2
set_strobe_PD:
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_PD_1 next time
BTFSS REG_COUNTER, 3 ; Check if all 8 registers in the
; CC700/CC900 are configured
GOTO loop_outer_PD ; If not-> Go to loop_outer_PD
BCF PORTC, STROBE ; Set STROBE=0
BCF PORTC, CLOCK ; Set CLOCK=0
init_PD: ; Clear all output pins
CLRF PORTC ; Clear output data latches
BCF PORTB, CLK_OUT ; Set CLK_OUT=0
BCF PORTB, DATA_OUT ; Set DATA_OUT=0
enable_interrupt_PD:
MOVLW 0x88
MOVWF INTCON ; Enables interrupt (external) ->
; Sets GIE=1, RBIE=1,
; the rest are 0 (including RBIF)
wait_for_interrupt_PD: ; Wait for External interrupt on PORTB
SLEEP ; MCU in sleep mode
NOP ; Does nothing before an interrupt
; occurs
GOTO wait_for_interrupt_PD
;*****************************************************************************
; Look-up tables used for configuration of CC700/CC900
; 3 tables, one for each possible mode: PD, RX and TX
;*****************************************************************************
ORG 0x06
Table_RX:
MOVFW TABLE_PT
ADDWF PCL, 1
RETLW A_RX_H_val
RETLW A_RX_L_val
RETLW B_RX_H_val
RETLW B_RX_L_val
RETLW C_RX_H_val
RETLW C_RX_L_val
RETLW D_RX_H_val
RETLW D_RX_L_val
RETLW E_RX_H_val
RETLW E_RX_L_val
RETLW F_RX_H_val
RETLW F_RX_L_val
RETLW G_RX_H_val
RETLW G_RX_L_val
RETLW H_RX_H_val
RETLW H_RX_L_val
ORG 0x18
Table_TX:
MOVFW TABLE_PT
ADDWF PCL, 1
RETLW A_TX_H_val
RETLW A_TX_L_val
RETLW B_TX_H_val
RETLW B_TX_L_val
RETLW C_TX_H_val
RETLW C_TX_L_val
RETLW D_TX_H_val
RETLW D_TX_L_val
RETLW E_TX_H_val
RETLW E_TX_L_val
RETLW F_TX_H_val
RETLW F_TX_L_val
RETLW G_TX_H_val
RETLW G_TX_L_val
RETLW H_TX_H_val
RETLW H_TX_L_val
ORG 0x2A
Table_PD:
MOVFW TABLE_PT
ADDWF PCL, 1
RETLW A_PD_H_val
RETLW A_PD_L_val
RETLW B_PD_H_val
RETLW B_PD_L_val
RETLW C_PD_H_val
RETLW C_PD_L_val
RETLW D_PD_H_val
RETLW D_PD_L_val
RETLW E_PD_H_val
RETLW E_PD_L_val
RETLW F_PD_H_val
RETLW F_PD_L_val
RETLW G_PD_H_val
RETLW G_PD_L_val
RETLW H_PD_H_val
RETLW H_PD_L_val
;*****************************************************************************
END
;*****************************************************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -