📄 autobaud.s43
字号:
; * autobaud.s43
; *
; * description: This routine will determine the baud rate of the host
; * and set the client baud rate to match, it is run on the
; * client side.
; *
; * The DCO must be setup to operate at 1,048,576 Hz for the
; * follow numbers to be accurate.
; * The first CR will determine if the host is operating in
; * the range 115k<=baud<=14,400 and if so the client baud rate
; * generator registers will be set according to the table below.
; * If the host is not the range 115k<=baud<=14,400 then a second
; * carriage return will be required to determine the host baud range,
; * 9,600<=baud<=1200. If the host baud rate is in this range then
; * the baud rate generator registers are set appropriately according
; * to the table below. If it is NOT in this range, then and error
; * condition is returned.
; *
; * The UBR00/UBR01 register contains the prescale/divider
; * used for generating the correct baud rate, its
; * value is determine by the formula:
; *
; * UBR00/01 = (DCO clk frequency)1,048,576Hz/baud rate
; *
; * Apply this formula to determine the following table:
; *
; * Baud Rate count UBR00 UBR01 Modulation
; * ----------------------------------------------
; * 115,200 9.10 0x09 0x00 0x10
; * 57,600 18.20 0x12 0x00 0x84
; * 38,400 27.31 0x1b 0x00 0x94
; * 19,200 54.61 0x36 0x00 0xb5
; * 14,400 72.82 0x48 0x00 0x7b
; * 9,600 109.23 0x6d 0x00 0x44
; * 4,800 218.45 0xda 0x00 0xaa
; * 2,400 436.91 0xb4 0x01 0xdf
; * 1,200 873.81 0x69 0x03 0x7b
; *
; * The modulation value that goes in the UMCTL0 register is the
; * fractional portion from the above equation. This has been
; * calculated according to the procedure outlined in the
; * MSP430F1xx Family User's Guide.
; *
; **************************************************************************
; *
; * C. Farrow
; * Texas Instruments, Inc
; * September 2004
; * Built with IAR Embedded Workbench Version: 3.20A
; *
; *******************************************************************************/
#include "msp430x12x2.h"
PUBLIC autobaud
RSEG DATA16_C:CONST
stringbaud DC8 "Baud Rate generator set at: "
string1200 DC8 "1200"
string2400 DC8 "2400"
string4800 DC8 "4800"
string9600 DC8 "9600"
string1440 DC8 "14400"
string1920 DC8 "19200"
string3840 DC8 "38400"
string5760 DC8 "57600"
string115k DC8 "115k"
baudregs
DC8 9, 0, 16, 0
DC16 string115k
DC8 18, 0, 132, 0
DC16 string5760
DC8 27, 0, 148, 0
DC16 string3840
DC8 54, 0, 91, 0
DC16 string1920
DC8 72, 0, 123, 0
DC16 string1440
DC8 109, 0, 68, 0
DC16 string9600
DC8 218, 0, 170, 0
DC16 string4800
DC8 180, 1, 223, 0
DC16 string2400
DC8 105, 3, 123, 0
DC16 string1200
RSEG CODE
;-----------------------------------------------------------------------------
; function: int autobaud( void )
; description: Routine that waits for one or two <CR> from PC terminal program
; which is used to determine the baud rate of the host. The UART
; baud registers are then set to match the host baud rate.
;-----------------------------------------------------------------------------
autobaud
PUSH.W R10 ; save R10
still_txing
BIT.B #TXEPT, &UTCTL0
JNC still_txing
BIS.B #SWRST, &UCTL0 ; Place USART in reset
MOV.B #URXEIE, &URCTL0 ; Allow erroneous input to interrupt
BIC.B #SWRST, &UCTL0 ; Take USART out of reset
MOV.W #0x0, R12 ; select 115k Baud Rate
CALL #setbaud ; set 115k baud rate
CALL #getchar ; get character from USART, returned in R12
MOV.B #0xd, R13 ; look for a perfect match CR character
baud_115k CMP.B R12, R13 ; compare character with CR
MOV.B #0h, R10 ; setbaud parameter for 115K baud
JEQ continue ; goto setbaud
baud57600 MOV.B #0xe6, R13
CMP.B R12, R13 ; compare w/ recieved char
MOV.B #1h, R10 ; setbaud parameter for 57600 baud
JEQ continue
baud38400 MOV.B #0x1c, R13
CMP.B R12, R13 ; compare w/ recieved char
MOV.B #2h, R10 ; setbaud parameter for 38400 baud
JEQ continue
baud19200 MOV.B #0xe0, R13
CMP.B R12, R13 ; compare w/ recieved char
MOV.B #3h, R10 ; setbaud parameter for 19200 baud
JEQ continue
baud14400 MOV.B #0x80, R13
CMP.B R12, R13 ; compare w/ recieved char
MOV.B #4h, R10 ; setbaud parameter for 14400 baud
JEQ continue
otherbaud MOV.B #0, R13
CMP.B R12, R13 ; compare w/ recieved char
MOV.W #0xffff, R12 ; return -1
JNE return ; no valid match
CALL #delay_8_33ms ; delay for 8.33ms
MOV.W #0x5, R12 ; setbaud parameter for 9600
CALL #setbaud
CALL #getchar
MOV.B #0xd, R13 ; look for a perfect match CR character
baud_9600 CMP.B R12, R13 ; compare character with CR
MOV.B #5h, R10 ; setbaud parameter for 9600 baud
JEQ continue ; goto setbaud
MOV.B #0xe6, R13 ; look for a perfect match CR character
baud_4800 CMP.B R12, R13 ; compare character with CR
MOV.B #6h, R10 ; setbaud parameter for 4800 baud
JEQ continue ; goto setbaud
MOV.B #0x78, R13 ; look for a perfect match CR character
baud_2400 CMP.B R12, R13 ; compare character with CR
MOV.B #7h, R10 ; setbaud parameter for 2400 baud
JEQ continue ; goto setbaud
MOV.B #0x80, R13 ; look for a perfect match CR character
baud_1200 CMP.B R12, R13 ; compare character with CR
MOV.B #8h, R10 ; setbaud parameter for 1200 baud
JEQ continue ; goto setbaud
MOV.W #0xffff, R12 ; nothing matches so set return value to -1
JMP return
;----------------------------------------------------------------------------
continue ; come here once baud rate determined
;----------------------------------------------------------------------------
CALL #delay_8_33ms ; delay for 8.33 mS to clear slow baud
MOV.B R10, R12 ; R10 contains index into baudrate table
CALL #setbaud ; call setbaud with index
MOV.B R10, R12 ; move baud index into R12
CALL #showbaud ; call showbaud to display
MOV.W #0x0, R12 ; retrun value is 0
return
POP.W R10 ; restore R10
RET ; return
;---------------------------------------------------------------------------
; function: put_message( char *s )
; description: send a line to terminal display
;---------------------------------------------------------------------------
put_message
PUSH.W R10 ; save R10
MOV.W R12, R10 ; move *s into R10
repeat
CMP.B #0x0, 0(R10) ; look for NULL terminator
JEQ done ; if found, all done
MOV.B @R10, R12 ; else put *s in R12
CALL #putchar ; call putchar for display
ADD.W #0x1, R10 ; go to next character
JMP repeat ; repeat
done
POP.W R10 ; get return address
RET ; return
;---------------------------------------------------------------------------
; function: showbaud( int baud )
; description: This routine simply displays the selected baud rate chosen
;---------------------------------------------------------------------------
showbaud
PUSH.W R10 ; save R10
MOV.W R12, R10 ; put baud in R10
MOV.W #stringbaud, R12 ; pointer to string
CALL #put_message ; display string
MOV.W R10, R15 ; get index into baudregs
RLA.W R15 ; multiply index x 2
MOV.W R15, R14 ; save in R14
RLA.W R15 ; multiply index x 2
ADD.W R14, R15 ; add to create 4 word offsets
ADD.W #baudregs, R15 ; baudregs + offset
MOV.W 0x4(R15), R12 ; offset to get baud string
CALL #put_message ; display baud string
POP.W R10 ; restore R10
RET ; return
;---------------------------------------------------------------------------
; function: delay_8_33ms()
; description: delays program execution by 8.33ms @ ACLK=32KHz
;---------------------------------------------------------------------------
delay_8_33ms
MOV.W #273, &TACCR0 ; 273 ticks @ 32Khz = 8.33ms
MOV.W #TASSEL_1+MC_1+TACLR, &TACTL ; Clear and start timer
delay
BIT.W #TAIFG, &TACTL ; Check for TAIFG bit
JNC delay ; if not delay more
MOV.W #0, &TACTL ; reset TACTL
RET ; return
;---------------------------------------------------------------------------
; function: char getchar( void )
; description: None interrupt based UART read
;---------------------------------------------------------------------------
getchar
BIT.B #URXIFG0, &IFG2 ; character ready to read?
JNC getchar ; keep waiting
MOV.B &RXBUF0, R12 ; read char
RET
;---------------------------------------------------------------------------
; function: void setbaud( int baud )
; description: Set the baud rate generator registers
;---------------------------------------------------------------------------
setbaud
BIS.B #SWRST, &UCTL0 ; USART held in reset
AND.B #UTXE0+URXE0, &ME2 ; Disable USART operation
MOV.W R12, R15 ; Calculate offset
RLA.W R15 ; R12 is the table index
MOV.W R15, R14 ; R15 = 6 x R12 + &baudregs
RLA.W R15
ADD.W R14, R15
ADD.W #baudregs, R15
MOV.B @R15+, &UBR00 ; set baudregs.ubr00
MOV.B @R15+, &UBR10 ; set baudregs.ubr10
MOV.B @R15, &UMCTL0 ; set baudregs.umctl0
BIS.B #UTXE0+URXE0, &ME2 ; Re-enable USART operation
BIC.B #SWRST, &UCTL0 ; Release USART
MOV.B &RXBUF0, R14 ; Empty RX buffer and clear flags
RET ; return
;---------------------------------------------------------------------------
; function: void __low_level_put( int c )
; description: Low level put to USART
;---------------------------------------------------------------------------
__low_level_put
BIT.B #UTXIFG0, &IFG2 ; wait for Tx to be ready
JNC __low_level_put ; call to output
MOV.B R12, &TXBUF0 ; send c to USART Tx Reg
RET ; return
;---------------------------------------------------------------------------
; function: int putchar( int c )
; description: send single character to USART
;---------------------------------------------------------------------------
putchar
PUSH.W R10 ; save R10
MOV.W R12, R10 ; grab parameter c
CMP.W #0xa, R10 ; compare to EOL
JNE cont ; if EOL then
MOV.W #0xd, R12 ; convert to CR/LF
CALL #__low_level_put ; call to output
cont
MOV.W R10, R12 ; place c for call
CALL #__low_level_put ; call to output
MOV.W R10, R12 ; place return value in R12
POP.W R10 ; restore R10
RET ; return
end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -