■ PHOTO 3. The Cleverscope measured
1.659 mS between the beginning of the
first low-going pulse and the first rising
edge. The next falling edge clocked in
8. 33 mS later.
(binary 0000 0000 0000 0000 0000
0000 0000 0100). Bit 2 of the
IO0DIR register is directly associated with general-purpose I/O pin
P0.2 which, in this case, has been
assigned as an output pin.
Okay, since pin P0.2 is open
drain, all we need to do now is write a
0 to P0.2 to turn on the LED and a 1
to P0.2 to turn it off. There is more
than one way to accomplish this.
The simplest way to toggle our
LED is to use the LPC2136’s IOSET
and IOCLR registers. Writing a 1 to
bit 2 of the IOSET register will
produce a logical high state on
P0.2. Writing a 1 to bit 2 of the
IOCLR register will produce a
logical low state on P0.2. If you’ve
hooked up your LED to P0.2,
executing the IO0SET_bit.P0_2 and
IO0CLR_bit.P0_2 instructions in
Listing 1 will physically demonstrate
what I’ve just described to you.
The downside to using the IOSET
and IOCLR registers is that in operations that involve multiple bits being
toggled, the I/O pins emitting logical
lows lag slightly behind I/O pins
emitting logical highs. To get simultaneous output, the solution is to write
directly to the IOPIN register. Note
that both IOPIN code statements in
Listing 1 preserve the state of all of
the bits that will not be changed by
logically ANDing them with a 1.
Only the bits to be changed are
swept to zero in the logical AND
operation.
If a bit is to be changed from a 0
to a 1, that bit is logically ORed with a
1, as shown in the first IOPIN
statement. The logical OR operation
to turn on the LED in the second
IOPIN statement is shown for clarity.
The AND operation clears the P0.2
bit and turns on the LED. Thus,
logically ORing the band of zeroes is
unnecessary.
Reading input port pins is very
easy to do. The IOPIN register always
contains the logical status of every
port pin in its domain. In my simplified
example, the variable input_data
holds all of the P0 port pin logic states.
To get a particular pin’s state, just read
the IOPIN register and mask away
(logical AND with a zero) the bits you
aren’t interested in.
As per Schematic 2, load up four
sets of LED/current limit resistor
pairs between pins P0. 4-7 and
ground and four more LED/current
limit resistor pairs between P0. 17-20
and ground. When you’re done,
compile the advanced LED code in
Listing 2.
If you’re going to seriously use
peripherals that own a data and
address bus like LCDs or external
memory devices, you’ll need to
know how to put multiple bytes on
the LPC2136 I/O pins where you
want them and when you want them
there.
Listing 2 uses the idea behind
structures and structure pointers to
effectively overlay the bit pattern
depicted in the P0_DATA_BUS
data type over the LPC2136’s
IO0PIN, IO0SET, and IO0CLR
registers. Notice that the structure
elements in the P0_DATA_BUS bit
pattern match the connections to
LEDs and data input pins shown in
Schematic 2.
Once the physical layout of the
LPC2136’s I/O pins is determined,
all that has to be done is to
logically assign the respective pins in
the P0_DATA_BUS structure
element bit pattern and set their
direction with the contents of the
IO0DIR register.
The typedef struct statement
creates a data type called
P0_DATA_BUS and does not create a
typical structure in memory as you
would expect. The actual reads and
writes are executed against the
memory locations that are targeted
by the pointers to structures
(*DATA_BUS_IOPIN, *DATA_BUS_
IOSET and *DATA_BUS_IOCLR),
which happen to be the addresses of
the IO0PIN, IO0SET, and IO0CLR
registers. Thus, the statement
DATA_BUS_IOSET->data_low =
led_data actually sets the bits in the
IO0SET register associated with the
structure element data_low with the
value of the lower nibble of
led_data.
Since we are dealing with multiple
bits, we must make sure that if any
other bits in the data_low structure
element are set that were not set by
the data we just loaded are cleared.
So, we execute
DATA_BUS_IOCLR->data_low = ~led_data, which clears
any bits in the data_low structure
92
June 2006