Embedded Systems and Microcontrollers
CS 301 Lecture, Dr. Lawlor
Wristwatches, microwave ovens, keyboards, mice, and zillions of other
gadgets often have little CPUs inside them. These are called
"embedded" processors, because they're stuck inside some other box; or
"microcontrollers", because they're a microcomputer that controls some
other system. Most folks don't even think of them as computers,
but these tiny machines often are fully programmable.
I've hooked up one of my Microchip(tm) PIC microcontrollers to NetRun.
PIC in C
I've included a few little utility functions in the NetRun PIC environment:
- The function "led" turns on one of the red LEDs on the board. For example, "while (1) led(1);" turns on LED 1. There are 8 LEDs, numbered 0 through 7, in two columns (0 through 3 and 4 through 7).
- The function "wait" waits for the specified number of
milliseconds. For example, "while (1) wait(20);" repeatedly waits
for 20 milliseconds (this is not very exciting). You can wait from 0 to 255 milliseconds (because the wait time is only an unsigned byte).
- The global variable "GPIO" (General Purpose Input/Output) is
actually a hardware memory location whose bits are wired up to the
microcontroller's pins going to the outside world. If you write a
zero to this variable, all pins output 0v. If you write 0xff to
this variable, all pins output 5v. If you write in 0x8, pin 3
outputs 5v, and the other pins output 0v.
- All the rest of C (variables, for/while loops, if statements) is still there too.
Note that embedded code is almost always an infinite loop--the
controller's whole reason for existing is to do some task, and it's
usually supposed to continually do that task. In NetRun if your
code ever returns, I light LED 0 (the bottom-left LED), to let you know
something's wrong.
PIC Assembly
When you need to count clock cycles, or access special hardware
features, assembly is quite useful. Here's the (quite simple!)
instruction set for PIC microcontrollers:

"w" is the only register the thing has. "f" stands for a memory
address (up to 128 bytes). "k" stands for a program memory
address (up to 2048 instructions). "d" is the "direction bit"; it
determines whether the memory location f or the register w receives the
result.
Notice that:
- There's no hardware multiply, divide, or floating point. If you need these, you've got to write them yourself!
- Memory addresses have to be hardcoded into the instruction, which makes accessing memory via a pointer very tricky (and rare).
- Instructions are 14 bits wide, which isn't even a multiple of 8 bits!
- Instructions and memory are stored in totally separate locations,
and accessed differently. The program is almost always totally
non-volatile on embedded machines (burned into ROM), instead of being
loaded or compiled dynamically in RAM.
You can read some software serial code I wrote for the PIC. The "serial.c" file contains some carefully-timed assembly code to do serial communication.
Build One Yourself!
Here's the USB device programmer I used (with my own "usb_pickit" tool to upload the program).
Here's the underlying PIC hardware documentation. (The table of instructions shown above is on page 72).
Here's how to build your own circuit boards.
Here's a cheap source of servos, and the servo communication protocol.