FreeHC12 Example Guide

Author: Colin D. Bennett <>
Date: 30 May 2008


The purpose of this guide is to provide an overview of the example programs provided with FreeHC12. By going through the example programs, you can learn a lot about how to create your own programs for the HC12.


This program sets the state of the 8 LEDs (on PB7..PB0) based on the positions of the DIP switches (on PH7..PH0). It demonstrates both input using the DIP switches and output to the LEDs.

The 8 LEDs are not directly connected to the DIP switches in hardware, though this program makes it appear that way since the state of the switches is constantly output to the LEDs by the program.


This program uses the timer overflow interrupt to cycle the LEDs on the Dragon12 board. It demonstrates how to use the timer overflow interrupt and install your own interrupt handler.

The main program just has an infinite loop with a WAI (enter wait mode) instruction in it, which puts the 68HC12 MCU to sleep until an interrupt wakes it up. When it does wake up due to an interrupt, the timer overflow interrupt handler


This examples demonstrates the use of the delay_ms() function from hc12/delay.h and controls the row of eight LEDs accessible through port B.


This program displays "1234" on the seven segment LED display. To selectively illuminate the segments of the digits in a way that makes it appear as if they are constantly on, a multiplexing technique is used, where each digit has its own "enable" line, and each of the seven segments (eight if you include the decimal point) has a line that is shared between the 4 digits. By quickly cycling through the four digits using the enable line and setting the seven segments to the right pattern each digit, the multiplexing produces the desired appearance.

For this example, the led7seg driver is not used. This should help more clearly illuminate the basic usage of the 7-segment LED display. A simple delay loop is used for timing in this version of the program.


This is a more complex demo that uses interrupt, the HC12 timer module, and uses pulse width modulation to control the brightness of each digit separately.

In this example, the led7seg driver provides the core functionality. You can view the driver's source code in the FreeHC12 drivers directory under led7seg.c.


The D-Bug12 boot loader provides some functions that user programs can call to do basic operations like printing a formatted string to the serial port 0, which is the port that D-Bug12 controls, and this is the port that you are accessing to upload programs to the target board. These functions are at predefined locations in the HC12 address space. Support for calling them is provided in hc12/dbug12.h, as demonstrated in dbugio/hello_helper.c.

The dbugio example also demonstrates how the provided makefile can be used to easily integrate C and C++ modules into a single HC12 program.


The keypad example demonstrates how to use the keypad driver for the 4x4 matrix keypad on the Dragon12-Plus. It simply displays the key scan code in binary on the row of eight LEDs on port B.


This program demonstrates the use of polled asynchronous serial I/O on the HCS12 CPU using the uart_polled driver. The HCS12 CPU has two SCI (UART) ports, SCI0 and SCI1. We use SCI1 because SCI0 is reserved by DBug12. Connect to the connector P2 (the DB9 connector nearest to the power connector on the Dragon12-Plus board) to use SCI1.

The port baud rate and CPU frequency must be set (via UART_BAUD and F_CPU), which is taken care of by the Makefile, via gcc -D options. We must know the CPU clock frequency because the UART transmitter and receiver run off of the same clock, divided by a certain value, which depends on both the CPU clock rate and the baud rate. The actual calculation is done in the hc12/setbaud.h utility header.


Be sure to disable hardware flow control (RTS/CTS) on your computer when trying to communicate with the HCS12 CPU, since it is unsupported and will cause the serial commincations to fail.


This program is like the uart example except that it uses interrupt driven serial I/O instead of polled I/O. This allows the CPU to enter a low power mode between received bytes, which is more efficient when data is received only intermittently or at a low rate. The program machine code ends up being larger because the interrupt driven I/O is more complex than the polled I/O.


This is one of the most complex examples. It combines usage of the 4x4 matrix keypad (keypad driver), the seven segment LED display (led7seg driver), and the protothreads library.