CodeWarrior - 68HC12B - Hello Project

The goal of this part of the tutorial is to introduce you to Metrowerks Code Warrior in a way well enough so that you can practice 'C' programming.  Much of the complexity in using Code Warrior is eased by the use of stationary, which is a premade project template.  While this part does use the standard I/O library, be aware that many embedded systems programmers choose not to use it.

Our New Stationary

Building and executing the traditional hello world program in a small embedded system is a more profound experience in that there is no operating system and there is no standard output stream.  In the College of Engineering, Technology, and Architecture (CETA) at the University of Hartford we have 68HC12B32 development boards from Axiom Manufacturing.  The part number is CME12BC32.  The details of how to install stationery is in the install notes

A New Project From Stationary

With the stationary folder in place, start Metrowerks Code Warrior.  From the Windows task bar, select the following to open the Metrowerks IDE:

Start => Programs => Metrowerks => Code Warrior IDE

If the Startup window is not already opened then with your mouse select:

File => Startup Dialog...

In the Startup window, select 'Load Example Project' and in the Example project windows, use the left pane to navigate to find the AxiomPE_CME12-B32 stationary.  Next click the 'Set...' button and used the pop-up window to navigate to a directory for the new project and also enter the name 'hello' for the new project, click 'Save'.  The project and and location should be inserted into the corresponding fields in the Example Projects window, click 'Create Project' to create the new project. 

After a few moments, the project is created, congratulations.  The pane to the left, with the title bar hello.mcp is the project navigator window.  If you would rather not have the window docked, right click on its title bar and select MDI Child.  To move the window to a different docked position, select floating and then move to the new position.

To implement this program, we will use the file main.c provided with the stationary.  Back in the project File View pane, double click to open the file main.c.  Make the necessary changes to the file so it contains the following:

/*************************************************************
 * main.c - Jonathan Hill - Jan. 21, 2010
 * A not-so traditional version of "Hello World!"
 ************************************************************/
#include <stdio.h>
#include "termio_68HC12B.h"
#include "includes.h"
									
void main(void)  {
  int val, done = 0;
 
  TERMIO_Initbr(9600);
  val = printf("Hello World!\n");

  while(!done)
    { ; }
}

The standard input/ouput library header file (stdio.h) includes prototypes and other declarations associated with the standard input/output library.  The terminal input/output library header file includes like information regarding the terminal library.  In an embedded system the input and output can be managed many different ways.  This version of CodeWarrior addresses the issue of input/output handling by providing an example files named termio.c and termio.h which developers are encouraged to modify.  I modifed these files to produce files that work with our stationary, save each of these files to your project folder.

next, in the project manager right click on the sources folder icon and add the files to all the targets.

Project => Add Files...    

The termio header file is needed by the call to TERMIO_Initbr().  Unlike TERMIO_Init() provided with termio.c which does not accept a Baud rate value, TERMIO_Initbr() function accepts a Baud rate value, in this case the Baud rate is set to 9600 bps, assuming that the bus cycle rate is 8MHz. 

Despite the controversy, this main() returns void, as this program runs without an operating system of any kind.  The printf() call returns an integer equal to the number of succcessful conversions to standard output that were performed.  If we remove the assignment to val, the compiler will warn that the returned value is not being used.  If we leave the assignment, the compiler will warn that an unused variable is being removed.  Doesn't it all seem silly.

Building the Project

In the project window change the build target to Simulation.


Build target setting

Click the build button to make the build target. 


Build button

After a few moments the message window appears, indicating success or failure of the build.  If you have any errors, go back and fix your code.  Assuming success, click to close the message window. 

Simulating the Project

Next, start the debugger.  In the project manager click the debug button.  Newer versions of Metrowerks Code Warrior embellish the icon with a small insect figure.


Debug button

The simulation build target differs from the others in the stationary in that an I/O subsystem model is loaded along with a simulator.  You will next use a model that simulates the behavior of an serial communications terminal.  In the debugger window select:

Component => Open

In the pop-up window that appears, select the item titled Terminal and click OK. 


Component selection

The default size of the terminal component is quite large. Using the mouse, drag the left, right, and bottom borders to reduce the size of the new window. 

Running the Simulator

The 'C' code first listed in the source pane is the program start-up code; with PC tools this code is normally hidden from you.  Click the Start button to start the simulation, the stationary has a predefined break point that stops execution at main().


Start/continue button

The debugger window has a number of tools open and in view.  There are windows that list all the variables, procedure calls, CPU register values, memory contents, and disassembled code.  Rather than closing the three lower left windows and possibly having to reopen them them later, click to minimize each window.


Window minimize button

With the windows minimized, point the mouse cursor at the lower edge of the Source window.  Next press the left mouse button and drag to stetch the pane edge downward.  Click the step-over button, shown next.  This button causes the debugger to execute one 'C' text line, stopping at the next line containing executable code.  If the text line is a function call, then the entire function is executed and execution stops at the next line at this level.


Debug step-over

Click the step-over button again to execute the printf() instruction.  The familiar greeting should clearly be visible in the terminal window.  Program execution ends near the end of main().

The way the standard input/ouput library is written, the printf() function may return before trailing charaters are actually transmitted.  Continuing the program at the point returns to the startup code but may also give the UART a chance to catch-up.  If you accidentally lose control of the execution of your program, just the Halt button to stop program execution. 


Halt button

Before you exit the simulator, take a moment to look at each window and try a few things.  If you like, set a break point.  Click left to select a line in the source code, then right click.  In the pop-up window make a selection to insert a break point.  The reset button resets the program, so you can restart it. 

Getting Practical

To be able to use the standard input/output library the stdio.h header file must be included and a module like termio.c must also be in the project to provide the lower level primitive functions that actually access the serial communications port.  In this case the file we used a custom tailored source file for the 68HC12B series microcontrollers where the output is handled, character by character by TERMIO_PutChar(). 

void TERMIO_PutChar(char ch) {
  while (!(SCI.SCxSR1 & 0x80)) {};  /* wait for output buffer empty */
  SCI.SCxDRL = ch;                  /* transmit character */
}  

The while loop, referred to as a spin-lock literall locks the system until the transmitter is able to accept a new character.  It is critically important that the TERMIO_Initbr() function is called before using any standard input/output library function.  But in all honesty the standard input/output library is not used much in embedded applications.  We use the standard input/output library here as a vehicle in our review of 'C' programming, but thats about it.  There are several points worth considering;

In closing, there are several topics left for discussion later, such as the use of interrupts, the circular queue, and programming the actual hardware.


Please Let me know that you read my web pages.

This tutorial is written for computer engineering students at the University of Hartford.  Copyright is reserved by the author, but copies of this document may be made for educational use as-is, provided that this statement remains attached.  The author welcomes corrections, comments, and constructive criticism. 


Original Author: Jonathan Hill
( jmhill at hartford dot edu )
Copyright: Thu Jan 21 23:45:35 EST 2010