3.10.6.1 Ports as General Digital I/O

The ports are bi-directional I/O ports with optional internal pull-up resistors. The following figure shows a functional description of one I/O-port pin, here generically called Pxn.

Figure 3-60. General Digital I/O

WRx, WPx, WDx, RRx, RPx and RDx are common to all pins within the same port. CLKI/O, SLEEP and PUD are common to all ports.

Configuring the Pin

Each port pin consists of three register bits: DDxn, PORTxn and PINxn. As shown in I/O Ports Register Description, the DDxn bits are accessed at the DDRx I/O address, the PORTxn bits at the PORTx I/O address and the PINxn bits at the PINx I/O address.

The DDxn bit in the DDRx register selects the direction of this pin. If DDxn is written logic ‘1’, Pxn is configured as an output pin. If DDxn is written logic ‘0’, Pxn is configured as an input pin.

If PORTxn is written logic ‘1’ when the pin is configured as an input pin, the pull-up resistor is activated. To switch off the pull-up resistor, PORTxn has to be written to logic ‘0’ or the pin has to be configured as an output pin. A default configuration is applied by the port hardware when the reset condition becomes active, even if no clocks are running. For further details, see Alternate Port Functions.

If PORTxn is written to logic ‘1’ when the pin is configured as an output pin, the port pin is driven HIGH (‘1’). If PORTxn is written to logic ‘0’ when the pin is configured as an output pin, the port pin is driven LOW (‘0’).

All port settings done in DDxn, PORTxn and the port overrides from the alternate port functions need to be globally enabled by the ENPS bit in MCUCR.

Toggling the Pin

Writing a logic ‘1’ to PINxn toggles the value of PORTxn, independent of the value of DDRxn.

Note: The SBI instruction can be used to toggle one single bit in a port.

Switching Between Input and Output

When switching between tri-state ({DDxn, PORTxn} = 0b00) and output high ({DDxn, PORTxn} = 0b11), an intermediate state with either pull-up enabled {DDxn, PORTxn} = 0b01) or output low ({DDxn, PORTxn} = 0b10) must occur. Normally, the pull-up enabled state is fully acceptable because a high-impedance environment does not detect the difference between a strong high driver and a pull-up. If this is not the case, the PUD bit in the MCUCR register can be set to disable all pull-up resistors in all ports.

Switching between input with pull-up and output low generates the same problem. The user must use either the tri-state ({DDxn, PORTxn} = 0b00) or the output high state ({DDxn, PORTxn} = 0b11) as an intermediate step.

Table 3-77. Port Pin Configuration

DDxn

PORTxn

PUD

(in MCUCR)

I/O

Pull-Up

Comment

00

X

Input

No

Tri-state (Hi-Z)

010

Input

Yes

Pxn will source current if ext. pulled low.

011

Input

No

Tri-state (Hi-Z)

10

X

Output

No

Output Low (Sink)

11

X

Output

No

Output High (Source)

Reading the Pin Value

Independent of the setting of the data direction bit DDxn, the port pin can be read through the PINxn register bit. The PINxn register bit and the preceding latch constitute a synchronizer. This is needed to avoid metastability if the physical pin changes value near the edge of the internal clock while also introducing a delay.

The following figure shows a timing diagram of the synchronization when reading an externally applied pin value. The maximum and minimum propagation delays are denoted as tpd_max and tpd_min, respectively.

Figure 3-61. Synchronization when Reading an Externally Applied Pin Value

Consider the clock period starting shortly after the first falling edge of the system clock. The latch is closed when the clock is low, and goes transparent when the clock is high, as indicated by the shaded region of the SYNC LATCH signal. The signal value is latched when the system clock goes low. It is clocked into the PINxn register at the following positive clock edge.

As indicated by the two arrows tpd_max and tpd_min, a single signal transition on the pin is delayed between ½ and 1½ system clock periods depending upon the time of assertion.

When reading back a software-assigned pin value, a NOP instruction must be inserted as indicated in the following figure. The OUT instruction sets the SYNC LATCH signal at the positive edge of the clock. In this case, the propagation delay tpd through the synchronizer is 1 system clock period.

Figure 3-62. Synchronization when Reading a Software Assigned Pin Value

Digital Input Enable and Sleep Modes

As shown in the figure Figure 3-60, the digital input signal can be clamped to ground at the input of the Schmitt trigger. The signal labeled SLEEP in the figure is set by the MCU sleep controller in power-down mode, power-save mode and standby mode to avoid increased power consumption if some input signals are left floating or have an analog signal level close to VCC/2.

SLEEP is overridden for port pins enabled as external interrupt pins. If the external interrupt request is not enabled, SLEEP is also active for these pins. SLEEP is also overridden by various other alternate functions, as described in Alternate Port Functions.

If a logic HIGH level is present on an asynchronous external interrupt pin configured as “Interrupt on Rising Edge, Falling Edge or Any Logic Change on Pin” while the external interrupt is not enabled, the corresponding external interrupt flag is set when resuming from the above-mentioned sleep mode because the clamping in these sleep mode produces the requested logic change.

Unconnected Pins

If some pins are unused, it is recommended to ensure that these pins have a defined level even if most of the digital inputs are disabled in the deep sleep modes described above. Floating inputs must be avoided to reduce current consumption in all other modes where the digital inputs are enabled (reset, active mode and idle mode).

The simplest method to ensure a defined level of an unused pin is to enable the internal pull-up. Some pull-ups are disabled during reset. If low power consumption during reset is important, it is recommended to use an external pull-up or pull-down resistor. Connecting unused pins directly to VCC or GND is not recommended, as this may cause excessive currents if the pin is accidentally configured as an output.