How should unused I/O pins be configured on ATMega328P for lowest power consumption?
After digging through the datasheet, I found this:
14.2.6 Unconnected Pins
If some pins are unused, it is recommended to ensure that these pins have a defined level. Even though most of the digital inputs are disabled in the deep sleep modes as described above, floating inputs should 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. In this case, the pull-up will be disabled during reset. If low power consumption during reset is important, it is recommended to use an external pull-up or pull-down. Connecting unused pins directly to VCC or GND is not recommended, since this may cause excessive currents if the pin is accidentally configured as an output.
update in relation to comment/question:
According to table 14-1, the pull-up resistor is only active when the the following conditions are satisfied:
- The pin is set as input (DDxn bit is logic low)
- PORTxn is set logic high
- PUD is logic low
The only way you'll get significant current flowing through the pull-up resistor is if the pin experiences a low level with the pull-up enabled. This means either Atmel messed up badly (unlikely) or you have the pin configured as input with the pull-up enabled and the pin is somehow connected to ground.
Section 14.2.5
discusses digital input enable and sleep modes. To summarize, the digital input is clamped to ground at the input of the Schmitt Trigger to prevent a floating level while in sleep mode, unless the pin is configured as an external interrupt. I can't tell if digital output is disabled in sleep mode. It doesn't look like it is disabled according to figure 14-2
, though I wouldn't be too surprised if it was. The best bet is to use either an internal or external pull-up resistor.
- Set pin to input, drive pin high to engage internal pull-up: I think this should read: "make input high by engaging internal pull-up". (I would use the word "drive" only if you do so actively, by means of a FET to Vcc or ground.) It's clear that you want a defined level, and the pull-up takes care of that. Make sure enabling the pull-up is one of the first things you do after reset. That goes for I/O initialization in general. The only current will be the leakage current of the NFET of the push-pull pair, and the gate leakage of the input FET. Less than 1 µA: OK.
- Set pin to input, drive pin low: Not a good idea. If the software goes bananas and would switch the pin to output high you're shorting the pin, damaging the PFET of the complementary pair.
- Set pin to input, external pull up: Is the same as 1), only more expensive. But has the advantage that the pull-up will always be there; you may forget to enable the internal pull-up (which is disabled by default). If the I/O would accidentally switch to output low you'll have a small current drain.
- Set pin to input, external pull down: Again the cost of a resistor (yes, I know they're cheap, but cheap + unnecessary = expensive.) The same current as in 3) if the pin would go to active high.
- Set pin to output low: Has a higher leakage current than when configured as input, but still below 1 µA, so nothing to worry about. I would still enable the internal pull-up. It won't be active with the I/O as output, but if it would accidentally be switched to input the pin wouldn't remain floating.
- Set pin to output high: Same as 5)
- Set pin to output low, external pull down: The pull-down resistor is an unnecessary cost: it would make an output low, which is already low. But compared to 5) has the advantage that you're sure the pin won't float if unintended switched to input.
I would go for 1): input with internal pull-up; no external parts required. In an FMEA 5) may fare better, but that depends on how high you estimate the risk that you forget to enable the internal pull-up. A software design peer review should give you insurance.