memory and executed from there. Von Neumann Architecture
was (and is), in fact, the “stored-program concept.”
Data within a 16-bit PIC is also stored and addressed as a
16-bit package but we actually use the data in the normal
eight-bit way. The least significant byte of the 16-bit data word
is always found on an even address boundary (0, 2, 4, 6, etc.).
Accessing the most significant byte of the 16-bit data word
tied to an even address boundary reveals the odd data bytes
(1, 3, 5, 7, etc.). A quick look at the linker script of the 16-bit
device we will be discussing shows that our 16-bit PIC’s data
space begins at address 0x0800 and is 0x2000 bytes in length:
//LINKER SCRIPT MEMORY AREA SNIPPET
data (a!xr) : ORIGIN = 0x800,
reset : ORIGIN = 0x0,
ivt : ORIGIN = 0x4,
aivt : ORIGIN = 0x104,
program (xr) : ORIGIN = 0x200,
config2 : ORIGIN = 0xABFC,
config1 : ORIGIN = 0xABFE,
LENGTH = 0x2000
LENGTH = 0x4
LENGTH = 0xFC
LENGTH = 0xFC
LENGTH = 0xA9FC
LENGTH = 0x2
LENGTH = 0x2
Thus, 0x27FE is the least significant byte of data just
before the last and most significant byte of data at 0x27FF.
There are some other things we can take away from the
linker script snippet:
• The 16-bit PIC’s reset vector is located at 0x0.
• The 16-bit PIC’s Interrupt Vector Table begins at 0x04.
• The 16-bit PIC’s Alternate Interrupt Vector Table begins at
• The 16-bit PIC’s program space begins at 0x200.
• The 16-bit PICs’s Configuration Words reside at 0xABFC
a 16-bit PIC is made of, let’s look at what it takes to put some
code behind a 16-bit PIC and exercise the 16-bit hardware.
There’s no better way to learn about a new PIC than blinking some LEDs and forcing some characters through its UART.
Blinking LEDs and sending UART-based messages are basically what the PIC24FJ64GA002-based demo board you see in
Photo 1 is designed to do. Don’t be fooled. Blinking LEDs with
a PIC may sound simple. However, there are some things you
need to know about the PIC24FJ64GA002 before you can
successfully illuminate and extinguish an LED alternately using
a PIC24FJ64GA002 I/O pin. For example, take a look at
Figure 1. Quick. Tell me where you would hang your LED. Is
RA0 really a digital I/O pin or is it in the AN0 analog mode?
What about RB0? Is it really the I/O pin RB0? What does the
RB0 multiplexed function RP0 represent? (Get my point?)
The pin multiplexing scheme employed by the
PIC24FJ64GA002 may seem at first to be very complex.
However, the key to understanding any complex idea is breaking down the problem into smaller manageable parts. So, let’s
play the cards we were dealt. As you can see in Schematic 1,
the PIC24FJ64GA002 demo board has four onboard LEDs,
which are attached to RB12, RB13, RB14, and RB15.
Consulting the PIC24FJ64GA002 datasheet, I learned that all
of the PIC24FJ64GA002’s I/O pins are configured as inputs
following a reset. Since the I/O pins that are supporting the
LEDs are multiplexed with analog-to-digital (A-to-D) inputs,
let’s be safe and dedicate the LED-toting I/O pins to a digital
role. This is easily done by setting all of the bits within the A/D
Port Configuration Register (AD1PCFG). The AD1PCFG resets
to zero indicating all of the ANx A-to-D inputs are enabled.
Setting the AD1PCFG register bits to logical 1 disables the
associated A-to-D input and puts the selected port pin into
digital mode. Here’s the Microchip C30 C compiler statement
that erases all of the PIC24FJ64GA002’s A-to-D inputs:
Thus far, we have a 16-bit PIC that supports a 16-bit
data path, a 24-bit instruction set, and a 24-bit Program
Counter. You can also add a 16-bit x 16-bit Working
Register Array and multiple 16-bit Timer/Counters to the list
of 16-bit PIC features. The 16-bit x 16-bit Working Register
Array contains 16-bit register space for the 17-bit x 17-bit
single-cycle hardware multiplier and the 32-bit x 16-bit hardware divider, in addition to general-purpose 16-bit registers.
It’s obvious that the 16-bit PIC was designed to crunch
numbers. However, a PIC just isn’t a PIC unless you have
the ability to pound on stuff with the PIC’s I/O pins. With
that thought in mind, let’s do some touchy feely on some
real 16-bit PIC hardware.
AD1PCFG = 0x1FFF;
If you’re wondering why the 0x1FFF is not 0xFFFF, there are
only 13 possible A-to-D inputs. The three most significant bits of
the AD1PCFG register default to zero (0b0001111111111111).
The PIC24FJ64GA002 only supports AN0-AN5 and AN9-AN12.
By using the 0x1FFF value, we’re actually turning off A-to-D
■ FIGURE 1. Note the heavy use of pin function multiplexing.
The bold RPn pins are remappable peripheral pins. The RPx pins
can be configured to function as timer I/O, UART I/O, SPI I/O,
input/output capture I/O, PWM outputs, or comparator outputs.
BLINKING LEDS WITH THE
Believe it or not, everything we’ve
discussed up to this point concerning 16-bit
PICs has been “general-purpose.” Yep. All
of the stuff you’ve just read about is simply
standard equipment on a 16-bit PIC. Now
that you have a basic understanding of what
November 2007 83