Spare Time Labs 2.0 | |||||||||||||||||||||||||||||||||||||||||||||||
Welcome EazyCNC jDraft 2.0 PureJavaComm PIC CDC ACM Weather Ten-Buck Furnace
H8S Bootloader
Camera Calibration
Multitouch
Myford VFD Fun with HC08 bl08 printf II Java Goes Native
Densitometer printf jApp Igloo New Furnace New Furnace Part II Linux 101 H8S/gcc Quickie Gas Fired Furnace Down Memory Lane Exlibris Wheel Patterns Glitches CHIP-8 eDice Animato jDraft JNA Benchmark Contact Info |
Created 16.3.2008
Having fun with HC08Here is a nice little project for a rainy weekend, all this can be accomplished over a weekend and for under USD 15. This page has gone through several rewrites, mainly to get rid of my 'rant mode' writing, but it seems I just need to write it out of myself. Feel free to skip the first part. For references purposes and convenience I've put all the useful links here at the top of the page:
Table of ContentsEven though this is a rather long page it has a kind of 'linear' story to it and I've meant it to be read straight through. Having said that I realize that a table contents is handy, especially if later on you want to come back and look for something. Besides it allows you to skip the rant part and get down to the brass task, starting at 'Building the Hardware'.
Introduction
Why microcontrollers
Taking the long term view
Looking for a microcontroller
C-programmable
DIL package
USB Support
Single Chip
In-circuit Programming
Used by the Professionals
Mac Evangelism
Integrated Development Enviroment
Cost Issues
Which Microcontroller - Finally getting to it
Building the Hardware
The Bootload Adapter
The Microcontroller
Setting up the Software Tool Chain
Scary stuff - the command line
Your very first microcontroller software -- Blink LED
Moving On - Hello World
Real Programmers Do It with Eclipse
Creating a Makefile based C project in Eclipse
Understanding the Code
Brief Intro to Memory Mapped I/O
Walking through IntroductionThis page is about getting started with having fun with microcontrollers, particularly with the Freescale MC68HC908 family of controllers.This page is aimed at beginners in microcontrollers. While a microcontroller project may not be suitable as a first project in electronics I hope to show that it is not that difficult either. The controller here can be put together and the development environment set up in a few evenings and for less than 15 USD, if you have the basic infrastructure, a personal computer and tools, in place. Lots of people are interested in microcontrollers, as witnessed by the countless number of hobby pages in the net. If you are new to this hobby it might make sense to pause for a moment and think about why you want to get involved. Motivation always concerns me a lot, in more than one sense of the word. While I'm not always forthcoming with my own motivations, at least I try to be honest with myself. A lot of people vaguely cite that they want to learn to 'do microcontrollers' or 'learn a new programming language'. These are as good reasons as any, but I suspect that behind these statements there are dreams or ambitions that aim further. Search within yourself and find out what makes you tick. So before I get to the actual technical substance, let me do some soul searching here with you, maybe it will provoke some thoughts that will help you to make up your mind.
Why microcontrollersI spend about two hours every day commuting and no sooner than I've started the car my thoughts start to wonder and I get these ideas. Hey, it would be cool to monitor the electric consumption of the house, just measure the pulse train on the meter, or how about creating that CNC rooter I've always dreamed of and I could build an induction furnace or how about a levitation device... What is common to these pipe dreams is that most of these would be best implemented with a microcontroller. A microcontroller is a sort mini computer with a central processing unit or CPU, some memory and some peripherals or input output devices. Let's face it, analog circuits and logic chips are just not the way to go today. A microcontroller can create pulses and frequencies, measure signals, do math, do logic and control them in a wonderfully precise and repeatable way. No tolerances to worry about, no trimming to do, no need for special measuring devices. Everything is going digital and that is the way it should be. It just makes sense. "Anything you can do I can do better" is the attitude of digital processing toward analog circuits.
Taking the long term viewI'm a professional programmer involved in designing embedded systems on a daily basis for the past quarter of a century, almost as long as they've existed. I also enjoy tinkering with these things in my spare time. Now how twisted is that! With this schizophrenic mind set I cannot help bringing some of my professional baggage to my spare time activities although the motivations, goals, requirements and resources of professionals and hobbyist differ considerably. Learning new stuff, like microcontrollers, is fun, but it's also an investment. An investment in yourself and your future. Like any investment it requires spending one thing to gain another. Time and money. Money is a secondary consideration; anyone can be rich, but no-one lives forever so we all must carefully consider what we do with our time. As with any investment, it is natural to expect from it something in return, be it in the form of skills, opportunities, gratification or just sheer fun. So what has all this got to do with microcontrollers? Learning to 'do' microcontrollers is a big investment in terms of spending precious spare time. Nobody wants to see their investement go bust so it pays to invest carefully. Concerns include, "what if the chip I'm using gets discontinued," "what if the tools I'm using get discontinued," "am I going to be left in a niche where other users are few and far between." This may sound a bit pompous, talking like that in the context of a hobby project, but as one lives one learns, and I've seen so many one-off temporary projects, both hardware but especially software, to live well beyond the wildest expectations of their creators. I'll bet you anything that the guys writing Unix code more than fourty years ago had no idea that a lot of this code would still be running and tooted as the most advanced operating system available today: Mac OS X! I've found playing with microcontrollers both rewarding and fun, and it has even paid my mortage, but surely it also has swallowed a big chunk of my life.
Ok, so let's see where this sort of thinking has lead me and why. I'm not putting this forward as the only right way of going about it, I'm just sharing my point of view. Corrections and revisions of my opinions are encouraged. If you're still reading, remember, that it sometimes pays off to listen to others who've 'been-there-done-that', but you should also study yourself and find out what it is that you really want to do. It is your project and your life.
Looking for a microcontrollerFor years I've been looking for a suitable microcontroller that would fulfil my self-imposed constraints. In the past, me and my friends have had great fun building things from the 68HC11 family of devices, but, although a very nice device, it leaves something to be desired when compared to more modern offerings with internal Flash and whatnot. Here is my list requirements for a microcontroller:
Interestingly, this list is always almost the same regardless of what I am contemplating to do with it, pretty much like my cooking really; first I take a pound of butter, bowl of sugar, a pint of cream , half a dozen eggs and then I start to think what to cook and eat! In the following, I'll discuss these to give a beginner one point of view on the matter. Please note that there are many views on this, none, including mine, of which are necessarily absolutely correct. In the following I'll discuss my views on each of the above-listed requirements to some length.
C-programmableProgramming is at the very heart of microcontrollers - it is what makes them tick, and it is what makes them so universally applicable to various task. Those people at the silicon foundry who crank out these chips for us don't know or care what we do with them. And they don't have to, that is the beauty of it, because we as programmers put in the soul, the program, that dictates what it does. So the parts can be manufactured in millions, bringing the cost down.But those darn chips only understand and obey voltage levels in their memory cells and while it sometimes is necessary and strangely satisfying specifying those voltages with ones and zeros, it surely is not the way to go on a larger scale. So we need something higher level that allows us to think in more abstract terms than boolean logic and flip flops which are the building blocks of microcontrollers. We need a programming language. Now there is something about programming languages that makes people foam in the mouth. Don't know what it is, but there surely is something fascinating about them and everyone seems to have very definite opinions about them. Me too. Lots of the argumentation and discussion on programming languages seems to center around technical characteristics or philosophical issues about why one programming language is better than another. While there certainly are differences and one can put forward well-founded arguments for various aspects of different languages, I find that this sort discussion is centered around the wrong questions. The question is not about which programming language is the best, but rather which one you should use and thus learn. All the programming languages are pretty much the same. How could they be different, seeing that the computing architecture is always pretty much the same old Von Neumann and the problems are always the same, control flow, data representation, computation and storage management. Make a decision on those, throw in a syntax and, hey presto, we have a programming language! Of course, there are some differences and some languages are better than others, but the essential difficulties of programming are not likely to be solved with one programming language, any programming language, anytime soon! If they could be, I'm sure they would have been solved already - just look up the 2000+ programming languages at Wikipedia. So how do you go about choosing a programming language? To me it the choice is obvious: you select the most popular girl in town!. I know the old joke about flies and cow pat, but when something is popular there has got to be something good about it. And there is safety in numbers, bringing me to my pet long term view theme. When there is a large user base you get:
As often in life, it pays to take the middle road. Yes, it is a vicious circle that ties us to design decisions done decades ago but there is no escaping the past if you have the future in mind. Now isn't that ironic!
And the lucky winner is CC has never been my favorite programming language yet both professionally and hobby-wise it is the only choice I can think of when talking about small microcontrollers. The tools and the language are mature and standardized, even the C99 standard is ten years old next year. But hey, lots of people use BASIC or some improved C-like language to program microcontrollers, surely that makes sense? BASIC has a special place in my heart, it was the first language I learned and it still has certain appeal in its simplicity and ease of learning. However, I would never consider using it for anything real. Well, that is not quite true; only some weeks ago I was well on my way to write a BASIC compiler for HC08, I had the linker and assembler ready, and the compiler ticking, but fortunately I came to my senses before I wasted any more time on it. Speaking of BASIC, what BASIC are we talking about? ANSI BASIC, or some proprietary product? The original Dartmouth BASIC (born in -64 like me) was a very simple language that contained all the basic building blocks that you need in a programming language, but lacked the basic higher level abstraction features that I think are essential, like named subroutines, local variables and parameter passing, and structural control statements, without which programming is rather similar to assembler programming, making it difficult to manage anything complex successfully. Of course, later variants of BASIC added these features, only so many of them went their own way, so they are all the same, only different!
With C the people who can (?), the language and tools will be here in twenty years time when I or or someone else needs to get back and tweak the software. Imagine getting an old BASIC program to play ball with in ten years time. And this need to tweak is not an 'if', it's a 'when'!
Talking about proprietary products versus standard languages: while you can learn to program in a few weeks and learn a new language, any language, in days, it takes years to master and learn the nitty gritty details where the evils lurk, so to me it does not make sense to invest in learning something that may not exist tomorrow. Companies come and go, they are bought, sold and merged, products discontinued and killed off. So, personally, I would never invest programming in a language that does not have an exceptionally high likelihood of survival. A case in point, Microsoft's Quick BASIC for Mac was discontinued, killing a successful product that I was personally involved in. The same happened to a friend on the PC version. I go as far as making the language and tools affect the choice of the chip. If a chip is not supported by Gnu C it is a definite minus point. If it can't be programmed in C it is a non starter. No chip is so great that it makes sense to invest on re-learning a new programming language when the competition is bound to offer something that can be programmed with C. Before I close up this rather long and most likely boring section on programming languages, I can't help mentioning the project Arduino. Everyone interested in getting into microcontrollers should check it out. Although I think the idea of having yet another IDE and adding some sort of automatic preprocessor on top C does not really make sense to me, the project has a lot to offer.
DIL packageIn professional circles, surface mount devices are not only a fact of life but a desirable characteristic. However, for the hobbyist they are a real pain in the hindquarters. Not only do you need a printed circuit board, then soldering them is also no piece of cake. It can be done in a home workshop - I've done it myself, but I've also been forced to outsource some SMD soldering on one of my hobby boards! And it is not always easy for the professionals either; only last week I witnessed two failed professional attempts to solder a QFP package to a prototype.To your left you have two MC68HC908 chips with a 20 SNT coin and a 1/4 W resistor for size reference. The left one is a GZ16 in a 32 pin LQFP package and the one on the right is JB8 in a 20 pin PDIP package. Click on the image for a larger view. You can solder some SMD packages on a modified oven or you can do what I've done, which is soldering all the pins into a solid mass that I've then cleaned up with a solder wick. But soldering is not the biggest problem. To me, the biggest problem is that you need a PCB. It takes time to design and manufacture a PCB and because of that it makes sense to incorporate all of the circuitry on the board, including those you could've just Vero-boarded. So it takes even longer, and before you know it your enthusiasm is gone and the project just becomes one of those 'I'll finish it one day" -projects. Here is one project that for the time being has run out of steam, tucked away shamefully into a faraway corner of my hard drive. What I want is something that can be whacked together in matter of hours or a few days on a prototyping board. True, there are ready-made adapter boards for most SMD packages and one of these days I'll get some, and although money is no concern, per se, in a hobby, it goes against the grain to use 10 USD to mount a 2 USD chip, and still having to breadboard all the rest.
Thus, one of the key requirements is DIL packaging.
So what's this got to do with microcontrollers? Well, so many of my ideas would be best implemented so that
the low level real time stuff is done on the microcontroller but the rest, like networking, storage and user interface,
on a proper computer. Yes, I've seen weather stations that boast a web server on a match box size PCB but for me
using that old laptop in the corner to record and control my wind turbine parameters would make much more sense,
except that it can't do any real time stuff with Windows on it and I can't connect anything to it because it has no serial port.
Surely you can add a USB -serial port and many times that is the answer, but what about if my cool idea is
turned into a product someday? A USB serial port burdens the product with 20 USD for starters and incurs complexity
and still limits the connectivity to what a serial port can offer. Came to think of it, BasicSTAMP would set
it back even more.
So taking the long term view I think it makes sense for me to bite the bullet and learn to 'do' USB.
Besides doing it from the ground up just is the way I do things!
Many chip vendors and tool vendors provide free (as in free beer) versions of their tools and compilers.
Which is great and fine, especially as some of them are better, in some measures, that their Free (as in freedom)
counter parts. However, they are in it for the money, which means that there has got to be a catch somewhere,
like you can use only 32 files and 1 kB code per file and max 4 kB code. Of course, market pressure and
strategies seem to force the tool vendors to offer more and more free stuff and relax the crippling (=ei ole sana?)
to lure customers but at the end of the day commercial tools are at the mercy of tool vendors' business
decisions. Companies get sold and merged, whole product lines get sidelined or discontinued, in any
case improvements will require cash layout at some point.
So, for my hobby projects I want to use something that I hope will be there tomorrow at an affordable price.
Taking the long term view, if at all possible within the other constraints, I want to use gcc, the Gnu C-compiler,
that is bound to be there for the long term. The One Tool to Rule Them All.
Having said that, it seems that for 8-bit microcontrollers, which have some rather simple or downright weird
architectures, gcc is not likely to be available. It used to support things like 8051 but that has been
effectively dropped for the time being. And it may be that this is the way it is going to stay as there may be
a fundamental conflict between the small microcontroller and the multitude of languages the compiler supports and
the kind of more powerful CPU architecture it is designed for.
Fortunately there is the microcontroller world that is the equivalent of gcc, the SDCC - Small Device C Compiler.
Which just shows you the power of using standards and C - my favourite tool was not usable but I found another one!
Interestingly, it is the consumer market that in turn drives the professional markets! We are all hobbyist when it
comes to snapping photos with our IXUSes and it's the development of the consumer gear which definitely drives the chip development.
When I use an IDE I want to use the same IDE for everything, not change it as I juggle between projects, or as the case may be,
when the IDE company is busted or gets sold. Ask any CodeWright user if you want to hear more rant in this same vein. While
many of the proprietary IDEs, especially for embedded markets, are decent, I've found none that I would call good.
A lot of things are poorly executed, as if the developers themselves never used them for real work.
There is one IDE I actually like, and that is Eclipse. Incidentally, it is now Free Software although it has
its roots in the IBM VisualAge for Java. It gets so many things so right that I sometimes expect there is a mind
reader somewhere. The code completion and re-factoring tools are awesome, the ergonomics of the user interface leaves little
to be desired, the search and code navigation tools are great and work like a breeze. It has a large user space and is
available for all major platforms and support many languages. Vibrant and kicking.
And with the CDT plugin it is now a viable C/C++ environment. True, the re-factoring, build and search tools
for C/C++ are not yet quite as good as for Java, but it keeps getting better and is already my favorite
for C programming.
Of course, nothing is perfect and neither is Eclipse, but I like it and it seems to be destined for a great future, which
is all-important.
Cost as such is not a big issue, for one-off project it makes a little difference if a chip costs 2 USD or 40 USD,
but then there there is the co-later damage, investment in learning and using what you've learned.
If you learn
to use a 40 USD part, you are likely to use a similar part again and again and if you invent the next big mouse trap the 40 USD part may
make or brake the project. And needing to re-learn something as complex a new microcontroller is sure to put the brakes on
for some time, at least for the hobbyist.
By now you should see, even if you may not agree, why BASIC Stamp and PICAXE were not even running in this competion.
My short list of candidates for a microcontroller was:
The older PIC families had definitely weird and unfriendly architecture that made them unsuitable for other
than assembly language programming or using their special version of BASIC. The later 18F series seems to be
more main stream and SDCC supports both the 16 and 18 series of PICs.
PIC18F2550 supports USB, comes in a hobby-friendly 28 PDIP package (or even 40 pin!), requires an external crystal
and has 32 kB of Flash 2048 bytes of RAM.
Unfortunately, this chip was not actually available when I made my decision and even samples were impossible to get,
otherwise you might be reading my web page titled "Having fun with PIC18F2550". I have actually put in an order for some
samples, so maybe I'll be reporting back on it in a year or two.
Since I've not used it I cannot say what it takes to program it in-circuit as I want to do, but surfing the web you
see a lot of options software-wise.
Talking about crystal oscillators, while a crystal and the two caps plus resistor required by most chips are no big
deal they can cost more than the microcontroller!
Unfortunately, it is not available in a DIL or PDIP package which means that I need to get an adapter board or design a PCB.
No wonder those chips have been on the shelf for two years now.
Also, in-circuit programming via a C2 one wire interface sort of put me off because you cannot directly
generate from a serial or parallel port the sort of signaling it requires.
68HC908JB is available in a 18 pin PDIP package, which limits the number of I/O available and it does require an
external crystal, but it supports USB and has 8 kB Flash and 256 bytes of RAM.
In-circuit programming is possible with the one wire serial communication based monitor mode which is easy to
implement with standard serial port on any PC.
MC68HC908JB8 is also the cheapest of the lot at around 1.5 USD in quantities of one, the C8051F320 sell for around 6.5 USD
and the PIC18F2550 is sold around 4.50 USD, not that it makes much of a difference.
For serious professional work the Silicon Labs chip seem to provide best bang for buck in terms of being the industry
standard core with minimal external circuitry, fast clock speeds and more than adequate memory sizes. For the hobbyist
the PIC18 family seems very attractive as does the Atmel ATmega48 family which is available in the hobby-friendly 28 PDIP package.
Worth noting is also Atmel AT90USB family with its 64/128 kB Flash memory, 2/4 kB EEPROM, 4/8 kB RAM , high performance RISC architecture with USB 2.0 support and really attractive feature: USB bootloading. Sadly, it does not come in a suitable package.
After saying that I think that PIC18F family seems ideal for a hobby project I guess it now seems logical that this page is about HC908JB!
BTW There is logic according to which Freescale name their parts. Take for example MC68HC908JB8, the MC is
what Motorola has used for ages for designating their parts, the 68HC indicates that this is a descendant of the original
6800 microprocessor but in high speed CMOS, 9 indicates that this is a device with internal Flash ROM and 08 stands for
cpu architecture variant as in 6808, JB is the family of USB oriented devices and 8 is the amout of Flash memory
in the device in kilobytes. When ordering be careful the get the right part as this is the only variant available in PDIP package.
Note that nowadays this is a lead-free product and there is a discontinued product that is just as good
but impossible to get, so don't be put off if a part is discontinued, there is usually a replacement.
The hardware is really rather simple, anyone should be able to solder it together on a Veroboard in one or two evenings.
This may not be the ideal very first project in electronics as you need to be able to read schematics and hold the
soldering iron from the cool end. That said, this is pretty forgiving and easy to get to work, unlike some
of the analog transistor stuff I attempted and failed with 30 years ago. That's because digital is simple,
just two voltage levels and large tolerances.
The parts should not set you back more than 15 USD altogether. Some, like the not-so-easy-to-get USB Device connector
can be ripped from an old PC. Speaking of the USB connector, a good solution is not to have a Device connector at all but
to take a regular USB cable, cut away the Device end and solder the wires directly on to the Veroboard.
The hardware consists of basically two parts: a serial bootload adapter and the actual microcontroller, see the illustration below.
There is no need for a power supply because for up to 100 mA we can draw the power from the USB port and for this set up we'll be using well below 30 mA here.
The bootload adapter converts the voltage levels of your serial port to match those required by the microcontroller and
allows you to download software into the microcontroller as well as provides a handy way to debug and experiment with
your system. It also provides the 'high' voltage that is required to force the microcontroller in the Monitor Mode in
which the downloading can take place.
Below are the schematics for the bootload adapter. For complete, printable schematics scroll to the bottom.
The bootload adapter is just a MAX232A and a diode that performs a logical OR function to combine the receive (RX)
and transmit (TX) signals. This turns the serial communication into a party line where either end can talk to the other
end but only in turns. The MAX232A is made for the very purpose of converting from and to the serial line -12/+12 Volt
levels to the CMOS 0-5 V level logic. For this purpose it contains charge pumps that magically turn the +5 Volt feed into
the -/+ 10 Volt required.
The HC908 requires that a 'high' voltage of about 8 Volts is presented in the *IRQ pin to force it into the Monitor
Mode upon reset. The circuit presented here takes advantage of the MAX232A charge pumps to steal that voltage from there.
The adapter is re-usable in the sense that it is no longer required in this project once the project
finished so you may want to construct it separately for easy re-use. To your left you cas see a picture of my adapter.
Below you'll see the Vero-board layout I drafted for it (click the images for larger view). I usually don't go to the trouble of drawing a layout but I wanted to
make sure I did not run out of space as I wanted this to fit into my nice box.
It is also nice to have an LED so that there is something to experiment with as soon as the hardware is done. I also
always include a LED that tells me that the power is on, which in this design is the red LED on the adapter. This LED
also blinks as the serial communication takes place, which is both useful and comforting.
Below are the schematics for the microcontroller. I haven't included any actual peripherals at this stage to
keep the schematics simple, but you are sure to find plenty of online examples on how to connect LCD displays,
stepper motors, relays or whatever you fancy to put there.
Note that I've not yet personally implemented/tested the USB interface part, but from documentation
it appears that you should not need the pull up , nor should you need the serial resistors shown on my schematics.
I constructed mine on a Vero-board, see below, in about two hours with just the schematics as a reference. If you are inexperienced
it might make sense to draft a layout plan first.
For the software you need a C-compiler to compile your programs into machine code and a bootloader to
download and 'burn' the machine code into the microcontroller's internal Flash memory.
For anything larger than a single file test program I highly recommend using make to automate the process. You also need a text editor; any editor that can write plain text files will do, but I'll
show you how to set up a really streamlined development process and professional Integrated Development Enviroment with Eclipse.
And all this is free in every sense of the word.
For the compiler we use SDCC which you can download from their web site at
http://sdcc.sourceforge.net . In addition to the source code, pre compiled binaries are available for all the major platforms, so there is no need to compile it from scratch. (I need to praise the SDCC project for making a good job on this, because building it from the source, when I tried it, went according to the book, something that does not often happen with your average Open Source project.)
So download the distribution (see the Snapshot section), unpack it and put it where you like, for this tutorial I use my own set up as an example
and I keep SDCC in my home directory under the name
When reading through this stuff here you may get the impression that you are going to do a lot of command line typing stuff.
Not so, don't sweat it.
Even if you are not going to use an IDE but your favourite editor and work from the command line, your minute by minute routine is
going to be something like 'edit code, type make' over and over again, not a lot of typing really. And even if you are using an IDE you need to be able to
get grasp of the command line stuff to setup and trouble shoot the IDE stuff, when things don't go smoothly.
A few tips that will make life easier on the command line.
First of all you do not always need to type long lines, it is also possible to copy/paste stuff from for example this web page to the terminal so that you are spared from typing and typing errors.
Pressing the cursor-up key in the terminal window will bring back your previously entered line, which saves you from a lot of typing when you repeatedly need to try things. Press the up key several times to go back even further back in history.
This is universal, basic command line stuff that is worth learning. Every programmer should learn the basics of command line even if they spend all their life using an IDE.
Note that this page and the examples are written with Mac OS X as a reference platform so some things maybe slightly different in Linux and Cygwin, but not much, and should work almost verbatim. Much of this applies to pure Windows as well, but I won't be covering all platforms here.
We are going to fire up the Terminal to get access to the command line but before we do that we do a litle tweak that will lessen the amount of typing we need to do. We will modify the
/Users/nyholku/sdcc/bin/sdcc
sdcc
export PATH=${PATH}:~/sdcc/bin:~/bl08
If you are using Mac's TextEdit as your editor always make sure that the "Hide Extension"
and "If no extension is provided, use .txt" check boxes are unchecked when you save a file. Note that the file is invisible in Finder because it starts with a period. Also worth noting is that you cannot open files whose name begin with a '.' from within TextEdit, you need to do this from the command line with something like
Note that the 'shell' used by the Terminal was different (from bash) in versions before Mac OS Tiger so setting the path maybe a little different on older Macs.
If you paid attention you noticed that while we were messing with the path we also added the path to 'bl08' which
we will need later.
Next start a terminal session, on Mac you'll find the Terminal application under
After firing up the terminal you should see something like:
Now to just see that the 'path' setup was succesfull type
sdcc
SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.7.4 #4988 (Jan 9 2008) (Mac OS X i386)
Usage : sdcc [options] filename
Options :-
-bash: sdcc: command not found
you messed up the path setting or sdcc installation and need figure out what went wrong.
Next we install the bootloader software 'bl08' which will be used to download and program the
code into our microcontroller. To install it download the source code from here , unpack and
save into a directory named
To compile it you type the following:
cd ~/bl08
gcc -o bl08 bl08.c
Our first program will just blink a LED.
Simple but oh so satisfying, I can still remember how it felt about 30 years ago when I saw my first microprosessor
to blink that LED! Those were the days. This is also the way professional bring up prototype boards, just do
something simple like blinking a LED to see that the system is at least alive -- you can't run until you can walk,
so you need to take baby steps first.
To save you from typing I put all sample code on-line and you can download it from here,
but for, now lets pretend you type in the following program with your favourite editor:
and save it to file 'blink.c' in the directory '~/hc08demos/blink'. Your editor does not support colors? Don't worry, them colors ain't supposed to be
typed in , I just colored the listing to make it look pretty.
Next 'go to' the
cd ~/hc08demos/blink
sdcc -mhc08 --stack-loc 0x013F --code-loc 0xDC00 blink.c
Among the files produced there should be one named
Now all we need to do now is to download and program the code into our target microcontroller.
To do that you need to have a serial port connected to the bootload adapter and the USB cable connected between the
target and your PC to supply power to the device.
Before we can issue the download command we need to find out what is the name of your serial port. None of
the modern Macs come with a serial port, so if you are trying this out on a Mac you need to install a USB serial port adapter.
Don't forget to install the drives, see the adapter manual for that. The manual should also tell you the name of
the port but you can easily find it out yourself. This is a trick worth learning as this applies to Linux and Cygwin as well, just type:
ls /dev
ptyqe tty ttyv2
ptyqf tty.Bluetooth-Modem ttyv3
ptyr0 tty.Bluetooth-PDA-Sync ttyv4
ptyr1 tty.Kusti-Dial-UpNetworking-1 ttyv5
ptyr2 tty.Nokia3110c-Dial-upnetwo-2 ttyv6
ptyr3 tty.Nokia3110c-NokiaPCSuite-1 ttyv7
ptyr4 tty.usbserial-FTOXM3NX ttyv8
ptyr5 ttyp0 ttyv9
Now, the moment we have waited for, silence please, maestro drums.
Press the RESET switch to ensure that the target is in Monitor Mode, waiting for our stuff, and type:
bl08 -c /dev/tty.usbserial-FTOXM3NX -b 9600 -t jb8 -x 12 -f -g reset blink.S19
bl08 - MC68HC908 Bootloader - version 1.0.0.0
Reading S-records
Line ignored: S9030000FC
S-record data address 00FFFE size 000002
S-record data address 00DC00 size 000051
Mass erase
Program FFFE - FFFF .
Program DC00 - DC50 ..
Execute code from DC00
What a feeling, time to celabrate, get me a tall decaf nonfat mocha latte with mapple syrup and foamy top
, sprinkled with cinamon and chockolate shavings, I've deserved it.
This was such a memorable occasion that I've even filmed it for posterity, don't miss it, click the picture above.
If, on the other hand nothing happens, it is time to trouble shoot so you need to read the trouble shooting section at the very end of this page.
Before moving on, it might make sense to briefly consider what we have just done. To help to discuss this I've drawn the diagram below:
Reading from left to right things proceed pretty much in the same order as in reality.
First we have our program written in C in file called
All this takes place when we give the command
Also worth noting is that SDCC is the 'one stop shop' for compiling programs, it is a C-compiler, assembler and linker, all in
one package.
Next the loadable file is downloaded to the target microcontroller using the bootloader software
Debugging is the art of finding out why the system doesn't do what we told it to do. To do that we need get information
on what our code actual does and compare that information with our expectation of what it should be doing.
I've done a fair
amount of code writing on devices where the only output was a couple LEDs. Accomplising this does make you feel like a
hero, but it doesn't make sense, so the first thing I always do in a new project is to set up some way to send text out of the device.
When designing an embeded system it always pays to have serial port or some such on the device to get that text out
when you are developing the software, and even later on, because when system device fails to
perform as expected how are you going to find out what is the matter?
So, let's set up
We are going to do the classic 'Hello World!' program, finally!
Doing that is pretty simple, create a directory named
In to this directory copy two files,
Now create and type in the following code and save it under the name
Now you can compile this by typing the following three lines:
sdcc -c -mhc08 --stack-loc 0x013F hello.c
sdcc -c -mhc08 --stack-loc 0x013F printf.c
sdcc -mhc08 --code-loc 0xDC00 -o hello.S19 hello.rel printf.rel
By the way, above is an example of how you compile and link a multi file project using SDCC, an example
that I was unable to find anywhere when I started to work with SDCC.
If you look carefully, and as
a budding programmer you should always look carefully, you notice that the parameters passed to the
SDCC are slightly different in this example than in the previous. Or actually they are the same but
we are passing them slightly differently.
The first two lines are used to 'compile only' the files without linking them by
using the
The last line links the two previously compiled files,
Note that it is always ok to pass both options to SDCC regardless weather you are just compiling
or linking. Note also that with some different target architectures in SDCC the stack location
is actually needed in the link phase, not in the compile phase, so maybe the best strategy is to
always pass all parameters.
But all this typing is getting a bit tedious, so I think we are ready to introduce
Make is traditional Unix tool that is used to automate the compiling of programs.
Any non trivial C program consists of several source code files, each of which needs to be compiled separately and
then combined into a single executable. That's what we did above, the two first lines in the example compile the
two source code files and the last one links them together.
Now we use
Mac OS X supports
To use
Using
So create the following
Once you have the makefile in place you can 'make' it by just typing:
make
Now all that is left to do is to execute our litle Hello world.
So press RESET on the target device and type
the following command to download and execute the code. Note that this line is slightly different from
the previous command because we want invoke the
bl08 -c /dev/tty.usbserial-FTOXM3NX -b 9600 -t jb8 -x 12 -f -g reset -m hello.S19
This should produce the following output on your terminal:
Hello World, this HC08 talking!
Hello World, this HC08 talking!
Hello World, this HC08
And so on and so.
Bring another latte and this time make sure its hot enough and the crema gusto properly made.
To round up this 'Hello World' demo, let's review how we put together the
This is quite similar to what we did with the
But there is one more thing to do before everything is set up the way I like. While using the command line is actually as simple as typing 'make', it is not the way I want to work all day long...because there is a better way...
and go to Download page and select 'Eclipse IDE for C/C++ Developers', this is a nice little 67 MB download.
Double click on the
downloaded file and Mac will unarchieve it into a single
folder
Launch Eclipse by double clicking the icon.
Create a workspace by entering a path to where ever you want it to be generated.
Close the wellcome tab/view by clicking the X -shaped icon.
Eclipse is now installed and ready for action.
Into the 'Project name' entry field enter a name for the project, call it
Uncheck the 'Use default location' check box.
Into the 'Location' entry field enter
On the 'Project types list, expand the Makefile project and select 'Hello world C++ project'
It should look something like this (click image for larger view):
Click 'Finish'.
This will produce an error/warning dialog or two because the Makefile already exists, but just ignore them by cliking OK.
Now the situation should look pretty much as follows:
Make sure that the 'Console' tab (Eclipse calls them Views) is visible, if not, click on it.
If you can't
find it, go to "Window/Show View/Other..." menu and search for it by typing 'console' in the search box.
This tab/view
is the Eclipse equivalent of the terminal / command line we just left behind and you'll see the compiler print its error
messages there and even the output from our target device. Remember the printf exercise we did above? You guessed it,
even that output will appear in the console window!
Just for fun, you can now build the project, from the "Run" menu select "Build All" and you should see something like
this appear in the console view:
**** Build of configuration Default for project hello ****
make all
~/sdcc/bin/sdcc -mhc08 --stack-loc 0x013F --code-loc 0xDC00 --disable-warning 85 -o hello.S19 hello.rel printf.rel
Next we will introduce Eclipse and the bootloader to each other.
From the "Run/External Tools/Open External Tools Dialog..." menu lets open the external tools dialog.
In that dialog, on the left side panel, click on the row which says 'Program' and then just above it, click on the little document shaped icon with the plus sign on it.
This will create a new tool with a default name.
Into the Name entry field type 'run-hello' or what ever you fancy.
Into the 'Location' entry field enter the full path name to the bootloader, ie something like
Into the 'Working directory' entry field enter
Into the 'Arguments' entry field/box enter the same command line parameters we used when we did this from the terminal, i.e.
Now it should look like this:
Click on the Apply button to save the changes.
Now push the RESET button on the target device and click on the 'Run' button and you should see
in the 'Console' view that first the project is
quickly built and downloaded and then the familiar 'Hello World, this HC08 talking!' output should start
ticking in the window.
All you have to do now to build, download, program and execute you code is to select 'Run/External Tools/run-hello' from the menu.
But wait, lets take it one step further.
Select "Eclipse/Preferences..." from the menu and open the Preferences dialog.
In the the search entry field type 'key'.
From the short list that will appear select 'Keys'.
On the panel that lists all the commands scroll until you find 'Run Last External Tool' command and select it.
Click inside the 'Binding' entry field and then press the key on keyboard you want to use.
Click OK.
Now you can go through your whole development cycle of editing, compiling, linking, downloading, programming and executing by
with a single key press.
Now how cool is that!
This page is not a tutorial on C programming, which you can easily find elsewhere, but I felt that a short line by line walk
through the code might help you over some microcontroller related rough places not covered by standard C tutorials.
Before I go through, line by line, the code I'll show you how basic input/output and peripheral control
is typically handled with C in microcontrollers.
In this way controlling output devices or peripherals is as simple as assigning a variable!
This concepts also applies to input and reading of peripherals.
A few words of caution to store at the back
of your mind though: memory mapped registers are actual hardware, not 'just' memory. Merely reading them
may cause some special action and it is not always possible to read 'back' what you just wrote into a
register, some registers are read only, sometimes the same address accesses different hardware depending on
weather you read or write. Check your datasheets!
In MC68HC908JB8 there are 64 of these memory mapped at addresses 0x0000-0x003F. Bits in these
registers controls all the aspects of the microcontroller from simple pin output to
clock frequencies and memory protection.
Every byte in memory is made of eight bits each in either 1 or 0 state. This makes for 28 = 256 different combinations. When we are using these to do calculations this is typically treated as the numeric range -128..127, using what is called two's complement arithmetic.
But when we are talking about memory mapped registers or I/O ports, we are talking about individual bits which are indipendent of each other, yet we have to treat each byte which is a group of eight bits as single value.
Each bit has some specific meaning in the hardware, this meaning being explained in the datasheet of the microcontroller. What we need to do is to be able to change those bits individually.
Full discussion of binary arithmetic and bit manipulation is beyond the scope of this page, but here is a quick cheat sheet.
It is convetional to visualize a byte as a box with eight cells numbered them from right to left as follows.
To SET, CLEAR, TOGGLE or TEST a bit in any memory mapped REGISTER look up the bitmask from the following table:
(If you want to set or clear more that one bit at a time, you can combine the masks with the or-operator '|')
Once you have your bitmask you use the code from the following table:
There is a strong tradition to use hexadecimal numbers instead of decimal numbers when dealing with
bits so I've used it here, just better get used to it.
Lets rip this line appart and see what each part says:
This defines a variable of type
For most purposes you can equate
This is not standard C, this is a SDCC specific extension. I dislike these extension but
evidently I have been succumbed to use them.
The
But where did that address '0x00' and the name 'PTA' came from?
I looked them up from the MC68HC908JB8 datasheet,
which tells me that there is a memory mapped I/O port A named PTA in address 0x0000. Memory mapping simply means that an output port is so wired in the chip that as far as the software is concerned it looks like any other memory location. To output something to the port it is only necessary write to that address.
Memory mapping is very common in microcontrollers as it avoids the need for special I/O instructions in the chip, simplifying both software and hardware and makes expansion easy.
This tells the compiler that it must not optimize away any access to this variable. Normally, the C-compiler is free to deside, within certain bounds, when and if a variable value is updated. After analyzing the code the compiler may decice that there is no need to write a variable at all because the value is never used. This in no way alters the logic of the code, but if the variable is an output port it is vital that it actually gets written, because even if the code never reads the value, the LED certainly won't turn on without the write!
So it is vital that we declare the variable
Quite a lot of information we learned from the first line!
These two lines just define two more memory mapped registers, called CONFIG and DDRA, just like the port A stuff above. These are called registers as opposed to ports but technically and practically it is all the same, all look like ordinary memory locations.
Note the
This is an essential feature in any embedded microncontroller system which is designed to run for years without intervention, however, it is a pain when debugging and developing,therefore we turn it off here. Someday, when the code is finished I'll turn it back on by leaving out this line out.
Here we turn both bits B0 and B1 into outputs by writing 3 into the data direction register. This also makes the other pins inputs as we write 0's to them,
because I did not bother to use the form
Note the opening brace
A local variable is a variable that only exists while the block where it is defined is being executed. It is a handy way to declare variables
that cannot get mixed up with other variables in your software. Remember, global variables are evil.
The variable is defined as
The obscured statement actually just says that the compiler should read the port PTA and throw away the value. I put it into the loop to waste some time and to prevent the compiler from optimizing away the whole loop! Without that, the compiler might have decided that the whole loop was superfluous as the value of
This facility is called the
Here we are including the file
How did I know I needed to provide this?
Well, I read the documentation in the
My golden rule in programming is that all compiles should be 'clean', in other words that they should result in zero number of errors and warnings. In this way I know that when I see a warning it really means something. I highly recommend this practice to everyone.
Now in this situation here, in the following, you'll see that the body of this function is written in assembly language, not C, so the compiler does not
understand anything about it. What the compiler understands is that the argument
There is no universal way to get rid of a particular warning, although most C compilers will allow suppressing of particuar warnings via command line
options or pragmas. What I've done here is that I've told the compiler to read the argument
There is no guarantee that this works with every compiler, but so far it has worked with all the compilers I've come accross,
in any case it is legitimate C and should always compile and does not clutter my Makefiles with non portable compiler options.
Inline assembler is a last resort, most of the time best avoided even if you are tempted.
What these lines say is that 'clear the bit 0 of port A' (
This addresss (
How did I know that there is this routine that I could take advantage of ?How did I know how to call it and how the interplay with C with argument passing works?
Well, first of all, I deduced that there must be some such routine there, then I uploaded the machine code from an actual chip, disassembled and reverse engineered it and then I read the C compiler manual and experimented with the info I had. Took me only about eight hours to figure out those two hex bytes!
Do not let this scare you, you are unlikely to ever require this sort of wizardy, this is about the only thing I can think of in this context you need something like this. And since it is presented here, all you need to do is to use it.
The whole
Simply put, make system is a program called
The basic form of a make rule contains two lines of which the second one is indented and it looks as follows:
This describes a dependency between three files ,
saying that if either of the files on the right side of the colon,
Basically, that is all there is to it, you could describe your whole build process with a rule for each C file and one rule
to link them all.
Well done, in one minute you have learned to read and maybe even write Makefiles.
If you take that route, you pretty soon see that all your rules are more or less similar, so you may think
that would it not be nice to write some sort of generic rule to handle the bulk of these things, just
adding some special rules by hand. And of course you can:
Often you encounter a generic dependency rule that has no second line, like:
The file on the left side of the colon in a dependency rule is techically called the target and it
is actually what you should specify on the command line to build it when
you invoke
A phony target is not file at all, but you can use them just the same, which makes for all sort of handy tricks.
In addition to rules we can also use variables, actually macros, to make writing the rules easier and
more maintainable.
We are almost done, but I need to confess that I've left one or two things
out of the makefile to make it easier to grasp.
As presented here the rules do not cover the very real case in which a
C -program file includes, via the
This should be reflected in the rules and has to be done manually, there is no
generic rule to handle this, more is the petty, but the C 'include' and separate
compilation facility is rather rudimentary.
So in our example case you should really add the following rule:
It is also customary to have sort of 'utility' phony targets in make files like:
Thats it, you are done, your first microcontroller based on the 68HC908JB8 chip is up and running,
the bady is crying out letting the world to know that lungs are fine and the heart is pumping.
You are set up for life and the things you learned are applicable to countless other microcontrollers
out there.
Time to think what this baby will do when grown up, take it collage, teach it a few tricks
and hey the next big gizmo on TV-Shop could be yours and you a millioner!
Time to update your resume and get a career in embeded microcontrolles?
cheers Kusti
Note that I've not yet myself implemented/tested the USB interface part, but from documentation
it appears that you should not need the pull up , nor should you need the serial resistors shown on my schematics. At this stage, I would not put in the 1.5 k pull up, as this will cause your Mac to recognize the device and try find a driver for, which might create a problem, don't know yet. The serial resistors should do no harm, but I've seen them used, so I included them in the schemantics, although you should be able to do without them.
Looking at the schematics you may see an additional twist, I've added a transistor
connected to the DTR line of the RS232 connector. This allows the bootloader
Just add the following option to the command line:
This will toggle the DTR line for 1 second or 1000 milliseconds before the download begins.
I promised some trouble shooting help. Being mainly a 'software guy' I'm not really qualified to help in hardware stuff but here are some tips I've picked up over the years.
First, before connecting any power, I double check the circuitry, tracing the schematics with color pen to
make sure I've connected everything right. In Veroboards it is also too easy to forget to cut some traces
so I keep a special watch out for unwanted connections/shorts.
I also mentally check the schematics once more so that it all makes sense.
Too often you see schematics,
especially on magazines, that have some obvious errors in them. The most reliable schematics are those
that have been drawn with CAD program and then turned into a PCB board and that somebody has actually built it.
When you see a working bord produced from a CAD design way without any patch wires, then you can think that the schematics is ok.
Unfortunately this does no really apply for one-offs and new designs, like on this page.
A visual check should also be performed checking that all solderings look alright and that there are no cold solderings. Re-melt all suspects.
Also check for solder beads and off cut component legs which are easily caught up between pcb traces and component legs during
manufacture.
Before connecting the power make sure the voltages are all right. Elementary, but so necessary.
If you have a lab power supply with current limit it often
makes senso to the set the limit close to zero and then carefully allow more current until the voltages are in the proper range.
If circuit takes much more current than what you expect you should disconnect it and find out the cause. If you are not using
a lab power supply with built in amp metere then measuring the current consumption requires that you can insert the meter in the
circuit, which is bother, if you did not have the foresight to allow for it.
On most hobby electronic circuits a finger test is usefull. Most of the parts
should not be running hot, and you can test this with you finger, they should just feel warm. Mind you, some power components
are designed to run hot, so do not burn you fingers!
And before you poke anypart of you body to any circuit make sure the voltages
levels are safe. Take care!
In this project you'll be using the power from your computers USB port, which is current limited. This is both good and bad.
It is good in
that it protects your computer and to some extent your circuitry. Its bad in that a maximum of 500 mA is available for your circuitry and actually, according to specification, only 100 mA is available unless your device requests it, which requires that your device is up and running and able to that. In any case you want to be carefull when connection your own stuff to the USB port as the repairs to the mother board are expensive (can you say 'I need a new laptop mother board').
Once you connect the power you can check some voltages with a digital Volt meter.
Make sure it is not in the Amp setting or you'll be
creating short circuits!
The HC908 IRQ pin needs to be 2.5 V above the +5 V supply voltage, at about 8 V, for the part to enter Monitor Mode.
The crystal oscillator pins OSC1 and OSC2 are at about half of the internal 3.3 Voltage, on mine the meter showed 1.8 V. Off course this does not prove that the oscillator is running, but if you do not have an oscilloscope that is the best you can do. If you do have an oscilloscope why not have peek to ensure that it is running at 6 MHz, producing sort of sine wave at about 1 Volt peak to peak amplitude.
All the HC908 pins with pull down resistors should be at 0 V and all those with pullups should be at about 3.3V, note that the pull ups must not be to +5V!
The HC908 internal voltage regulator output should show about 3.3 V. And remember to check that +5 V supply!
Always check the cables, industry is full of anecdotal evidence of engineers flying around the globe just to plug it in!
To check that your serial port works, download a terminal emulator, like Z-term,and set it up to use the serial port.
Type something, and if what you are typing is echoed on the screen, then you have a local echo On and you need to find out
where to turn it Offf. Once the echo is off you should not see on the screen what you are typing.
Now take a male 9 pin D-connector
and connect a wire between the RX (pin 2) and TX (pin 3) pins and plug it into the serial port. Now type something
and you should see what type echoed back on the screen.
Next remove the connector and plug in the bootload adapter to the serial port. Also connect the adapter to the target device as it takes its power from there, which also implies that the target needs to be powered up ie connected to the USB port.
You should now be able measure that the 8.2 V voltage is ok and that LED is on on the adapter, the that the serial RXTX line between the adapter and the target is at about 3.3V.
Now set the terminal emulator to use some low baudrate like 300 bauds and you should see the LED on the adapter to shimmer as you type something , try '@' sign because it has a lot of '0' bits and will thus be more visible on the LED than some other characters. You should also see with a volt meter that the TXRX signal fluctuates as you type.
Don't forget to quit the Terminal Emulator once you are through, otherwise the serial port will be busy and the bootloader cannot access the port.
You can learn something by trying the bootloader bl08. On the command line type
This will try to connect to the target and erase it.
If the seria port is busy or the port name is wrong or is not a serial port you should get:
Check that no other instance of the bootloader is executing (you can do this from the commandline with
If the adapter is not working or not powered up you should get the following error message:
Which indicates that when the bootloader sent out a byte it failed to receive it back which is what should have happened regardless of
weater the target is functioning or not. See above for basic serial port trouble shooting. This error is an indication that loop back
is not working and either your adapter is not working or the target device is holding the line.
If the adapter is working and powered up but the target is not responding you get:
Check that the condition for succesfull Monitor mode entry are present, these typically are that the IRQ pin is at +7.5 V or above, and that certain input pins have pull ups or pull downs. Check from the datasheet.
If you get
The the target probaply is ok as there was some responce but the baud rate was not correct. Check the baudrate you used against the device data sheet and the boot mode you are using, the baudrate depends on your oscillator speed and on some HC908 devices more than one baudrate is available and this is configred with one or more input pins upon reset.
If you get:
this is an indication that someone, most likely your target device, is sending stuff to the serial port.
Maybe you forgot to RESET it before you tried to bootload.
If you have done your homework and it still does not work you can always try some Freescale users forum or as a last resort email me!
cheers Kusti
|