📄 serial.a51
字号:
;*A**************************************************************************
; NAME: serial.a51
;----------------------------------------------------------------------------
; REVISION: $version: $
;----------------------------------------------------------------------------
; PURPOSE: This file contains the serial routines
;
;----------------------------------------------------------------------------
; NOTES:
;
;****************************************************************************
; CHANGES:
; CC03 introduces binary transfer mode send_hex_byte changed to send_data_byte
;
;****************************************************************************
$TITLE (*** Serial Routines ***)
SERIAL_MODULE SEGMENT CODE
;_____ I N C L U D E S ____________________________________________________
$include (config.inc)
$include (register.inc)
;_____ M A C R O S ________________________________________________________
CR_CHAR EQU 0Dh
LF_CHAR EQU 0Ah
;_____ D E F I N I T I O N ________________________________________________
;_____ D E C L A R A T I O N ______________________________________________
PUBLIC send_char, send_cr_lf, send_point
PUBLIC send_data_byte
PUBLIC get_char, get_byte, get_byte_binary
PUBLIC autobaud
RSEG SERIAL_MODULE
;*F***************************************************************************
; NAME: send_char
;-----------------------------------------------------------------------------
; PARAMS: ACC: character to send
;
; RETURN:
;
;-----------------------------------------------------------------------------
; PURPOSE: send one character on the serial link
;
;*****************************************************************************
send_char:
jnb TI,send_char ; wait Tx is ready
clr TI
mov SBUF,A ; send character
ret
;*F***************************************************************************
; NAME: send_cr_lf
;-----------------------------------------------------------------------------
; PARAMS:
;
; RETURN:
;
;-----------------------------------------------------------------------------
; PURPOSE: send a CR character followed by a LF character on the serial link
;
;*****************************************************************************
send_cr_lf:
mov A,#CR_CHAR ; transmit 0Dh
acall send_char
mov A,#LF_CHAR ; transmit 0Ah
acall send_char
ret
;*F***************************************************************************
; NAME: send_point
;-----------------------------------------------------------------------------
; PARAMS:
;
; RETURN:
;
;-----------------------------------------------------------------------------
; PURPOSE: send a '.' character followed by CR/LF on the serial link
;
;*****************************************************************************
send_point:
mov A,#'.'
acall send_char
acall send_cr_lf
ret
;*F***************************************************************************
; NAME: send_data_byte
;-----------------------------------------------------------------------------
; PARAMS: R7: character to send (&convert) store and send
;
; RETURN:
;
;-----------------------------------------------------------------------------
; PURPOSE: Send one data byte over the serial line
;
;*****************************************************************************
send_data_byte:
mov A,R7
send_data_byte_ascii:
swap A
acall hex_to_asc ; convert MSN
acall send_char ; send MSN
mov A,R7
acall hex_to_asc ; convert LSN
acall send_char ; send LSN
ret
;*F***************************************************************************
; NAME: get_char
;-----------------------------------------------------------------------------
; PARAMS:
;
; RETURN: ACC: character received
;
;-----------------------------------------------------------------------------
; PURPOSE: wait one character is received on the serial link
; echo this character on the line
;
;*****************************************************************************
get_char:
jnb RI,get_char ; wait Rx is ready
clr RI
mov A,SBUF ; read received data
acall send_char ; echo
ret
;*F***************************************************************************
; NAME: get_byte_binary
;-----------------------------------------------------------------------------
; PARAMS:
;
; RETURN: ACC: byte in binary format
;
;-----------------------------------------------------------------------------
; PURPOSE: wait an a byte (1 character) from the serial link
;
;-----------------------------------------------------------------------------
; NOTE:
;
;*****************************************************************************
get_byte_binary:
jnb RI,get_char ; wait Rx is ready
clr RI
mov A,SBUF ; read received data
; acall send_char ; echo -> In New Binary mode : No Echo
ret
;*F***************************************************************************
; NAME: get_byte
;-----------------------------------------------------------------------------
; PARAMS:
;
; RETURN: ACC: byte in binary format
;
;-----------------------------------------------------------------------------
; PURPOSE: wait an hexadecimal ascii byte (2 characters) from the serial link
;
;-----------------------------------------------------------------------------
; NOTE: R6 modified by the routine without saving it
;
;*****************************************************************************
get_byte:
acall get_char ; wait ascii MSB
acall asc_to_hex
swap A
mov R6,A
acall get_char ; wait ascii LSB
acall asc_to_hex
orl A,R6 ; build byte
ret
hex_to_asc:
anl A,#0Fh ; keep nibble
add A,#90H
da A
addc A,#40H
da A
ret
asc_to_hex:
clr C
subb A,#'0'
cjne A,#0Ah,asc_to_hex_1
asc_to_hex_1:
jc asc_to_hex_3
add A,#-7
cjne A,#10h,asc_to_hex_2
asc_to_hex_2:
jc asc_to_hex_3
mov A,#00h ; bad ASCII, return 00h
asc_to_hex_3:
ret
;*F***************************************************************************
; NAME: autobaud
;-----------------------------------------------------------------------------
; PARAMS:
;
; RETURN:
;
;-----------------------------------------------------------------------------
; PURPOSE: check speed reception of a 'U' char and program the baud
; generator according to it
;
;*****************************************************************************
$if BRG_IBG
autobaud: ; autobaud with internal baud rate generator
anl TCON,#0Fh
mov TMOD,#10h ; timer 1 in 16 bits mode
jb P3.0,$ ; wait for start bit
jnb P3.0,$ ; wait for data bit 0 'H'
setb TR1 ; start timer
mov R0,#02h
auto_bit:
jb P3.0,$ ; wait for data bit 1/3 'L'
jnb P3.0,$ ; wait for data bit 2/4 'H'
djnz R0,auto_bit
jb P3.0,$ ; wait for data bit 5 'L'
jnb P3.0,$ ; wait for data bit 6 'H'
clr TR1 ; stop timer
jb P3.0,$ ; wait for data bit 7 'L'
jnb P3.0,$ ; wait for stop bit 'H'
; BRL = ~(T1 / 16) + 1
; T1 / 16 : 2 shift left and keep MSB
mov A,TH1
anl A,#00Fh
mov R0,A
mov A,TL1
mov A,TL1
jnb ACC.3,auto_correct ; take care of round
add A,#010h
auto_correct:
anl A,#0F0h
orl A,R0
swap A ; ACC = T1 / 16
; ~() + 1
cpl A
inc A
mov BRL,A ; set the reload register
mov SCON,#052h ; TI= 1, RI= 0, uart mode 1
orl PCON,#080h ; SMOD1= 1
mov BDRCON,#01Fh ; SPD= 1, BRR = 1
ret
$endif ; BRG_IBG
$if BRG_T2
autobaud: ; autobaud with timer 2
mov T2CON,#00h
mov TL2, #00h ; RLe Autobaud improvement first reset cpt
mov TH2, #00h
jnb P3.0,$ ; Check for '1' on RxD line: bug 0007 modification
jb P3.0,$ ; wait for start bit
setb TR2 ; start timer
jnb P3.0,$ ; wait for data bit 0 'H'
jb TF2, autobaud ; RLe: Timeout : Buggly UART Laptop
jb P3.0,$ ; wait for data bit 1 'L'
jnb P3.0,$ ; wait for data bit 2 'H'
jb P3.0,$ ; wait for data bit 3 'L'
jnb P3.0,$ ; wait for data bit 4 'H'
jb P3.0,$ ; wait for data bit 5 'L'
jnb P3.0,$ ; wait for data bit 6 'H'
jb P3.0,$ ; wait for data bit 7 'L'
clr TR2 ; stop timer
jnb P3.0,$ ; wait for stop bit 'H'
mov R0, #7 ; RLe Modif: measure correction
dec_measure:
dec TL2 ; remove one cycle of measurement
mov A,TL2
cjne A,#0FFh,next_dec
dec TH2 ; remove 1 to TH2 if initially TL2 was equal 00h (TH2,TL2:0200h--> 01FFh)
next_dec:
djnz R0, dec_measure
TH2_00:
mov A,TH2
mov R6,A
mov A,TL2
clr C ; first multiply by 2
rlc A
xch A,R6
rlc A
xch A,R6
add A,TL2 ; and then add the original value
xch A,R6
addc A,TH2
;
; a,r6 = (a,r6)/64
;
mov R0,#6
div64:
clr C
rrc A
xch A,R6
rrc A
xch A,R6
djnz R0,div64
cpl A
mov RCAP2H,A
mov A,R6
cpl A
mov RCAP2L,A
mov SCON,#052h ; serial port in 8 bits UART
mov T2CON,#034h ; Timer2 in Baud rate Generator mode
setb TR2 ; start Timer2
ret
$endif ; BRG_T2
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -