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 HC08

Here 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:

  • Schematics
  • SDCC - Small Device C Compiler
  • Eclipse Downloads
  • bl08 - HC08 bootloader
  • Tiny printf page
  • MC68HC908JB8 Datasheet
  • MAX232A Datasheet
  • HC908JB8 PDIP-16 Pinout
  • MAX232 PDIP-16 Pintout

    Table of Contents

    Even 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 blink.c
    Understanding hello.c
    Understanding Makefiles
    Wading Through the Makefile
    Now you are on your own
    P.P.S. - Trouble shooting

    Introduction

    This 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 microcontrollers

    I 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 view

    I'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 microcontroller

    For 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:

  • C-programmable
  • DIL package
  • USB
  • Single chip
  • Minimal in-circuit programming adapter
  • Minimal external parts
  • Free tools
  • Simple, Elegant
  • 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-programmable

    Programming 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:

  • more tools
  • more people to ask for help
  • more sample code
  • more free code
  • better documentation
  • better understood idiosynchracies
  • less errors and bugs in the tools and language
  • more stable tools
  • more job opportunities
  • a future!
  • 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 C

    C 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 package

    In 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. USB Support I seem to go through PC hardware, meaning mostly laptops, at an alarming rate. Both privately and professionally. And coming from not-too-wealthy circumstances it pains me to see completely functional stuff end up at a landfill. So I dream of using them for something. This used to be easy with parallel ports and serial communication, but in recent years the computers, especially laptops, often come without any other ports than USB. So the days of parallel and serial ports are numbered.

    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.

    Single Chip

    Like I said, I've had great fun with HC11 but unless you can cram your code into 512 bytes you need to use external ROM memory for the program storage. It also requires at the very minimum an external reset circuitry and a clock oscillator or a crystal. This is not today's technology, I want something that has all in one chip. Not only will it help keeping the costs down but it also reduces the complexity.

    In-circuit Programming

    Long gone are the days when we erased EPROMs with UV-light and 'burned' them in a prom-programmer, and that is good. Today's microcontrollers, especially in a hobby project, should be programmable in-circuit. And without an expensive in-circuit programming adapter, too. I can dish out 300 USD for a evaluation kit that includes the adapter, but I don't want to! I prefer something simple that can be hooked to a serial port more or less directly. Or better yet, since I wanted to have USB anyway, it would be ideal to program it through the USB connection as well. I guess this is the long term view again: while I can spend the money on professional gear, what if my efforts are something that some other hobbyist wants to try too? Their situation maybe completely different, think of students and schools for example.

    Besides doing it from the ground up just is the way I do things!

    Free Tools

    Let me state that I'm not a Free Software advocate but at the same time I see that there is a lot of sense in it and some of it is actually darn good.

    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!

    Used by the Professionals

    Maybe I'm biased, but I would not like to use something that is inferior to what the professionals use. This is not snobism, it is just that I expect the pros to have done their homework when selecting their tools and chips. And, more importantly, it is their choices, not the hobby market, that will keep the tools and chips alive.

    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.

    Mac Evangelism

    Now, I know the following is going to sound stupid and stubborn, especially coming from a guy who runs Windows XP and three Linuxes under Parallels on Mac OS, but I can't help it: I want to do my embedded development under Mac OS X. I know, it limits your options, it is more work, it makes no sense, but its great fun.

    Integrated Development Enviroment

    I'm not a great fan of Integrated Development Enviroments (IDEs) - a good editor, C-compiler and a Makefile leaves little room for improvement. Now, let me qualify that I'm not big fan of proprietary vendor specific IDEs such as CodeWarrior or VisualDSP. They are all the same, only different, that is the problem. They all have more or less the same features, but implement them slightly differently making me re-learn all that stuff. And when you see one vendor doing a better job in one area it makes you really frustrated to use the poor imitation, until you realize that the better one does a poorer job on some other stuff. That's when I really get frustrated.

    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 Issues

    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.

    Which Microcontroller - Finally getting to it

    At first it would seem that there is the proverbial embarras de richesses but given my constraints above it actually boils down to a few choices. Of course, I do not claim to have a complete picture of the ever-changing microcontroller landscape and may have missed new entrants, especially as I started this 'project' some years ago. Which sort of proves my point about requiring something that can be whacked together in one weekend and has a future!

    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:

    Microchip PIC18F2455/2550/4455/4550 family

    Microchip seems to be very popular among hobbyist, but I haven't very often seen it in professional use. I secretly suspect that the major reason for their success is that they offer so many of their devices in plastic DIL packages!

    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.

    Silicon Labs C8051F3XX family

    Silion Labs has some very innovative chips and I actually have two chips on my table as I write this. The C8051F3XX family is based on the well-known and widely supported 8051 instruction set and besides USB it has 16 kB Flash and 1024 bytes of RAM and requires no, none, zero external components, not even a crystal. Even if Micochip datasheet explains that it is impossible to 'do' USB without a crystal oscillator, it seems that Silicon Labs can do it. Now that is what I call an integrated solution!

    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.

    MC68HC908JB family

    By chance Motorola (now Freescale) MC6800 and its siblings and descendants were one of the first microcontrollers I learned and the 68HC08 family is a sort of upgraded/downgraded descendant of it. The evolution of the 68XX family would make for an interesting pondering but I won't do it here, suffice to say that the 68HC11 that once looked like the future is now considered an evolutionary dead-end mutation.

    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.

    Building the Hardware

    To start having fun with HC08 you need just two micro chips, crystals and a dozen or so other components. The hardware setup presented here is very much like many others out there and not unlike those on the Application Notes for HC908. I'm mainly repeating the information here for my own reference, there is nothing special about this setup, but if you are new to this the notes may help you get going, after all the datasheet is almost 300 pages long, with a half a dozen application notes thrown in!

    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

    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.


    The Microcontroller

    The microcontroller I've used is pretty much self-contained. To function it needs just a few bypass capacitors on the power supply lines, an external crystal for the oscillator and one or two pull up/down resistors to configure the Monitor Mode entry.

    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.

    Setting up the Software Tool Chain

    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 'sdcc'. The full path on my Mac is then '/Users/nyholku/sdcc' and the actual compiler is at '/Users/nyholku/sdcc/bin/sdcc'.

    Scary stuff - the command line

    Next we will venture to the dreaded world of the shell / comman line interface, but don't worry, I won't leav you hanging there, but I do think it is usefull to know this side of life too. If you are a complete novice to the command line I suggest you read my Linux 101 for Dummies which covers the basics.

    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 'PATH' so that 'sdcc' directory is always searched for commands whenever we type the name of a command. In this way instead of typing

    /Users/nyholku/sdcc/bin/sdcc

    we can just type

    sdcc

    to invoke the C compiler. This needs to be done before we start the Terminal for it to take effect. To modify the 'PATH' in Mac OS X you open the file '.bash_profile' in your home directory and add the following line. Your home directory is the folder with your username inside the 'Users' folder. So open the file and add the following line at the end:

    export PATH=${PATH}:~/sdcc/bin:~/bl08

    If there is no such file, create it.

    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 'open .filename'.

    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 /Applications/Utilities and to start a session just double click it.

    After firing up the terminal you should see something like:

    Now to just see that the 'path' setup was succesfull type

    sdcc

    and you should something like

    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 :-

    and about a hundred lines of other helpfull text. If you get something like

    -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 'bl08' in your home directory.

    To compile it you type the following:

    cd ~/bl08 gcc -o bl08 bl08.c

    This should complete silently in about a second and you should see, with 'ls' command, that there is now a brand new file called 'bl08' in your current directory.

    Your very first microcontroller software -- Blink LED

    Now we are all set up to compile and execute our first program, the embeded world equivalent of the all time classic first program, "Hello World".

    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:

    data at 0x00 volatile char PTA;
    data at 0x04 volatile char DDRA;
    data at 0x1F volatile char CONFIG;
    
    int main(int argc, char** argv) {
            CONFIG=0x01; // Disable COP
            DDRA=0x03; 
            while (1) {
                    unsigned int i;
                    PTA ^= 0x03;
                    for (i=0; i<50000; ++i) 
                            PTA;
                    }
            }
    

    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 '~/hc08demos/blink' directory with:

    cd ~/hc08demos/blink

    And finally we can compile it with:

    sdcc -mhc08 --stack-loc 0x013F --code-loc 0xDC00 blink.c

    This should silently produce, without any error messages, a bunch of files in the current directory, which you can verify with ls command. If you made any typing errors, the compiler will output error messages on the console/terminal along with the line numbers of the offending lines. Take your cue from there, go to your editor and fix them.

    Among the files produced there should be one named 'blink.S19', which is the actual machine code we have just compiled our C program to. The file is in what is known as S-record format, and basically it is just a textual representation of the 1's and 0's, in hexadecimal numbers, that we want to put into the Flash memory. If you want, you can open it with a text editor and see the hexadecimal stuff but there should be no need to do that.

    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

    This will produce a long list of devices, something like (I've shortened the listing from both ends to conserve some screen space):

    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 we look for something with tty. and USB in it, and there it is, on the second column, last line but one, 'tty.usbserial-FTOXM3NX'. In Linux the serial port is often called '/dev/ttys0'.

    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

    If everything goes as planned we should see something like:

    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

    And the LED on our board should start blinking at the rate of about once a second!

    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 'blink.c', which the C compiler SDCC compiles first into assembly language and then into a relocatable object code file. A relocatable object file contais machine code that has not yet been positioned in memory and which may contain references to subroutines and variables in some other, separately compiled, relocatable file. The process of positining the code in memory and resolving and patching those references between files is called linking, and is the final step before we get the final loadable and excecutable file blink.S19.

    All this takes place when we give the command 'sdcc ...' illustrated in the diagram.

    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 bl08, which loading takes place when we issue the command 'bl08 ...' illustrated in the diagram.

    Moving On - Hello World

    While a blinking a LED is a nice and necessary first step , what we realy need next is an ability to debug our 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 'printf' facility that allows you to output whatever you need, whenever you need.

    We are going to do the classic 'Hello World!' program, finally!

    Doing that is pretty simple, create a directory named 'hello' inside the 'hc08demos' directory, and make it your current directory with 'cd ~/hc08demos/hello' command. Rember that all this stuff can be downloaded so you do not need actually do this manually.

    In to this directory copy two files, 'printf.c' and 'printf.h'. You can get these files and read more about them from this page but right now you do not need to. Yes, there is a 'built in' printf which comes with SDCC but mine is a pure C, light weight version, and I wanted to show off here!

    Now create and type in the following code and save it under the name 'hello.c' in the same directory:

    #include "printf.h" 
     
    data at 0x00 volatile char PTA;
    data at 0x1F volatile char CONFIG; 
    
    
    void putchar(char x)  {  
       (void)x;  
    _asm 
            bclr #0,_PTA 
            jsr 0xFED6
    _endasm; 
    } 
    
    int main(int argc, char** argv) {
            CONFIG=0x01; // Disable COP
            while (1) {
                    printf("Hello World, this HC08 talking!\n");
                    }
            }
    
    
    

    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 '-c' option on the command line. Because the compiler generates code to set the stack pointer, the compiler needs to know the stack location and we thus pass initial stack pointer value using the '--stack-loc' command line option. On HC08 architecture stack grows downwards, so we pass the address of the top of the available RAM memory here. If you have an other variant of HC08, look it up from the datasheet.

    The last line links the two previously compiled files, 'hello.rel' and 'printf.rel' together to produce a loadable code module 'hello.S19'. To do this the the linker needs to know where to put the code so we pass this info to it using the '--code-loc' option. This is typically the lowest address of the Flash memory, again refer to the datasheet.

    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 Makefiles.

    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 make to automate this.

    Mac OS X supports make out of the box so there is nothing to install, and so do most Linux distros, in Cygwin you need to install the C-development tools but I won't be covering that here.

    To use make you create a file named Makefile into which you put rules that tellmake how to compile and link your project. You then invoke make by typing make and, well, that is it, it compiles and links your program, it is even clever enough to compile only those files that need to be compiled, a big bonus in project where a full build may take hours or days!

    Using make is something that all C-programmers should learn to use and should use, none of your infernal IDE specific managed builds that you have no control over. Make is universal and transportable accross operating systems and very popular so it is worth investing a few minutes in the basics.

    So create the following 'Makefile', note the Capitalization, in the 'hello' directory:

    
    
    SDCC = ~/sdcc/bin/sdcc
    
    OBJS =	hello.rel printf.rel
    
    LIBS =
    
    TARGET = hello
    
    SDCCFLAGS = -mhc08 --stack-loc 0x013F --code-loc 0xDC00 --disable-warning 85
    
    %.rel : %h
    
    %.rel : %.c
    	$(SDCC) -c $(SDCCFLAGS) $< -o $@
            
    $(TARGET):	$(OBJS) Makefile
    	$(SDCC) $(SDCCFLAGS) -o $(TARGET).S19 $(OBJS) $(LIBS)
    
    all:	$(TARGET)
    

    Once you have the makefile in place you can 'make' it by just typing:

    make

    Which should result in the very same commands to be executed and displayed on the Terminal as you what you would have entered yourself manually.

    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 built in Terminal Emulator, so that we see what our little beast is outputing to us:

    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 'hello' program, refer to the diagram below:

    This is quite similar to what we did with the 'blink' software, only this time we compiled our 'hello.c' program and the print functions it uses from 'printf.c' separately via the two 'sdcc' commands and finally we linked them together using the 'sdcc' the third time, as illustrated in the diagram.

    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...

    Real Programmers Do It with Eclipse

    To download Eclipse surf to http://www.eclipse.org

    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 'Eclipse' which you can then copy where ever you want to keep it.

    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.

    Creating a Makefile based C project in Eclipse

    Create a new C project from the "File/New/C Project" menu and in the 'C Project' dialog that opens do the following:

    Into the 'Project name' entry field enter a name for the project, call it 'hello'.

    Uncheck the 'Use default location' check box.

    Into the 'Location' entry field enter

    '/Users/nyholku/hc08demos/hello'

    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

    From now on, that is all it takes to build you project no matter how big it gets.

    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

    '/Users/nyholku/bl08/bl08'

    Into the 'Working directory' entry field enter

    '${workspace_loc:/hello}'

    Into the 'Arguments' entry field/box enter the same command line parameters we used when we did this from the terminal, i.e.

    '-c /dev/tty.usbserial-FTOXM3NX -k -b 9600 -t jb8 -x 12 -f -g reset -m hello.S19'

    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!

    Understanding the Code

    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.

    Brief Intro to Memory Mapped I/O

    Some processors have special instructions for doing output but much more typical is the use of so called memory mapping. Memory mapping simply means that the hardware is so wired that writing to a particular memory address will cause some action to take place in the hardware. Typically there is a hardware latch or register attached to that address and the outputs from that register control various things such as output port pins.

    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.

    7 6 5 4 3 2 1 0

    To SET, CLEAR, TOGGLE or TEST a bit in any memory mapped REGISTER look up the bitmask from the following table:

    bit no B7 B6 B5 B4 B3 B2 B1 B0
    bit mask 0x80 0x40 0x20 0x10 0x08 0x04 0x02 0x01

    (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:

    What How Example Comment
    SET REGISTER |= bitmask PTA |= 0x80; Set the highest bit of Port A to 1
    CLEAR REGISTER &= ~bitmask DDRA &= ~0x01; Clear the lowest bit of Data Direction Register A
    TOGGLE REGISTER ^= bitmask PTA ^= 0x10 | 0x08; Toggle the two middle bits in Port A
    TEST REGISTER & bitmask if (PTA & 0x40) Check if the bit 6 in Port A is set

    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.

    What follows is a blow by blow treatise of the code.
    data at 0x00 volatile char PTA;
    

    Lets rip this line appart and see what each part says:

    char PTA

    This defines a variable of type char giving it the name PTA.

    For most purposes you can equate 'char' as byte in your own mind, with the integer value in the range -128..127.This is not the full story but let is stand like this for this discussion.

    data at 0x00

    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 'data' tells the compiler to place this variable in data (RAM) memory which is the sort of memory that will loose it's contents when the power fails, as opposed to code (ROM) memory which is retains it's contents without power. The 'at 0x00' tells the compiler not to decide where to put the variable but to put it at the given address '0x00'.

    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.

    volatile

    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 volatile.

    Quite a lot of information we learned from the first line!

    data at 0x04 volatile char DDRA;
    data at 0x1F volatile char CONFIG;
    

    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.

    int main(int argc, char** argv) {
    
    This line defines a function called main which is where the execution of the code starts. It looks rather complex, but you do not need to really understand what it says, every C program should have one and only one main function and it should look exactly as it is here. Whenever writing code, just copy/paste it from here.

    Note the '{' or opening brace, in C the statements that make up a function are closed within braces, as are statements that we want to group together. If you look at the last line of the code you'll see the matching closing brace '}'.

            CONFIG=0x01; // Disable COP
    
    This line turns off the watchdog feature in the HC908JB. Any computer may get hungup or start running wildly because of a glitch, alpha particle, design error or software bug. In those situations someone has to press the reset button. This is where the watchdog, or as the datasheet wants to call it, Computer Operating Properly (COP) feature kicks in. It is a simple circuit that detects that the software is running wild or hangup by seeing that the COP register has not been cleared for a while, in which case the watchdog will reset the whole microcontroller.

    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.

     DDRA=0x03; 
    
    The name DDRA stands for Data Direction Register port A and it is a register that controls weather each of the eight pins in the port A are input or outpus. For each pin in the device and each bit in the PTA port there is a corresponding bit in the data direction register. Writing a 1 bit into any of those bits will turn the corresponding port pin into an output.

    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 'DDRD |= 0x01 | 0x02;'. Mayby I should have used it, now I'm teaching bad habits here.

            while (1) {
    
    Here is what a typical microcontroller main program looks like, this is a loop that loops forever, after all, what would the microcontroller do once it finishes its task? Wait for disposal? No, it keeps waiting for more of the same stuff to do.

    Note the opening brace '{' and the matching closing brace '}' five lines down, which define the loop body i.e. those statements that are looped while the condition is true, which in C is anything that is not zero.

                    unsigned int i;
    
    This line defines a local variable 'i' which we will be using a few lines later to waste some time by looping doing nothing.

    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 unsigned int giving it the numerical range of 0..65535 as oposed to normal signed int, which has only the range of -32768..32768, which was rather small for the delay I wanted here.

                    PTA ^= 0x03;
    
    This line toggles the Port A bits B0 and B1 in effect turning On or Off the two LEDs in our circuitry.
                    for (i=0; i<50000; ++i) 
                            PTA;
    
    These two lines form a loop that will increment the value of our local variable 'i' from 0 to 50000, executing the rather obscure statement PTA each time.

    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 'i' is never used anywhere outside the loop and it would have been quite legitimitate for the compiler to optimize it all away.

                    }
            }
    
    These are the closing braces that end the while loop and the main function.

    Understanding hello.c

    #include "printf.h" 
    
    Every non trivial program should be broken into smaller chunks for maintainabilety, managabilety and sometimes for re-use, be it that re-use is the wholy grail of software development that often is best not persued. Every seriour programming language also provides someway of organizing the code into separate chunks. In C the facility is not very elegant or sophisticated, but it is effective and powerfull, ugly but matches the style.

    This facility is called the '#include' preprocessor directive which effectively inserts the given file in that place of your source code.

    Here we are including the file 'printf.h' which includes the public declarations of the functions and variables in our printf library. As I said before there is also a standard printf function that you can use, in which case you would be including the standard header file stdio.h here. See any tutorial text on C for details.

    data at 0x00 volatile char PTA;
    data at 0x1F volatile char CONFIG; 
    
    This is the same stuff as in the blink code above.
    void putchar(char x)  {  
    
    Here we define and declare, to be grammatical, a function named putchar that takes one argument (the char x part), a character to output, and returns no value (the void part). This function, or actually it is a subroutine because it returns no value, is needed and called by the printf facility to output a character to terminal.

    How did I know I needed to provide this?

    Well, I read the documentation in the 'printf.h' file, that's how.

       (void)x;  
    
    This line is not necessary and has no function, but nevertheless I explicitly wrote it with some pain!

    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 'x' is never used, and it complains with a warning. The compiler is within its rights to complain but the code is correct so I need silence the compiler to satisfy my 'no warnings' rule.

    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 'x' casting away the value to void. In practice the compiler will then optimize this away so the line produces no code, but this usually prevents the compiler from complaining, because I've 'used' the variable.

    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.

    _asm 
            bclr #0,_PTA 
            jsr 0xFED6
    _endasm; 
    
    These lines insert what is known as inline assembler code. To understand it, quite a lot of background in assembly language is required, so I won't try to explain it in detail here.

    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' (bclr #0,_PTA) and then 'call suboutine at address 0xFED6' (jsr 0xFED6).

    This addresss (0xFED6) is within the HC908JB8 factory programmed mask ROM memory and contains a handy routine that will output a character in the accumulator A through port A pin 0 using standard async protocol at 9600 baud, which is quite a handy routine to know about, because this particular model of HC908 has no serial port!

    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.

    } 
    
    Thats the closing brace for the 'putchar' function.
    int main(int argc, char** argv) {
            CONFIG=0x01; // Disable COP
            while (1) {
    
    All this is same stuff as in the blink code above.
                    printf("Hello World, this HC08 talking!\n");
    
    And this calls the printf function from our 'printf.c' file passing it the 'Hello..' text as argument.
                    }
            }
    
    I guess you know these by know.

    Understanding Makefiles

    The whole make system is actually quite complex but you can master the basics in just a few minutes, there is no need to set out to learn it all, just learn as you go.

    Simply put, make system is a program called 'make' which when executed reads 'make rules' from the file named 'Makefile' in your current directory.

    The basic form of a make rule contains two lines of which the second one is indented and it looks as follows:

    
    hello.rel : hello.c hello.h
    	sdcc -c -o hello.rel hello.c
    

    This describes a dependency between three files , saying that if either of the files on the right side of the colon, hello.h and hello.c, is changed, then the file on the left side of the colon, hello.rel, needs to be rebuild. To second line is the command that is used to rebuild that file.

    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:

    
    %.rel : %.c
    	sdcc -c $< -o $@
    
    Basically this rule says that every '.rel' file depends on the corresponding '.c' file. And on the second line we use the '$@' to refer to the 'left' side of the dependency rule and the '$<' refers to the file on the 'right' side of the dependency. Simple realy.

    Often you encounter a generic dependency rule that has no second line, like:

    
    %.rel : %.h
    
    In this case it just describes the dependency but the commands to rebuild need to be found from some other dependecy rule that pertains to the file in questions. This makes sense, you do not want a file to be built twice, no point in that, and also you do not want to create opportunities for inconsistencies by having the actual build commands in two places.

    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 make. If you specify nothing on the command line 'make' defaults to the phony target 'all'.

    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.

    Wading Through the Makefile

    So now we are ready to walk through our very own 'Makefile':

    
    SDCC = ~/sdcc/bin/sdcc
    
    Here we create a macro named SDCC so that when ever we need to refer to our C compiler we do not have to type all that long path name, and, more importantly, we now have just one place where to change it if the location changes. Also, using a full path to the SDCC executable here makes it unnecessary to set the enviroment 'PATH' correctly when running this make from within Eclipse.
    
    OBJS =	hello.rel printf.rel
    
    Here we create a macro 'OBJS' to hold all the names of all those relocatable files that our program consists of. Every time you add a new 'file.c' to your project, you add 'file.rel' here. This makes it simple to add new files to your project. That is all there is to it, well, almost.
    
    LIBS =
    
    An other macro 'LIBS' is created here that holds all the libraries that we want to link into our program. It needs to be separate from our own program files because typically we do not have source code for these and thus cannot or do not want to build these. In our example we have none.
    
    TARGET = hello
    
    By using '$TARGET' in our make file instead of just typing 'hello' I have abstracted the name of our main target so that it is easy to change. Changing project names is sometimes necessary but can be a royal pain, I've yet to figure out how to do that on Visual Studio!
    
    SDCCFLAGS = -mhc08 --stack-loc 0x013F --code-loc 0xDC00 --disable-warning 85
    
    All C compiler support hundreds of options to tweak this and that, so to keep our makefile managable it makes sense to use a macro to hold these parameters.
    
    %.rel : %h
    
    This is the rule that says that any relocatable object file '.rel' depends on the corresponding '.h' -file. This rule has no commands because the actual commands will be found from the rule for the actual source code files, just below.
    
    %.rel : %.c
    	$(SDCC) -c $(SDCCFLAGS) $< -o $@
    
    This is the actual rule that compiles all our C programs files. See how the use of the two macros SDCC and SDCCFLAGS makes this much shorter.
    
    $(TARGET):	$(OBJS) Makefile
    	$(SDCC) $(SDCCFLAGS) -o $(TARGET).S19 $(OBJS) $(LIBS)
    
    And this rule finally puts it all together saying that if any of the files that make up the program has changed, including this 'Makefile', then rebuild our program by linking all the files together. See how the macro 'OBJS' makes life much more bearable, already on these two lines we have used it twice, imaging what a maintenance nightmare if would be without a macro, when someday we have dozens of files in our project.
    
    all:	$(TARGET)
    
    And finally, this makes use of the defaul phony target 'all' so that we can just build the whole thing by typing 'make'.

    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 '#include' directive, another file, making it dependent on that file too and requiring a recompile if any of these files changes.

    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:

    
    hello.rel : printf.h 
    
    Much as I hate this phrase: "I have left this as an exercise to the reader".

    It is also customary to have sort of 'utility' phony targets in make files like:

    
    clean:
    	rm *.rel
    	rm *.lnk
    	rm *.S19
    	rm *.map
    	rm *.mem
    	rm *.asm
    	rm *.rst
    	rm *.sym
    	rm *.lst
    
    The compile process typically leaves a lot of intermediate files around and I, for one , want to keep my directories clean, so I include a clean-up target like above which allows me to delete all non essential files from the project with a simple command 'make clean' before I archive or backup it.

    Now you are on your own

    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


    P.S. - Full schematics

    Here are the full schematics I promised, click for a printable size.

    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 bl08 to automatically reset the microcontroller before downloading, saving you from the trouble!

    Just add the following option to the command line:

    -r 1000

    This will toggle the DTR line for 1 second or 1000 milliseconds before the download begins.

    P.P.S. - Trouble shooting

    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.

    Some general hardware related trouble shooting tips

    I usually take baby steps anyway, even if I think I could just wire and fire it up and get it to work. Taking it step by step brings familiarity and confidence which always helps.

    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!

    Some serial port related trouble shooting

    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

    bl08 -c /dev/tty.usbserial-FTOXM3NX -b 9600 -t jb8 -e

    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:

    Failed to open seria port/dev/tty.usbserial-FTOXM3NX: No such file or directory

    Check that no other instance of the bootloader is executing (you can do this from the commandline with 'ps -A' command that will list all running processes, if you see one, make a note of the process id number and kill it with kill processid). Also make sure that some other application is not using it. And of course make sure the drivers are properly installed.

    If the adapter is not working or not powered up you should get the following error message:

    Serial port failed to receive a byte, read returned 0

    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:

    Loopback failed, nothing was received

    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

    Loopback failed, sent XX, got YY

    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:

    Unexpected data from serial port: XX

    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