Programming Differences between a Microcontroller and a Microprocessor?

This is really two questions in one...

Firstly, what is the difference between a microcontroller and a microprocessor?

Microprocessor is a purely a CPU that follows a set of instructions read from an external memory bus. It controls external peripherals (such as screen, keyboard, mouse, hard drive, etc) via an external communications bus. When you program a microprocessor, your program is external to the device. In a computer, this memory is initially the boot up BIOS ROM which initially reads the operating system from the hard drive into RAM memory, then continues to execute it from there.

Microcontroller is kinda like an all-in-one CPU + Memory, with some external ports to communicate with the outside world. It's self contained and doesn't use external memory to hold it's program (although if needed it can read and write working data to external memory).

Secondly, is programming a microcontroller and microprocessor the same?

In some ways yes, and in some ways no.

Assembly language is a broad term that describes a set of instructions that the CPU can directly understand. When you 'compile' assembly language, it doesn't really compile anything, all it does it convert it to a sequence of bytes that represent the commands and plugs in some relative memory locations. This is common to both microprocessors and microcontrollers.

However, different types of CPU understand a different set of CPU instructions. For example, if you write an assembly language program that works with a pic 16F877 microcontroller, it will be complete nonsense to a microprocessor or any other microcontroller outside of the 16Fxxx family of pic microcontrollers.

So, although assembly works in a similar way across all microprocessors and microcontrollers, the actual list of instructions that you write are very different. To write in assembly language, you need to have an in depth knowledge of the device's architecture, which you can normally get from the datasheet in the case of a microcontroller.


The difference is that the microcontroller includes on-chip memory like Flash EEPROM and RAM, and peripherals like parallel and serial I/O. With the first microprocessors those were all external devices. Instead of the I/O's microprocessors had an the address and data bus brought to their pins.
The way you write code for either is the same.

To illustrate that point: there are architectures (ARM for instance) where the very same CPU is availble as microcontroller (with all code and data memory on the chip), as microprocessor (all code and data memory external), or as hybrid (some memory on the chip, but for most applications you will add external memory). The CPU is the same, so the programming (in the sense of CPU instructions) is the same.


Although this tends to be a grey area, another common difference between microcontrollers and microprocessors is that microcontrollers often use Harvard architecture (separate address space for code and data), while micrprocessors almost all use Von Neumann architecture (combined address space for code and data).

Examples of microntroller families using Harvard architecture include: AVRs, Intel 8051, PICs (except PIC32, see below), and ARM Cortex-M3. A notable exception are Freescale processors, like the HCS08, which use Von Neumann architecture, as does the Parallax Propeller.

This affects programming in several ways (examples shown below use C):

There may be several types of RAM, each with their own address space. For example, the 8051 has external data (xdata) which is addressed separate from the first 256 bytes of RAM, even though both are implemented on the same chip. So one has to use qualifiers on variables declarations like unsigned int xdata foo;

If constants are declared in code memory, they may need to be copied to RAM before they can be accessed. Or, there needs to be a way to access code memory as if it were data -- e.g. the code qualifier for 8051s, or PIC's Program Space Visiblity (PSV) feature.

These non-standard ways of accessing code and RAM tend to be the major difference (besides peripherals) when porting C code from one chip family to another.

You can't execute code from RAM in a strict Harvard architecture, so there can't be any self-modifying code (unless you count re-flashing program memory on the fly). However the PIC32 has a modified Harvard architecture that allows code to be executed in RAM. The Parallax Propeller actually makes use of its ability to modify code to perform subroutine returns, since it has no hardware stack.