Skip to main content

Microcontrollers

Section 5.1 Data Direction

Each I/O pin on the ATmega328P is bidirectional. Through associated registers, each pin can be configured as an input (which allows the microcontroller to read its corresponding logic level) or an output (which allows the microcontroller to send data to the pin). Figure 5.1.1 shows a schematic of how this works.
Schematic of I/O port registers. A D flip-flop is labeled DDRxn. The input of this flip-flop is the data bus. The clock is the control signal "write DDRxn." The output connects to the enable of a tri-state buffer. The active-LOW clear pin connects to the reset signal. Another D flip-flop is labeled PORTxn. The input of this flip-flop is the data bus. The clock is the control signal "write PORTxn." The output connects to the input of the same tri-state buffer. The active-LOW clear pin connects to the reset signal. The third flip-flop is labeled PINxn. The input of this flip-flop is the output of the same tri-state buffer. The clock signal is the microcontroller I/O clock. The output connects to the input of a different tri-state buffer, whose enable pin connects to the "read PINxn" control signal and whose output connects to the data bus.
Figure 5.1.1. Hardware schematic of I/O port registers: DDRxn controls the data direction, PORTxn controls the data sent to output pins, and PINxn contains the data state of input pins.
The directionality of each I/O pin can be configured with the data direction register associated with that pin’s port. The three data direction registers on the ATmega328P are DDRB, DDRC, and DDRD. By default upon startup, each bit in each data direction register has a value of 0, which corresponds to each I/O pin being configured as an input pin. By writing a 1 to a pin’s bit in its corresponding data direction register, that pin will be configured as an output pin.
Writing data to an output pin can be accomplished by sending data to that pin’s port data register. Each port on the microcontroller has its own port data register: PORTB, PORTC, and PORTD. Reading data from an input pin can be accomplished by reading data from the corresponding pin register. The three pin registers are PINB, PINC, and PIND.