Here is a nice little project for a rainy weekend, all this can be accomplished over a weekend and for under USD 15. TROUBLESHOOTINGTROUBLESHOOTING
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 firts part.
For references purposes and convenience I've put all the usefull links here at the top of the page:
Eclipse SDCC printf bl shcematics bill of materials kivoja kuvia adapter photo pinouts overall setup the compile process
This page is aimed at beginners. While a microcontroller project is maybe not 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.
Lot's of people are interested in microcontrollers, witness 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 many senses of the word. While I'm not always forward coming on own motivations, I at least try to be honest with myself. A lot of people site vaguely that they want to learn to 'do microcontrollers' or 'learn a new programming language'. These are as good reasons as anything but I suspect that behind these sentences there are some further aiming dreams or ambitions. Search 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.
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 house electric consumption, 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.
Micro controller is a sort mini computer with a central processing unit or CPU, some memory and some peripherals or input output devices. Lets face it, analog circuits and logic chips just are 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.
I'm a professional programmer involved in designing embedded system daily for the past quarter of a century, almost as long as they've existed. I also enjoy tinkering with these things on 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 a lot.
Learning new stuff, like microcontrollers, is fun but it also an investment. An investment on your self and your future. Like any investment it requires spending on 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 be careful what we do with out time. Like with any investment it is natural to expect some return from it 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 want's to see their investement go bust so it pays to invest carefully. Worries like 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 pomppus, talking like that in the context of a hobby project, but as one lives one learns and I'v seen so many one-off temporary projects, both hardware but especially software to live well beyond the wildest expectations of their creators.
Bet you anything that those guys writing Unix code more than fourty years ago had no idea that a lot of this code would still be running be tooted as the most advanced operating system available today: Mac OS X!
I've found playing wit microcontrollers both rewarding and fun and it has even paid my mortage but it surely has taken a big chuck of my life.
Ok, so let's see where this sort of thinking has lead me and why. I'm not putting these forward as the only right way of going about it, just sharing my views. Besides, I reserve the right to be corrected and revise my opinions. If your still reading, remember, that it sometimes pays to listen to others who've been-there-done-hat, but should examine yourself and find out what it is that you realy want to do. It is your project and your life.
For years I've been looking for a suitable microcontroller that would fulfill my self imposed constrains. In the past me and 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 for when compared to more modern offerings with internal Flash and what not.
Here is my list requirements for a microcontroller:
Interestingly this list is always almost the same regardless of what I am contemplating to do with it, pretty much like my cooking really, first I take a pound of butter, bowl of sugar, a pint of cream , half a dozen eggs and then I start to think what to cook and eat! In the following I'll discuss these to give a beginner one view of these matter, note that there are many views, none of which is absolutely correct.
In the following I'll discuss my views on each of these to some length.
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 an a larger scale. So we need something higher level that allows us to think in more abstracts terms than boolean logic and flip flops which are the building block of microcontrollers.
We need a programming language.
Now there is something about programming languages that make 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 seem center around technical characteristics or philosophical issues about why one programming language is better than an other. While certainly there are differences and one can put forward well founded arguments for various aspects of in different languages, I find that this sort discussion is centered around the wrong questions.
The question is not about which programming language is best but which one you should use and thus learn.
All the programming languages are pretty much the same. And how could they be different, 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! Surely there are differences and some languages are better than other, but essential difficulties of programming are not likely to be solved with a programming language, any programming language, any time soon! If it had been I'm sure it would have been solved already, just look up the +2000 programming languages in 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 in it. And there is safety in numbers, bringing me to my pet long term view theme.
When there is a large user base you get:
As often in life, it pays to take the middle road.
Yes, it is a vicious circle that ties us to design decisions done decades ago but there is no escaping the past if you have the future in mind. Now isn't that ironic!
C has never been my favorite programming language yet both professionally and for hobby it is the only choice I can think of when talking about small microcontrollers. The tools and the language are mature and standardized, even 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 special place in my heart, it was the first language I learned and it still has certain appeal in its simplicity and eas 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 have the linker and assembler ready, and the compiler ticking, but fortunately I came to my senses before I wasted any more time on it.
Talking of BASIC what BASIC are we talking about? ANSI BASIC, or some proprietary product?
The original Darthmouth BASIC (born in -64 like me) was a very simple language that contained all the basic building block 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 the people who can , the language and tools will be here in twenty years time when me or or somebody else needs to get back and tweak the software. Imaging getting an old BASIC program to play ball in ten years time. And this is need to tweak is not 'if', this is '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 on 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 language which 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 so far as making the language and the 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-learn a new programming language when the competition is bound to offer something that can be programmed with C.
Before I wind up this rather long and most likely boring section on programming languages, I can't help mentioning project Arduiono. Everyone interested in getting into microcontrollers should check it out. Although I think the idea of having yet and other 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.
On the left you two MC68HC908 chips with a 20 SNT coin and a 1/4 W resistor for size reference. The left one is a GZ16 in 32 pin LQFP package and the one on the right is JB8 in a 20 pin PDIP package. You can click on the image for larger view.
You can solder some SMD packages on a modified owen or you can do what I've done is I've soldered 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, also those that you could just have 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 projects that for the time being as run out of steam, tucked away shamefully into a far away corner of my hard disk.
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 moneys 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.
So, one of the key requirements is DIL packaging.
So what's this got to do with microcontrollers? Well, so many of my ideas would be best implemented so that the low level real time stuff is done on the microcontroller but the rest, like networking, storage and user interface, on a proper computer. Yes, I've seen weather stations that boast a web server a match box size PCB but for me using that old laptop on 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 is 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 learn to 'do' USB.
Besides doing it from the ground up just is the way I do things!
Many chip vendors and tool vendors provide free (as in free beer) version 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 catch somewhere, like you can use only 32 files and 1 kB code per file and max 4 kB code. Of course market pressures and strategies seem to force the tool vendors to offer more and more free stuff and relax the cripling to lure customers but at the end of the day commercials tools are at the mercy of their business decisions. Companies get sold, merged, whole product lines get side tracked 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 affordable prices.
Taking the long term view if at all possible within the other constrains 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 have support things like 8051 but that has been effectively dropped for the time being. And it maybe that this is the way it is going to stay as there maybe a fundamental conflict between 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 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 an other one!
Interestingly it is the consumer market that in turn drives the professional markets! We are all hobbyist when it comes to snapping photos with our IXUSes and its the development of the consumer gears which definitely drive the chip development.
When I use an IDE I want to use the same IDE for everything, not change it as I jugle between project, or as the case maybe, when the IDE company is busted or gets sold. Ask any CodeWright user if you want to hear more rant in this same vane. 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, like 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 thinks 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 leave little to be desired for, the seach and code navigation tools are great and work like breeze. It has large user space and available for all major platform and support many languages. Vibrant and kicking.
And with the CDT plugin it now is a viable C/C++ environment. True, the re-factoring, build and search tools for C/C++ are not yet quite as good as for C/C++ 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 bestinated for a great future, which is all important.
Cost as such is not a big issue, for one-off project it makes a little difference if a chip costs 2 USD or 40 USD, but then there there is the co-later damage, investment in learning and using what you've learned.
If you learn to use a 40 USD part you are likely to use it again and again and if you invent the next big mouse trap the 40 USD part may make or brake the project. And needing to re-learn something as complex a new microcontroller is sure to put the brakes on for some time, at least for the hobbyist.
By know you should see, even if you may not agree, why BASIC Stamp and PICAXE were not even running in this competion.
My short list of candidates for a microcontroller was:
The older PIC families had definitely weird and unfriendly architecture that made them unsuitable for other than assembly language programming or using their special version of BASIC. The later 18F serias 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 hvae actually put in an order for some samples, so maybe I'll be reporting back on it in a year or two.
Since I've not used it I cannot say what it takes to program it in-circuit as I want to do, but surfing the web you see a lot of options software wise.
Talking about crystal oscillators, while a crystal and the two caps plus resistor required by most chips are no big deal they can cost more than the microcontroller!
Unfortunately it is not available in a DIL or PDIP package which means that I need to get an adapter board or design a PCB. No wonder those chips have been on selv for two years now.
Also the in-circuit programming via the C2 one wire interface sort of put me off because you cannot directly generate from a serial or parallel port the sort of signaling it requires.
68HC908JB is available in a 18 pin PDIP package, which limits the number of I/O available and it does require an external crystal, but it supports USB and has 8 kB Flash and 256 bytes of RAM.
In circuit programming is possible with the one wire serial communication based monitor mode which is easy to implement with standard serial port an any PC.
MC68HC908JB8 is also the cheapest of the lot a 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 industry standard core with minimal external circuitry with fast clock speeds and more than adequate memory sizes. For hobbiest the PIC18 family seems very atrractive 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 realy 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 seem 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 carefull the get the right part as this is the only variant available in PDIP package. Note that now days 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 replament
The hardware is realy rather simple, anyone should be able to solder it together on a Vero board it 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 you can rip from an old PC. Speaking of the USB connector, a good solution is not to have a Device connector at all but to take regular USB cable, cut away the Device end and solder the wires directly on to the vero board.
The hardware consist 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 as we'll be using well below 30 mA here.
The bootload adapter converts the voltage levels of your serial port to match those required by the microcontroller and it allows you to download software into the microcontroller and also 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 schematic scroll to the bottom.
The bootload adapter is just a MAX232A and a diode that perform a logical OR funcition 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 a 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. On the left you cas see a picture of my adapter.
Below you'll see the Vero-board layout I drafted for it (click the images larger view). I do no usually go to the trouble of drawing a layout but I wanted to make sure I did not run out of space as I wanted this to fit into my nice box.
It is also nice to have an LED so that there 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 usefull and conforting.
Below are the schematics for the micro controller. I've not included any actually peripherals at this stage to keep the schematics simple, you are sure to find plenty of examples from the web how to connect LCD displays, stepper motors, relays or whatever you fancy to put there.
I constructed mine on a Vero-board, see below, in about two hours with just the schematics as a reference. If you are inexperienced it might make sense to draft a layout plan first.
For the software you need a C-compiler to compile your programs into machine code and a bootloader to downloadd and 'burn' the machine code into the microcontrollers internal Flash memory. For anything larger than a single file test program I highly recommend using automake (or 'make' for short) 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 realy stream lined 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 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 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'
.
In the following when I write 'type' it means that you should type in from the keyboard the line exactly as it is and end the line by pressing the ENTER key on your keyboard.
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 Eclipse but your favourite editor, your minute by minute routine is going to be something like 'edit code, type make' over and over again. 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, should work almost verbatim. Much of this applies to pure Windows as well, but I won't be covering all platforms here.
We are going to fire up the Terminal to get access to the command line but before we do that we do a litle tweak that will lessen the amount of typing we need to do. We will modify the
/Users/nyholku/sdcc/bin/sdcc
sdcc
export PATH=${PATH}:~/sdcc/bin:~/bl08
'PATH'
so that 'sdcc'
directory is always searched for commands whenever we type the name of a command. In this way instead of typing
we can just type
to invoke the C compiler.
This needs to be done before we start the Terminal so that it will 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:
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 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.
Now, 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
SDCC : mcs51/gbz80/z80/avr/ds390/pic16/pic14/TININative/xa51/ds400/hc08 2.7.4 #4988 (Jan 9 2008) (Mac OS X i386)
Usage : sdcc [options] filename
Options :-
-bash: sdcc: command not found
and you should something like
and a about hundred lines of other helpfull text. If you get something like
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'
commmand that
there is now a brand new file called 'bl08' in your current directory.
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. By the way, this is the way professional bring up prototype boars, 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 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 them to make them look pretty.
goto the '~/hc08demos/blink' directory with:
cd ~/hc08demos/blink
sdcc -mhc08 --stack-loc 0x013F --code-loc 0xDC00 blink.c
And finally we can compile it
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 line numbers of the offending lines. Take you 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 want you can open it with a text editor and
see the hexadecimal stuff but there should be no need to do that.
Almost there, 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 serial port connected to the bootload adapter, and the USB cable connected to the target and your PC to supply 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 comes with a serial port so if you are trying this out on a Mac you need to have a USB serial port adapter.
Don't forget to install the drives, see the adapter manual for that. The manual also probaply tells you the name of
the device but you can easily find it out your self so it is worth learning an this applies to Linux and Cygwin aswell, just type:
ls /dev
ptyqe tty ttyv2
ptyqf tty.Bluetooth-Modem ttyv3
ptyr0 tty.Bluetooth-PDA-Sync ttyv4
ptyr1 tty.Kusti-Dial-UpNetworking-1 ttyv5
ptyr2 tty.Nokia3110c-Dial-upnetwo-2 ttyv6
ptyr3 tty.Nokia3110c-NokiaPCSuite-1 ttyv7
ptyr4 tty.usbserial-FTOXM3NX ttyv8
ptyr5 ttyp0 ttyv9
This will produce a long list of devices something like (I've shortened the listing from both ends to conserve some screen space):
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'
. (I believe in Linux the serial port is often called '/dev/ttys0'
and that probaply applies to Cygwin too)
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 24 -f -g reset blink.S19
bl08 - MC68HC908 Bootloader - version 1.0.0.0
Reading S-records
Line ignored: S9030000FC
S-record data address 00FFFE size 000002
S-record data address 00DC00 size 000051
Mass erase
Program FFFE - FFFF .
Program DC00 - DC50 ..
Execute code from DC00
If everything goes as planned we should see something like:
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 matcha latte with mapple syrup and foamy top with sprinkle of 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.
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 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 wewe 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.
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 it 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 is a couple LEDs. Accomplising this does make you feel like a hero but doesn't make sense, so the first thing I always do 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 because when (and that is a when, not if) a 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 'HelloWord!' program, finally!
Doing that is pretty simple, create a directory named 'hello'
inside the 'hc08demos'
directory.
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.
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, that is an example of how you compile and link a multi file project using SDCC, an example
that I was able 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 slightly differently.
The first two lines are used to compile only (no linking) by passing
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 it using the
'--stack-loc'
command line option.
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.
Note that it is always ok to pass both option to SDCC regardless weather you are just compiling or linking. Note also that with some different targer 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 or properly speaking Automake is traditional Unix tool that is used to automate the compiling of programs.
Any non trivial 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 Automake to automate this. Mac OS X supports Gnu Automake 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 instructions for the automake on
how to compile and link your project.
You then invoke automake 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 spelling, 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 make file in place you can make it by just typing:
make
Which should result in the very same commands to executed and displayed on the Terminal as you what you
would have entered yourself manually.
Now all that is left 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
litle beast is outputing to us:
bl08 -c /dev/tty.usbserial-FTOXM3NX -b 9600 -t jb8 -x 24 -f -g reset -m hello.S19
Hello World, this HC08 talking!
Hello World, this HC08 talking!
Hello World, this HC08
This should produce the following output on your terminal:
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, let's refer to the
diargram 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 funcstion it uses, i.e. 'printf.h'
separately via the two 'sdcc' and
finally we linked them together using the 'sdcc' the third time, as illustrated in the diagram.
But there is one more thing to before everything is set up the way I like. While using the command line is actually as simple as typing 'make', it is not the way I want to work all day long...because there is a better way...
and go to Download page and select 'Eclipse IDE for C/C++ Developers', this is a nice little 67 MB download.
Double click on the
downloaded file and Mac will unarchieve it into a single
folder '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.
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.
on the left side panel click on the row which says 'Program' then the litle documen 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, ie
'-c /dev/tty.usbserial-FTOXM3NX -k -b 9600 -t jb8 -x 24 -f -g reset -m hello.S19'
Now it should look like this:
Click on the Apply button to save the changes.
No 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 the familiar 'Hello World, this HC08 talking!' world output should start ticking in the window.
Now, all you have to do 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. I use the 'ยง' key which is right above the tab key and which is otherwise used for nothing.
Click OK.
Now you can go through your whole development cycle of editing, compiling, linking, downloading, programming and executing by with a single key press.
Now how cool is that!
This page is no tutorial on C, which you can easily find elsewhere, but I felt that a short line by line walk through the code might help you over some microcontroller related rough places not covered by standard C tutorials.
Before I go through, line by line, the code I'll show you how basic input/output and peripheral control is typically handled with C in microcontrollers.
In this way controlling output devices or peripherals is as simple as assigning a variable!
This concepts also appliest input or reading of peripherals.
A few words of caution to store at the back of your mind though: memory mapped registers are actuall 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 registter, some 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 frequencys 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. 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 beoynd this page, but here is a quick cheat sheet.
It is convetional to visualize a byte as box with eight cells and numbeber them from right to left as follows. There is also 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.
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 |
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 with 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
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. Looking at 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) {
main
which is where the execution of the code starts. It looks rather complex, but you do not need to realy 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 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, so therefore we turn it off here. Someday, when the code is finished I'll turn it back on by leaving this line out.
DDRA=0x03;
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 0 and 1 into output by writing 3 into the data direction register.
while (1) {
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;
'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 exist while the block, defined by the cyrly braces, is 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;
for (i=0; i<50000; ++i) PTA;
'i'
from 0 to 50000, executing the rather obscure statement PTA
each time.
This 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 timen and to prevent the compiler from optimizing away the whole loop! Without that, the compiler might have desided 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 to optimize it all away.
} }
while
loop and the main
function.
#include "printf.h"
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.
data at 0x00 volatile char PTA; data at 0x1F volatile char CONFIG;
blink
code above.
void putchar(char x) {
putchar
that takes one argument (the char x
), a character to output, and returns no value (the void
). 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. So how did I know I needed to provide this? Well I read the documentation in the 'printf.h'
file, that's how.
(void)x;
My golden rule in programming is that all compiles should be 'clean' in other words that they should result in zero errors and warnings. In this way I know that when I see a warning it realy means something. I highly recommend this practice to everyone.
Now 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.
There is no guarantee that this works with every compiler, but so far has worked with all the compilers I've come accross, in anycase 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;
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 and 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 the chip, disassembled and reverse engineered it and then I read the C compiler manual and experimented with. 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 this and here it is, already chewed up for you.
}
'putchar'
function.
int main(int argc, char** argv) { CONFIG=0x01; // Disable COP while (1) {
blink
code above.
printf("Hello World, this HC08 talking!\n");
printf
function from our 'printf.c'
file passing it the 'Hello..' text as argument.
} }
The whole automake 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, automake system is a program called 'make'
which when executed '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 desribe 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 think that would it not be nice to write some sort of generic rule to handle the bulk of these just adding some special rules by hand. And of course you can:
%.rel : %.c
sdcc -c $< -o $@
'.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 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.
So now we are ready to walk through our very own 'Makefile'
:
SDCC = ~/sdcc/bin/sdcc
'PATH'
correctly when running
this make from within Eclipse.
OBJS = hello.rel printf.rel
LIBS =
TARGET = hello
'$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. Changin
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
%.rel : %h
'.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 $@
$(TARGET): $(OBJS) Makefile
$(SDCC) $(SDCCFLAGS) -o $(TARGET).S19 $(OBJS) $(LIBS)
'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 when someday we have dozens of
files in our project.
all: $(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
an other file, making it dependent on that file too and requiring a recompile
if any of those 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 realy add the following rule:
hello.rel : printf.h
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
'make clean'
before I archive or backup it.
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
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.