Serial I/O Routines Using the 8051's Built-In UART
This 8051 code library is intended to provide a variety of
commonly used I/O functions found in high-level languages
to 8051 assembly language programs. All I/O is assumed to
be though the 8051's built-in UART, connected to a terminal
or terminal emulation program running on a PC or workstation.
All of the routines within this library make calls to
These two simple routines are responsible for all the I/O
performed by this library; none of the other routines
directly access the 8051's built-in UART.
These may be replaced with
Interrupt Driven Serial I/O Routines
or custom routines if a different type of I/O device is to be
This library is available in plain text
or in a ZIP file. I hope you find
it useful. --Paul
Using the Serial I/O Routines
This information is believed to be correct, but errors or
oversights are possible. In particular, these routines may
overwrite registers, though an attempt has been made to
indicate which routines will overwrite which registers.
When it doubt, just peek at the source code.
- Basic character input. Simply waits for a byte and
returns it in Acc.
- Basic character output. Waits for the UART's transmitter
to be available and then sends the character in Acc.
- Sends a CR/LF sequence. While this seems simple, the
required code is 8 bytes whereas an ACALL is 2 bytes, so
this routine can save quite a bit of code memory. Acc
is not altered as well.
- Gets a two-digit hexidecimal input, which is returned in
Acc. If <ESC> is pressed, Carry is set, Carry is clear otherwise.
If return is pressed with no input, PSW.5 is set, PSW.5 is
clear otherwise. R2 and R3 are altered.
- Gets a four-digit hexidecimal input, which is returned in
DPTR. If <ESC> is pressed, Carry is set, Carry is clear otherwise.
If return is pressed with no input, PSW.5 is set, PSW.5 is
clear otherwise. R2, R3, R4 and Acc are altered.
- Converts an ascii value ('0' to '9', 'A' to 'F') into a
number (0 to 15). Carry is set if Acc contained an invalid
character. Lowercase letters ('a' to 'f') are considered
invalid, so a call to UPPER should be
made if the character might be lowercase.
- Prints the value in Acc as a two-digit hexidecimal number.
Acc is not changed. This routine tends to be very useful for
troubleshooting by simply inserting calls to PHEX within
troublesome code. Note: The version of PHEX which originally
appeared in PAULMON1 destroys the value of Acc!
- Prints the value of DPTR as a four-digit hexidecimal number.
- Prints a string located within code memory. DPTR must be
loaded with the beginning address of the string before calling
PSTR. Strings may be larger than 256 bytes.
The string may be terminated with a 0 (which would not
be transmitted). The string may also be terminated by setting
the most significant bit of the last character. In this latter
case, the last character is transmitted with it's most sig bit
cleared. For example:
do_msg: mov dptr, #mesg1
mov dptr, #mesg2
mesg1: .db "This is a test messag", 'e'+128
mesg2: .db "testing: 1.. 2.. 3..", 0
- A simple chunk of initialization code for the 8051's
built-in UART. The constant "baud_const" must defined
according to this simple formula:
baud_const = 256 - (crystal / (192 * baud))
cyrstal is the 8051's cyrstal osc. frequency (in Hz) and
baud is the desired baud rate (in bits per second).
- Prints the value in Acc as an unsigned (base 10) integer (0 to 255).
Leading zeros are supressed. Acc is not changed, but Carry and
PSW.5 (f0) are changed.
- Prints the value in Acc as a signed (base 10) integer (-128 to 127).
Leading zeros are supressed and the '-' is printed if necessary.
Twos complement format is assumed: 0xFF = "-128",
0x7F = "127".
- Prints the 16 bit value in DPTR as an unsigned (base 10)
integer (0 to 65535). R2, R3, R4, R5 and PSW.5 are altered. This
code uses a (very compact) successive-subtract divide routine
to get around limitations with the 8051's DIV instruction when
generating the first three digits. For polled I/O (such as the
CIN/COUT routines provided here) this shouldn't be a problem,
but for a timing critical interrupt driven I/O system the CPU time
required for this routine may need to be considered carefully.
- Changes the value of Acc to uppercase if Acc contains a
lowercase letter. If Acc contains an uppercase letter, digit,
symbol or other non-ascii byte, the value of Acc is not altered.
- Prints the value of Acc as an eight digit binary number.
- Returns the length of a string in code memory. The length
is returned in R0. DPTR must point to be beginning of the
string, as with PSTR. Strings may be
longer than 256 bytes, but only the eight least significant
bits will be returned in R0.
- Gets a string of input. The input is finished when
a carriage return (ascii code 13) is received. The carriage
return is not stored in the string and the string is
terminated with a zero. Non-printing characters are not
accepted, but backspace (ascii code 8) and delete (ascii code
127) are handled. R0 and Acc are altered. The string is
stored in a buffer within internal ram, begining at
str_buf. The value of max_str_len determines
the maximum size string that can be entered. A total of
max_str_len+1 bytes must be reserved in internal ram
for the buffer, to allow for the null termination. Care
must be taken to prevent the string's buffer from overwriting
registers, program variables, or the stack by selecting
values for str_buf and max_str_len which will
not conflict with other internal RAM usage. All access to
the buffer uses indirect addressing, so the upper 128 byte bank
memory in the 80x52 may be used without affecting the special
- Prints the string within the internal ram buffer used by
GETSTR. In contrast with PSTR,
no specification for the buffer's location is required (the value
defined by str_buf is used). Acc and R0 are altered.
- Gets an unsigned integer input, which is returned in Acc.
The input is terminated when
a carriage return (ascii code 13) is received.
Non-numeric characters are not
accepted and input which would exceed the allowed range (0 to 255)
is also not accepted. Backspace (ascii code 8) and delete (ascii code
127) are handled. R0, R1, R2 and B are altered. No internal
RAM buffer is required as with GETSTR.
- Returns with Carry set if Acc contains an printable ascii
character (32 to 126) or Carry clear otherwise.