📄 uart_sw.asm
字号:
CLR bit_count ; Clear bit number (LSB first)
; Synchronization delay~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LD A,CNTRL ; Read counter
LD X,CNTRH
ADD A,#$30 ; Add a delay to this value.
LD Y,A
LD A,X
ADC A,#$00
LD DCR0H,A ; An output compare will occur after the delay.
CALL CHK_cnt
LD DCR0L,Y ;
CALL ENB_ocmp ; Set clock & interrupt enable
RIM ; Remove interrupt mask.
; Loop for sending byte ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
trans_wait
BTJF sci_status,#BS,trans_wait ; Byte sent?
SIM ; Set interrupt mask.
RET
;------------------------------------------------------------------------------
;ROUTINE NAME : CHK_cnt
;INPUT/OUTPUT : Y reg.
;DESCRIPTION : Check counter
;COMMENTS :
;------------------------------------------------------------------------------
CHK_cnt
CP Y,#$00
JRNE chk_cnt_ret
INC Y
chk_cnt_ret
RET
;+--------------------------------------------------------------------------------------+
;Interrupt routine defination
;+--------------------------------------------------------------------------------------+
; ********************************************
; * *
; * INTERRUPT SUB-ROUTINES SECTION *
; * *
; ********************************************
;------------------------------------------------------------------------------
;ROUTINE NAME : OpComp_INT (Interrupt routine)
;INPUT/OUTPUT :
;DESCRIPTION : Output compare interrupt
;COMMENTS : Used for both transmition & reception mode
;------------------------------------------------------------------------------
.OPCOMP_int
BTJF PWM0CSR,#CMPF0,opcomp_int_ret ; Is it an OCMP? Yes continue, else return.
BRES ATCSR,#CMPIE ; Disable interrupt
LD A,bit_count ;
JRNE rxtx_routine ; Check for first bit
LD A,CNTRL ; Read counter (reference count )
LD X,CNTRH ;
LD DCR0H,X ; Set DCRXX reg's
LD DCR0L,A ;
rxtx_routine
CALL OPCOMP_appln ; Receive & transmit routine
opcomp_int_ret
IRET
;------------------------------------------------------------------------------
;ROUTINE NAME : OPCOMP_appln
;INPUT/OUTPUT :
;DESCRIPTION : Handle receive & transmit section
;COMMENTS :
;------------------------------------------------------------------------------
OPCOMP_appln
LD A,sci_status ; SCI mode in A.
CP A,#$10 ; Transmission mode?
JRNE rx_proc ; Yes continue, else go to RX_bit.
; Transmission process ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LD A,bit_count
CP A,#0 ; Check for START?
JRNE chk_stop_bit ; Yes continue, else go to chk_stop_bit
BRES PADR,#3 ; START bit
JP next_bit_condn
chk_stop_bit
LD A,bit_count ;
CP A,#data_length ; STOP bit sent?
JRNE chk_data ; Yes continue, else go to chk_data
; Byte sent ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BSET sci_status,#BS ; Byte sent, so set BS
LD A,ATCSR ;
AND A,#$06 ; STOP CLK, Reset CMPIE
LD ATCSR,A
JRA opcomp_appln_ret
chk_data
CP A,txrx_data_lnth ; all data bit sent?
JRULT tx_data_bit
; Send stop bit ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BSET PADR,#TxD ; Put PA3 pin in high level for STOP bit.
JRA next_bit_condn
; Send next data bit ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
tx_data_bit
BTJF tx_byte,#0,tx_bit_0 ; Is the next bit to sent equal to 1?
BSET PADR,#TxD ; Put TxD pin in high level (bit=1) for 1 bit.
JRA shift_bit
tx_bit_0
BRES PADR,#TxD ; Put TxD pin in low level (bit=0) for 1 bit.
; Create a delay of 1 bit ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
shift_bit
SRL tx_byte ; Put the next bit to send as bit 0 of tx_byte.
next_bit_condn
INC bit_count ; Increment bit number.
LD A,DCR0L ; Read the last OCMP value.
LD X,DCR0H
ADD A,del_1bl ; Add a delay of one bit to this value.
LD Y,A
LD A,X
ADC A,del_1bh
LD DCR0H,A ; An OCMP will occur one bit after
CALL CHK_cnt
LD DCR0L,Y ;
; End of the output compare management ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
enb_cmpie
TNZ PWM0CSR ; For clearing the CMPF0 BIT/Interrupt.
BSET ATCSR,#CMPIE ;
opcomp_appln_ret
RET
; Check for receive section~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
rx_proc
CP A,#$05 ; Reception mode?
JRNE enb_cmpie ; Yes continue, else go to enb_cmpie
; Reception mode ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LD A,bit_count
CP A,#data_length ; Byte completely received?
JRUGE byte_received ; No continue, else go to byte_received
; Read & check the new bit ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LD A,PADR
RLC A
RLC A
AND A,#Mask_ICAP1 ; Check the first sample of RxD pin.
LD tmp_var,A
LD A,PADR
RLC A
RLC A
AND A,#Mask_ICAP1 ; Check the second sample of RxD pin.
ADD A,tmp_var ; Add it to the first value.
LD tmp_var,A
LD A,PADR
RLC A
RLC A
AND A,#Mask_ICAP1 ; Check the third sample of RxD pin.
ADD A,tmp_var ; Add it to the former value.
PUSH A
;Check START bit~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
LD A,bit_count
CP A,#0 ; Is it START?
JRNE stop_chk ; No continue, with START received
POP A
CP A,#$02 ;
JRMI next_bit_condn
; Optional: User can modify here to handle errors~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
JP next_bit_condn
stop_chk
LD A,bit_count
CP A,txrx_data_lnth ; Is it STOP?
JRULT databit_chk
POP A
CP A,#$02 ; Two or three '1' received?
JRUGE rx_end_chk
; Optional: User can modify here to handle errors~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
; JP byte_received
rx_end_chk
LD A,bit_count
INC A
CP A,#data_length
JRUGE byte_received
JP next_bit_condn
;Data part~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
databit_chk
POP A
CP A,#$02 ; Two or three '1' received?
JRMI receive_0 ; Yes continue, else go to receive_0
LD A,rx_byte
ADD A,posn_bit
LD rx_byte,A ; Store received data in rx_byte
; Create a delay of 1 bit ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
receive_0
SLL posn_bit
JRA next_bit_condn
; New byte received ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
byte_received
BSET sci_status,#BR ; Byte received
LD A,ATCSR
AND A,#$06 ; STOP CLK, Reset CMPIE
LD ATCSR,A
JRA opcomp_appln_ret
;------------------------------------------------------------------------------
;ROUTINE NAME : IpCap_INT (Interrupt routine)
;INPUT/OUTPUT :
;DESCRIPTION : Input capture used to detect START bit
;COMMENTS :
;------------------------------------------------------------------------------
.EI1_int
LD A,CNTRL ; Check the current value of counter
LD X,CNTRH
ADD A,del_sampl ; Add a delay to have a OCMP after 0.5 bit
LD Y,A ; after the input capture
LD A,X
ADC A,del_samph
LD DCR0H,A ; An output compare will occur in 0.5 bit.
; Remove pending OCMP interrupt.
CALL CHK_cnt
LD DCR0L,Y
; Enter in sampling mode ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
BSET sci_status,#SP ; Enter sampling mode.
BRES PAOR,#RxD ; PA7 defined as input floating,
BRES PADDR,#RxD ; No interrupt
CALL ENB_ocmp ; Set counter clock & Enable OCMP interrupt
.Dummy
IRET
ENB_ocmp
TNZ PWM0CSR ; Clear pending OCMP interrupt
BRES PWMCR,#OE0 ; Enable OPC function
LD A,#$11 ; CMPIE=1:Compare Interrupt Enable.
LD ATCSR,A ; Counter Clock = fCPU
RET
;+--------------------------------------------------------------------------------------+
segment byte at FFE0-FFFF 'vectit' ; Defines Vector Interrupt Segment
;+--------------------------------------------------------------------------------------+
;| INTERRUPT VECTORS |
;+--------------------------------------------------------------------------------------+
DC.W Dummy ;FFE0-FFE1h location
DC.W Dummy ;FFE2-FFE3h location
DC.W Dummy ;FFE4-FFE5h location
DC.W Dummy ;FFE6-FFE7h location
DC.W Dummy ;FFE8-FFE9h location
DC.W OPCOMP_int ;FFEA-FFEBh location
DC.W Dummy ;FFEC-FFEDh location
DC.W Dummy ;FFEE-FFEFh location
DC.W Dummy ;FFF0-FFF1h location
DC.W Dummy ;FFF2-FFF3h location
DC.W Dummy ;FFF4-FFF5h location
DC.W EI1_int ;FFF6-FFF7h location
DC.W Dummy ;FFF8-FFF9h location
DC.W Dummy ;FFFA-FFFBh location
DC.W Dummy ;FFFC-FFFDh location
DC.W main ;FFFE-FFFFh location
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -