SMILEY’S WORKSHOP ☺
chops. If you want to take a more
humane and neuron-saving approach,
then use macros with sensible names.
We will take the latter approach and write
the macros port_pin_activate_pullup(),
port_pin_deactivate_pullup(), and
port_pin_toggle() that we will discuss
below.
Switching Between Input
and Output
It is possible to get problematic
intermediate states when changing
between certain states:
• From tri-state to output HIGH.
We will take care of this in the
digitalio pin_mode() macro which will
always deactivate the pull-up and set the output to 0
before setting the data direction to output.
■ FIGURE 7. Arduino ATmega328 pin mapping.
Setting a Pin to Tri-state
This is only odd because it indicates that there is a
third state for a binary system which — by definition —
only has two states. Tri-state is considered a third state for
a pin; the first two being HIGH (Vcc) or LOW (GND). Tri-state means that the pin is disconnected from the voltage
and can be considered no longer in the circuit to which it
is attached. When the AVR system is reset, the digital I/O
pins are in the tri-state condition.
Expanded Digitalio Functional Requirements
Specification
The digitalio toolset will provide functions or macros
to do the following:
• Set a port pin mode to input or output.
Warning Arduino Pin 13 is Funky
While we are cataloging funkiness, let’s not forget to
mention that digital I/O is a bit off on the Arduino pin 13
which is attached to an LED and resistor. This doesn’t have
much effect if you want to use it as an output pin, but it
does if you use it for input. If you activate the internal pull-up, then the high voltage will be about 1.7V rather than
the expected 5V. The Arduino reference states “If you
must use pin 13 as a digital input, use an external pull-down resistor.”
Expanding the avrtoolbox
Digitalio Library
Now that we have a good idea about the underlying
AVR digital I/O architecture, let’s expand our avrtoolbox
libavr digitalio toolset to include some more useful
functions and macros. We’ll demonstrate this with a
chaser light application that reads the digital input from an
eight-bit DIP switch and writes the digital output to eight
LEDs configured as shown in the figures from last month’s
workshop, except that now we will be using ports rather
than the Arduino style pins.
Expanded Digitalio Application
Programmer’s Interface
port_pin_mode()
Description: Set a port pin mode to input or output.
Syntax: port_pin_mode(uint8_t PORTx, uint8_t pin,
uint8_t mode)
Parameters:
uint8_t PORTx: The port as identified in io.h.
uint8_t pin: The pin number 0 to 7.
Uint8_t mode: Either INPUT or OUTPUT.
Returns: Nothing.
Example:
// Set PORTB pin 4 to output
port_pin_mode(PORTB, 7, OUTPUT);
port_pin_read()
Description: Reads the state of a pin in a port.
Syntax: port_pin_read(uint8_t PORTx, uint8_t pin)
Parameters:
uint8_t PORTx: The port as identified in io.h.
uint8_t pin: The pin number 0 to 7.
Returns: HIGH, LOW.
Example:
// Get the pin state
November 2011 51