Paul's 8051 Code Library Free 8051 Code ---------------------------------------------------------------------------- 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 through 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. If interrupt driven I/O is required or a different I/O device is to be used, CIN and COUT could be replaced with the equivalent interrupt driven routines or code to access special hardware. 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.ece.orst.edu/~paul/8051-goodies/serial_io.html Last updated: 3 Jan 1996 Status: finished (but more routines my be added in the future) Suggestions, comments, criticisms: ----------------------------------------------------------------------------