Summary: When trying to build an electronic device based around a microprocessor, it's useful to have the microprocessor itself send back updates as it executes its code so that one can debug any problems with the device. The microprocessor type that I invariably use is an Atmel 8-bit AVR (most often the ATmega168) so this write-up will be focused on getting that system to work. So how do we get these debugging messages from the AVR microprocessor? One way is to use the USART capabilities of the AVR to communicate with a computer via an RS-232 serial connection. Although the RS-232 serial connection represents an older way of doing things, it does work just as well, for our purposes anyway, as more modern methods, and is especially appropriate if you have an old unused computer lying around that could do with a new reason to live!


The Hardware

So how do we add a USART debugger to an AVR microprocessor-based electronics project? Well firstly, you need the hardware which consists of:

Serial Port-to-TTL Converter Module

Serial Port-to-TTL Converter Module

1. Serial Port-to-TTL Converter Module: This module converts the higher voltage serial signals on the computer into the lower voltage AVR signals and vice versa. You could build this module yourself - just solder together a Max232 chip or equivalent (eg. Max3232), its supporting passive components (ie. some capacitors) and the DB-9 connector onto some stripboard or similar - but why go to all that bother when you can just order a professional looking one ready-to-go for a token amount. The modules will have at least one pin marked 'TX'  meaning transmission, and one pin labelled 'RX' meaning reception. These need to be connected to the RX and TX pins, respectively, of the AVR's USART for the two ICs to be able to communicate. In addition, VCC and GND pins will also be present on the converter module and these MUST be connected to the SAME power supply as that which is powering the AVR and its associated electronics.

2. Computer: An old unused PC that has an 'old-style' DB-9 serial port can be given a new lease on life by dedicating it exclusively to AVR debugging duties (and AVR programming too if you are so inclined). I use an old Dell desktop from the early 2000s that can no longer feasibly cope with the high-speed computer world of today and would have been on a trash heap somewhere by now. Instead, it has been stripped of most of its software and is used solely for the purpose of AVR debugging via the USART (and some AVR microprocessor programming too). As it is still using Windows XP, the debugging function runs in the ancient application, Hyperterminal (which comes with older versions of the Windows operating system).  Once again there are other more modern serial debugger applications out there but Hyperterminal caters well enough for our microprocessor debugging needs.

RS-232 cable

RS-232 serial cable

3. RS-232 serial cable: A standard 'old-style' serial cable connects the Serial Port-to-TTL module to the computer. Just one point to note here: make sure the genders of the connections on the cable are compatible with those of both the Serial-to-TTL module and the computer serial port as there are several different connector gender configurations of cable out there.

The Firmware (the code on the AVR)

Once the hardware has been sorted out, the firmware code that is flashed onto the AVR microprocessor needs to be adjusted to activate the AVR’s USART and to have it start sending messages back to Hyperterminal. This can be most easily achieved by first adding two files to the main project folder on the electronics project under development, and secondly by making a few small changes to other existing files within the project.

The extra files that need to be added to the project folder are:

As for project firmware code changes that need to be made, these are as follows:

– in the file ‘main.c’ (or equivalent), change / add the following lines of code (usually found at the beginning of the file):

#define F_CPU 15000000UL // or whatever crystal is being used to provide the clock speed to the AVR (in this line of code, it is set to 15MHz). The value also needs to match the clock speed stated in the Makefile – if you are using Makefiles that is (see instructions below)
#define BAUD 9600 // USART setting – needs to match the Baud Rate set in Hyperterminal
#define DEBUG 1 // This activates the USART code so that it is running as part of the project code on the AVR
#include “uart.h” // This ensures that the USART code is included in the code flashed onto the AVR
#ifdef DEBUG // definitions if DEBUG = 1 (ie. Debugging is active)
#define logs_P(message) uart_puts_P(message)
#define logs(message) uart_puts(message)
#define logc(message) uart_putc(message)
 #define logi(message) uart_puti(message)
#else // no definitions if DEBUG = 0
#define logs_P(message)
#define logs(message)
#define logc(message)
#define logi(message)

– In addition, the following line of code needs to be added to the main() function/loop (of the main.c file) :



Finally, a couple of changes in the MakeFile need to be made also:

F_OSC   = 15000000 // this refers to the clock speed of the AVR and needs to be appropriate for the crystal that is being used in the project (here it is set to 15MHz)
SRC = $(TARGET).c <other source files> uart.c // this line refers to the source files to be used in the ‘make’ process. The USART files are added simply by adding the code ‘uart.c’ to the end of the list of other source files (also you don’t need to add ‘uart.h’ here as this will be included automatically when uart.c is added)

Using the USART debugger:

Once the hardware has been set up and the USART files and set-up code have been added to the project as described above, how do we get the AVR to send log messages to the computer screen? By inserting a line of code calling on any of the functions below where you want the AVR to update you as it is running through its code. When a debug line of code is reached, it will elicit a response on the USART and the appropriate message will be displayed on the computer screen. The key functions for putting something into the USART are :

  • logs_P()for a string located in the AVR’s memory that you want to appear as a log entry
  • logs() –  for a string you want to appear as a log entry
  • logi()for an integer you want to appear as a log entry
  • logc()for a char to appear as a log entry

Some Examples:

If you want a string (stored in the AVR program memory) to be displayed at a particular point in the running of the code, you would use:

logs_P( “\r\nThis is a String\r\n” ); 

If you wanted to know the value of a certain integer variable while the AVR is running, you would insert the following line of code at the point where you want the variable’s current value to be outputted to the computer screen:

logi ( variableName );


USART Debugger Hardware
Serial-to-TTL Module
RS-232 cable
Windows computer with DB-9 serial portDB-9