How I/O pins are structured?

I have this long been question.
How digital or analog I/O pins can both read and output signal?

What particular element reads and output signal?
and how are they structured from terminal to micro controller?
I looked up the Arduino board circuit schematics but failed to understand -3-

Any help?

p.s. I'm not talking about DAC / ADC.

Here's the datasheet:

http://www.atmel.com/images/atmel-8271-8-bit-avr-microcontroller-atmega48a-48pa-88a-88pa-168a-168pa-328-328p_datasheet_complete.pdf

Diagram in section 14.2 (page 78) shows the basic per-pin circuitry (not including any special uses).

One of the circuit elements you might not have seen before is the CMOS transmission gate (the device
shown being controlled by the SLEEP signal, bottom left), but think of it as a SPST analog switch.

How digital or analog I/O pins can both read and output signal?

What particular element reads and output signal?

It's not the same element. :wink: I don't know the details of how it's done in the ATmega chip, but it's possible to either switch between the (internal) circuits, or to enable just the input or enable just the output.

Philosophically, _you could leave the input circuit connect at all times and simply ignore it (in software) when using the pin as an output. Of course, it's not possible to leave the output circuit connected (and active) at all times since the output drives the pin high or low. and that would interfere with whatever is connected externally. (It is possible with open collector outputs if the output is left in it's high-impedance state, but the Arduino doesn't have open collector outputs. _

The Arduino does have open collector (well open drain), you just do this:

void setup ()
{
  digitalWrite (pin, LOW) ; //setup for open-drain
}

void drive_pin_open_drain (bool val)
{
  pinMode (pin, val ? OUTPUT : INPUT) ;
}

That way you only ever turn on the bottom FET on the pad.

DVDdoug:
it's possible to either switch between the (internal) circuits, or to enable just the input or enable just the output.

Philosophically, you could leave the input circuit connect at all times and simply ignore it (in software) when using the pin as an output.

Well, there is no reason to "disable" an input circuit and given the input impedance of CMOS, there really is no practical way to do so since the impedance of an open "switch" and an input buffer are much the same (or favour the input buffer).

The choice that may be made in the design of a microcontroller, is when an output is enabled, whether to (with additional complexity) read the state of the output register or the actual state of the pin itself which may (and particularly so with an open-collector driver) not actually be what is written to it.

This most certainly matters in respect of read-modify-write instructions whether implemented in the chip itself, or in code.