UART Serial Terminal Output Test



After sufficiently testing our EEPROM chips and with the knowledge that we are communicating with them properly we can start to build programs to test other devices added to our system. One of the more useful devices to add is a UART, and that is just what we will do.

UART stands for Universal Asynchronous Receiver/Transmitter. In our case it is just a transmitter that will take the parallel data on our data bus, and send it out bit-by-bit “serially” to somewhere else. The somewhere else is another computer with a serial port that will assemble this data and do something useful to it like display it on a monitor.

I have struggled with assembling this circuit for so long because of many different factors,

  1. I am stubborn with my wiring, always thinking it is correct, when more than often it is not correct.
  2. The initialization of the UART (16550) is not discussed clearly in the data sheet.
  3. The USB-> TTL module I purchased on the cheap from China is garbage. Well maybe.
  4. I tried re-cycling code I found on the internet as if it would magically work.
  5. I overthought my initial test code, and I am awful at programming in assembly.

My test code is as follows,

Screen Shot 2014-08-20 at 10.18.09 PM

INIT_UART initializes the UART. To do so we need to write to some of the UART’s registers. A0, A1, and A2 are used to address these registers along with the control signals /IOREQ, /WR, and /RD. The data bus is also attached to the UART to send the data we will write into these registers, and later to send data through the UART. The registers we are concerned with are the Divisor Latch Registers (DLAB: High Register: 00H & 01H), the Line Control Register (Register: 03H), the Line Status Register (Register: 05H), and the Transmitter Holding Register (DLAB: Low /WR: Low Register: 00H).

The Divisor Latch Register can be programmed by first setting bit 8of the Line Control Register high. This makes address 00H the LSB of the divisor and 01H the MSB of the divisor. What is the divisor to program? The divisor can be calculated by using the formula,

Screen Shot 2014-08-20 at 10.18.18 PM

Typical baud rates are 9600 and 19200. Baud rate is how many bits per second you can send. Therefore it follows that with 8-bit data and one added start and stop bit, you have 18 bits for every “word”/character which is two bytes. So with a 9600 baud rate you could potentially send around 533 characters a second if there was no overhead from the microprocessor (about a page worth of characters). Typical UART frequencies can be found in the 16550 data sheet, I used 1.8432 MHz since I had this oscillator already in a half-can package. If we re –arrange the formula for the divisor and plug in our known values we get,

Screen Shot 2014-08-20 at 10.18.29 PMTo program 12, we can either explicitly tell the assembler we want to put the decimal number 12 in, or program the Hex value ‘0C’. Remember the divisor latch register’s LSB is programmed at 00H and the divisor latch register’s MSB is programmed at 01. If your divisor was say 1000 then your HEX value would be 03E8H and E8H would go to the divisor latch register’s LSB 00H and 03H would go to your divisor latch register’s MSB 01H.

Next we program the line control register by sending the data 03H to its address 03H. According to the 16550’s data sheet this tells the UART to expect 8 bit data size and add one stop bit as well as the start bit for each word that will be sent. Along with this definition, 03H also resets DLAB to that we can start to transmit data when we send bytes to the Transmitter Holding Register.

Before we send the data however we need to check the Line Status Register’s bit 5 to make sure that when our loop does execute that we aren’t already sending a character when we try to send another. To do this the BIT command is used, which sets the Zero Flag to the opposite of the value on the bit being tested. For us this is the Transmitter Holding Register Empty bit, and when this bit is enabled the UART is ready to transmit again.

To send we ‘out’ a ‘word’ to the Transmitter Holding Register at 00H, since DLAB is low this should work. As we loop back our main program we again test the Transmitter Holding Register Empty bit in the Line Status Register before sending another word.

To capture the data my UART was sending I use a USB to RS-232 adapter, and used PUTTY to listen to the adapter at 9600 baud. To obtain the RS-232 requirements I used a MAX237 level shifter. You see, our circuit works at 5V which is sometimes called TTL level while RS-232 works around 12V levels. The level shifter takes care of bumping up the voltage to the correct level. The adapter has a DB9 serial connector, and since we are only transmitting, we hook up our transmit line to the receive line on the adapter’s DB9 connector (PIN 2) and our circuits ground connection to the adapter’s DB9 connector (PIN 5).

If all goes well you should see a steady stream of ‘A’ characters flooding your screen. After so much time trying to get this to work I was ecstatic to see all of the ‘A’s. Now our computer has a flexible and useful form of output that we can use for debugging, and we no longer have to rely on those LEDs, which at the MHz frequency are useless because of flicker threshold.

Below is the realized schematic for the Z80 UART Test Circuit. Remember how I mentioned that the USB-> TTL module I purchased on the cheap from China is garbage. Well I am just mad at it because the Tx and Rx lines are 3.3V TTL logic levels instead of 5V TTL logic levels. It is called a D-SUN USB->TTL adapter. When I initially ran my test I was using this and getting garbage on my serial terminal. This can probably be solved with a 5V to 3.3V level shifter, but I had the other adapter around and the MAX237 chip. You could get away with using one of the USB->TTL serial adapters, and negate the MAX237 altogether from the circuit. This would simplify the parts list a bit and the wiring since you could take the Tx line right from the UART and connect it to your adapter. Just make sure that your adapter is for 5V TTL levels and not 3.3V!

UARTTEST Schematic

All Files from this project can be downloaded from my GitHub Repository,

Z80 Project Repository

This slideshow requires JavaScript.

About Matt Cook

Computer Engineer
This entry was posted in Uncategorized and tagged , , , , , , , , . Bookmark the permalink.

2 Responses to UART Serial Terminal Output Test

  1. ciernioo says:

    Hi, I was wondering – if you have a functional UART allready, and you are looking for a display solution, why not use some uart-to-vga adapter projects ? One of more inspirational for me was the work of this guy:

    • Matt Cook says:


      It is funny. I spent the last weekend replicating that exact project with an ATMEGA644. I got the display to work with a lot of flickering, and it was not quite where it was supposed to be on the screen, which may have to do with porting the code to the 644, but I am not sure. Either way that project has one downfall I can see from the code, and that it only has a very small window to actually accept data from the UART. The ATMEGA644 would stop outputting the VGA signal as soon as it had to handle my UART stream. I found that if you just shortly attached the UART signal (for about a second) and detached it that the display would go away, and come back re-drawn with some extra characters.
      To avoid spending weeks on a buggy display that I can’t seem to figure out, and not have an update I have instead decided to purchase a UART to VGA solution from HobbyTronics in the UK. It may take a few weeks to get, but from what it looks like it will be a good platform to keep my design going. Now that the output is “sorted” I am going to be looking into input from a PS/2 keyboard since I found a nice compact one at a second-hand store on the cheap. If I can get this to work I will have a simple terminal to build off of, and I can start adding RAM and doing some useful work.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s