0
\$\begingroup\$

Please explain me why DDRx register must be set in some situations after setting PORTx register.

\$\endgroup\$
  • 1
    \$\begingroup\$ Can you give an example of such a situation? \$\endgroup\$ – chamod Feb 7 at 21:58
  • 1
    \$\begingroup\$ Setting to what? Sometimes you want to turn off the output (put it in tri-state). Is that the case? \$\endgroup\$ – Eugene Sh. Feb 7 at 22:06
1
\$\begingroup\$

Say that you need a pin to transition between being high impedance (high-Z) and being driven high, or using the internal pull-up resistor and being driven low. Such a transition requires changing a bit in two different registers, yet you can't actually modify both registers at the same time. Most of the time you can get away without paying attention to the order, but there are exceptions.

IO pin states

During the brief period of time between writing to PORTx and DDRx (or vice versa), the I/O port will be in an unwanted intermediate state. In some cases this intermediate state can cause a glitch or even damage components.


As an example, when writing a "bit banged" software implementation of I2C (which doesn't allow driving the pin high at any time as another chip may be driving the same line low), one must first clear the relevant DDRx bit and then set the PORTx bit to avoid the "output high" state when transmitting a 1 after a 0.

write order effects

\$\endgroup\$
0
\$\begingroup\$

For example if you want it to go smoothly from Hi-Z to high state, without low state glitch, you would set bit high in PORTx and then set DDRx to output, but I think it doesn't matter in practice - if you write something like:

DDRD=0x01;
PORTD=0x01;

in your code, the low state output will be forced on PD0 just for several hundred nanoseconds. It's usually very unlikely that this could do any harm in the device connected to this line.

Usually, after initializing ports, you are initializing the connected devices on a "higher layer" - you apply some kind of reset, set initial values etc.

After all the output circuit of the AVR is simple - DDRx controls the tristate/strong driver feature, and PORTx controls the output value. Just please remember that setting a bit in PORTx with corresponding DDRx bit cleared, will result in a pullup (weak high state driver) being applied to this line, which is useful for button inputs etc.

\$\endgroup\$

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.