📄 serial.s
字号:
;***************************************************************************
;*
;* Title: Serial UART Routines
;* Version: 1.0
;* Last updated: 6 Oct 2003
;*
;*
;* DESCRIPTION:
;* This files contains routines for dealing with the UART serial
;* port, ie, the RS232 port that can be used for debug or talking
;* to the LCD display.
;*
;* Note that when the internal UART is enabled the Tx & Rx pins are
;* made output & input regardless of the DDRD register.
;*
;* Hardware Connections:
;* PE1: Output. Transmit data pin.
;* PE0: Input. Receive data pin.
;*
;*
;***************************************************************************
/* Here are the definitions we need, both in included files and defined right here */
#include "frankmp3.h"
#include "frankasm.h"
/* defines for UART 0 - the debug port */
#define BAUDRATE 51 /* UART0: 51 = 19,200 kb/s with a 16 MHz clock */
#define UARTCTL ((1<<TXEN)+(1<<RXEN)+(1<<RXCIE)) /* UART0: Enable transmitter & receiver & receive interrupt */
/* define for uart 1 - the LCD & pushbuttons port */
#define BAUDRATE1 51 /* UART1: 51 = 19,200 kb/s with a 16 MHz clock */
#define UARTCTL1 ((1<<TXEN)+(1<<RXEN)+(1<<RXCIE)) /* UART1: Enable transmitter & receiver & receive interrupt */
/* Make the routines in this file available for use by others */
.global UART_init
.global UART_TxCharWait
.global UART_TxCharWaitC
.global UART_PutHexWait
.global UART_PutHexWaitC
.global UART1_TxCharWaitC
.global Delayms
.text
;**********************************************************************************
;*
;* UART_init
;* Initializes the UART functions.
;*
;* This routine is called once after reset, and performs any initializations
;* specifically required by the UART routines. They are:
;* - set the baud rate
;* - enable the UART
;*
;* Accepts: Nothing
;* Returns: Nothing
;* Uses: flags.
;*
;**********************************************************************************
UART_init:
push temp
; Initialize the UART 0 port, ie the debug port
ldi temp,BAUDRATE
out UBRR,temp ; UART baud rate
ldi temp,UARTCTL
out UCR,temp ; UART control register
; Initialize the UART 1 port, ie the lcd & pushbuttons port
ldi temp,BAUDRATE1
sts U1BRR,temp ; UART baud rate
ldi temp,UARTCTL1
sts U1CR,temp ; UART control register
pop temp
ret
;**********************************************************************************
;*
;* UART_TxCharWaitC
;*
;* C callable version.
;* Transmits a single character out the UART0 (debug port), waiting until the UART is
;* ready to send it out. This should be used for testing ONLY - it is slow.
;*
;* This routine checks if the UART transmit hardware is ready to accept
;* another character. If it is it gives the byte in param1 to the UART, then returns.
;*
;* If the UART transmitter is not ready to accept a new character, this routine
;* waits until it is ready..
;*
;* Accepts: Byte to output in r24
;* Returns: Nothing
;* Uses: flags
;* r24 is left unchanged
;*
;**********************************************************************************
UART_TxCharWaitC:
push param1
push temp
mov param1,r24
rcall UART_TxCharWait
pop temp
pop param1
ret
;**********************************************************************************
;*
;* UART_TxCharWait
;* Transmits a single character out the UART0, waiting until the UART is ready
;* to send it out. This should be used for testing ONLY - it is slow.
;*
;* This routine checks if the UART transmit hardware is ready to accept
;* another character. If it is it gives the byte in param1 to the UART, then returns.
;*
;* If the UART transmitter is not ready to accept a new character, this routine
;* waits until it is ready..
;*
;* Accepts: Byte to output in param1
;* Returns: Nothing
;* Uses: param1, temp, flags
;* param1 is left unchanged
;*
;**********************************************************************************
UART_TxCharWait:
in temp,USR
sbrs temp,UDRE
rjmp UART_TxCharWait ; loop until UART ready for new data
; execute here if uart ready to accept a new byte
out UDR,param1 ; write byte from param1 to UART
ret
;**********************************************************************************
;*
;* UART1_TxCharWaitC
;*
;* C callable version.
;* Transmits a single character out UART1, waiting until the UART is ready
;* to send it out. This should be used for testing & init ONLY - it is slow.
;*
;* This routine checks if the UART1 transmit hardware is ready to accept
;* another character. If it is it gives the byte in param1 to UART1, then returns.
;*
;* If the UART transmitter is not ready to accept a new character, this routine
;* waits until it is ready..
;*
;* Accepts: Byte to output in r24
;* Returns: Nothing
;* Uses: flags
;* r24 is left unchanged
;*
;**********************************************************************************
UART1_TxCharWaitC:
push temp
UART1TXCWC:
lds temp,U1SR
sbrs temp,UDRE
rjmp UART1TXCWC ; loop until UART1 ready for new data
; execute here if uart ready to accept a new byte
sts U1DR,r24 ; write byte from param1 to UART
pop temp
ret
;**********************************************************************************
;*
;* UART_PutHexWaitC
;*
;* Identical to UART_PutHexWait below, but a C callable version.
;*
;**********************************************************************************
UART_PutHexWaitC:
push param1
push temp
push temp2
mov param1,r24
rcall UART_PutHexWait
pop temp2
pop temp
pop param1
ret
;**********************************************************************************
;*
;* UART_PutHexWait
;*
;* This routine converts the byte passed in param1 into its two hexadecimal
;* ASCII characters and sends them out the UART. The bulk of this routine is in
;* the hex-to-hex-ASCII conversion process.
;*
;* This routine uses UART_TxCharWait to send the two characters to the UART,
;* bypassing the UART queue and hence being slow. Use this routine for
;* debugging applications only.
;*
;* This routine converts the Hexadecimal quantity stored in param1 into ASCII
;* hex digits ready for display & sends them out the UART. The ASCII numbers
;* of digits 0-9 are hex 0x30 for zero to 0x39 for 9. The letter A has the ASCII
;* code of $41. The program functions as follows:
;*
;* Make a copy of param1
;* Move param1 high nibble to the low nibble; zero the high nibble
;* Add the ASCII code for 0
;* If result greater than ASCII code for 9, add 7
;* Put the result in the UART transmit queue
;* Take the original copy of param1; zero the high nibble
;* Add the ASCII code for 0
;* If result greater than ASCII code for 9, add 7
;* Put the result in the UART transmit queue
;* return
;*
;*
;* Accepts: Byte to be output in param1
;* Returns: Nothing
;* Uses: param1, temp, flags
;*
;**********************************************************************************
UART_PutHexWait:
push temp2
mov temp2,param1 ; make a copy of param1
; deal with the high nibble first
swap param1
andi param1,0x0f ; high nibble now low, high nibble clear
ldi temp,'0'
add param1,temp ; add ASCII code for zero
cpi param1,58 ; is result greater than ASCII code for 9?
brmi UARTPHW1 ; branch if no - number is 0-9
ldi temp,7
add param1,temp ; else add 7, to make ASCII A thru F
UARTPHW1:
rcall UART_TxCharWait ; send the high nibble to the UART
; now do the low nibble, identically to what we just did for the high nibble
mov param1,temp2 ; get the copy of the original byte
andi param1,0x0f ; high nibble clear
ldi temp,'0'
add param1,temp ; add ASCII code for zero
cpi param1,58 ; is result greater than ASCII code for 9?
brmi UARTPHW2 ; branch if no - number is 0-9
ldi temp,7
add param1,temp ; else add 7, to make ASCII A thru F
UARTPHW2:
rcall UART_TxCharWait ; send the low nibble to the UART
pop temp2
ret
;**********************************************************************************
;*
;* Delayms
;*
;* void Delayms (u08 ms)
;*
;* Performs a programmable delay of 0 to 255 ms. Does this by having an inner
;* loop of 16,000 cycles which is 10 ms at a 16 MHz clock. This is then iterated
;* by an outer loop. (16,000 = 160 * 25 * 4) ie 160 iterations of 25 iterations
;* of 4 cycles.
;*
;* Accepts: number of ms to delay in r24
;* Returns: Nothing
;* Uses: flags.
;*
;**********************************************************************************
Delayms:
tst r24
breq Delayms9 ; exit if asked for a zero ms delay
push temp
push temp2
push r24
Delayms1: ; this is top of the outer loop
ldi temp,160 ; top of inner loops: 160 * 25 * 4
Delayms2:
ldi temp2,25
Delayms3:
nop
dec temp2
brne Delayms3 ; inner core of 4 cycles, repeated 25 times
dec temp
brne Delayms2 ; loop until we've done this 160 times
dec r24
brne Delayms1 ; repeat outer loop until r24 (ms count) finished (ie zero)
pop r24
pop temp2
pop temp
Delayms9:
ret
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -