skip navigational linksPJRC
Shopping Cart Download Website
Home Products Teensy Blog Forum
You are here: 8051 Tools Code Library Serial I/O, Polled

PJRC Store
8051 Board, $79
LCD 128x64 Pixel, $29
LCD 16x2 Char, $14
Serial Cable, $5
9 Volt Power, $6
More Components...
8051 Tools
Main Page
Software
PAULMON Monitor
Development Board
Code Library
89C2051 Programmer
Other Resources

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 CIN and COUT. 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 used.

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.

cin
Basic character input. Simply waits for a byte and returns it in Acc.
cout
Basic character output. Waits for the UART's transmitter to be available and then sends the character in Acc.
newline
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.
ghex
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.
ghex16
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.
asc2hex
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.
phex
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!
phex16
Prints the value of DPTR as a four-digit hexidecimal number.
pstr
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
              lcall   pstr
              lcall   newline
              mov     dptr, #mesg2
              lcall   pstr
              ret
      mesg1:  .db     "This is a test messag", 'e'+128
      mesg2:  .db     "testing:  1.. 2.. 3..", 0
poweron
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))
where cyrstal is the 8051's cyrstal osc. frequency (in Hz) and baud is the desired baud rate (in bits per second).
pint8u
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.
pint8
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".
pint16u
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.
upper
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.
pbin
Prints the value of Acc as an eight digit binary number.
lenstr
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.
getstr
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 function registers.
pstrbuf
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.
gint8u
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.
isascii
Returns with Carry set if Acc contains an printable ascii character (32 to 126) or Carry clear otherwise.


Paul's 8051 Code Library, Paul Stoffregen
http://www.pjrc.com/tech/8051/serial_io.html
Last updated: February 24, 2005
Status: finished (but more routines my be added in the future)
Suggestions, comments, criticisms: <paul@pjrc.com>