The eZ8 can have up to two UART's built in. It can be used to send midi notes to a keyboard or text to a terminal program running on your computer.
To set up serial you need to specify the baudrate and set the pinmodes for the serial pins.
Calculating the frequency for the baudrate generator.
;Change this to the crystal frequency you are using. SYSFREQ EQU 2000000 ; UART baudrate selection UART_BAUD EQU 115200 UART_BRG EQU ((SYSFREQ + (UART_BAUD * 8)) / (UART_BAUD * 16))
Macro to turn on uart interrupts
EI_U: MACRO
orx IRQ0ENH, #%10
orx IRQ0ENL, #%10
ENDMAC
If you want to be able to receive data via serial as well add this line:
VECTOR UART0_RX = isr_uart_rx
...and next: set up the pinmodes and interrupts.
init_uart:
ldx PAADDR,#DDR ;Set RX to input
orx PACTL,#(16)
andx PACTL,#~(32) ;Set TX to output
ldx PAADDR,#AF
orx PACTL,#((16)|(32))
ldx U_BRH, #HIGH(UART_BRG)
ldx U_BRL, #LOW(UART_BRG)
ldx U_CTL1, #%00 ; clear for normal non-Multiprocessor operation
ldx U_CTL0, #%C0 ; Transmit enable, Receive Enable, No Parity, 1 Stop
EI_U
ret
To send a byte simply do this:
ldx U_D, #42 ; Write 42 to serial data register.
If you want to make sure it works every time make sure to wait for the uart to finish sending the last byte. You can do this by checking the uart status register. In a routine it looks like this:
putc:
push R1
$$:
ldx R1, U_STAT0 ;Loop until serial is ready.
and R1, #%04
jr Z, $B
ldx U_D, R0 ; Write R0 to serial data register. It gets sent automatically!
pop R1
ret
Using interrupts for receiving bytes is really helpful. You don't have to worry about continuously polling for data. Just have an interrupt service routine for it. Make sure your interrupts are globally enabled using the EI instruction. Also make sure you set the isr vector. VECTOR UART0_RX = isr_uart_rx
isr_uart_rx: ldx R0,U0RXD ;Load data from uart rx data register in R0 ;put your code here iret
This is simpleserial.inc revision 1.
; simpleserial.inc
; by Koen van Vliet
; CC0 - Public Domain
; blog:
; http://8times8.host56.com
; programmers reference:
; http://ez8tut.sourceforge.com
VECTOR UART0_RX = isr_uart_rx
;Change this to the crystal frequency you are using.
SYSFREQ EQU 2000000
;------------------------------------------------------------------------------
; UART baudrate selection
UART_BAUD EQU 115200
UART_BRG EQU ((SYSFREQ + (UART_BAUD * 8)) / (UART_BAUD * 16))
; UART control, status and data register mnemonics
U_BRH EQU U0BRH
U_BRL EQU U0BRL
U_CTL0 EQU U0CTL0
U_CTL1 EQU U0CTL1
U_STAT0 EQU U0STAT0
U_D EQU U0D
EI_U: MACRO
orx IRQ0ENH, #%10
orx IRQ0ENL, #%10
ENDMAC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Output a character to UART
; R0: holds the character to send
putc:
push R1
$$:
ldx R1, U_STAT0
and R1, #%04
jr Z, $B
ldx U_D, R0
pop R1
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Output a string to UART
; RR0: holds the address of the string
puts:
push R2
push R3
ld R2, R0
ld R3, R1
$$:
ldc R0, @RR2
cp R0, #0
jr Z, $F
call putc
incw RR2
jr $B
$$:
pop R3
pop R2
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Output a string to UART from register file instead of flash
; RR0: holds the address of the string
puts_r:
push R2
push R3
ld R2, R0
ld R3, R1
$$:
ldx R0, @RR2
cp R0, #0
jr Z, $F
call putc
incw RR2
jr $B
$$:
pop R3
pop R2
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Output data from Flash of SIZE bytes long
; RR0: holds the address of the data
; R4: The size
putFd:
push R2
push R3
ld R2,R0
ld R3,R1
$$:
ldc R0, @RR2
call putc
incw RR2
djnz R4,$B
pop R3
pop R2
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Intialize UART
init_uart:
ldx U_BRH, #HIGH(UART_BRG)
ldx U_BRL, #LOW(UART_BRG)
ldx U_CTL1, #%00 ; clear for normal non-Multiprocessor operation
ldx U_CTL0, #%C0 ; Transmit enable, Receive Enable, No Parity, 1 Stop
EI_U
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Output an integer to UART formatted as a string
; RR0: holds the integer
puti:
cp R1,#0
cpc R0,#0
jr nz,$F
ld R0,#30h
call putc
ret
$$:
ld R5,#00h
ld R2,#high(-10000)
ld R3, #low(-10000)
call Num1
ld R2,#high(-1000)
ld R3, #low(-1000)
call Num1
ld R2,#high(-100)
ld R3, #low(-100)
call Num1
ld R2,#high(-10)
ld R3, #low(-10)
call Num1
ld R3,R2
Num1:
ld R4,#('0'-1)
Num2:
inc R4
add R1,R3
adc R0,R2
jr c,Num2
sub R1,R3
sbc R0,R2
cp R5,1
jr z,Num3
cp R4,#('0')
jr z,Num4
Num3:
ld R5,1
push R0
ld R0,R4
call putc
pop R0
Num4:
ret
SCOPE
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Interrupt Service Routine for UART
isr_uart_rx:
ldx R0,U0RXD ;Load data from uart rx data register in R0
;put your code here
iret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;; Routine: puth
;;;;; Print byte as hexadecimal
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
puth:
push R0
;Upper nibble
srl R0 ;>>4
srl R0
srl R0
srl R0
add R0,#30h
cp R0,#(30h + 9) ;0-9
jr ule,$F
add R0,#(10h - 9);A-F
$$:
call putc
pop R0
;Lower nibble
and R0,#0Fh
add R0,#30h
cp R0,#(30h + 9) ;0-9
jr ule,$F
add R0,#(10h - 9);A-F
$$:
call putc
ret
Please submit corrections, suggestions, and new documentation here: Submit a ticket
← Return to Reference Index
This is not an official Zilog website. Zilog nor 8times8 are liable for any damage done to equipment. Tutorial and reference copyright ©8times8 Creative Commons CC-0 License (public domain.) This reference uses content from Zilog's technical datasheets. Fair use only. Datasheets copyright © 2013 Zilog®, Inc. Z8, Z8 Encore!, Z8 Encore! XP and Z8 Encore! MC are trademarks or registered trademarks of Zilog, Inc. Read Zilog's terms at zilog.com
Website design by Koen van Vliet. Hosted by sourceforge.net