How do I read digital input on ATmega16?
Brazilian greetings!

First of all thanks Joby for your example. Secondly, his example has just a minor error. The number 0x20 is not correct. It should be 0x04. Also, just as a suggestion, I would not use hexadecimal numbers like 0xFB, 0x20, or 0x04 in the code. I would suggest using the PIN port definitions found in the io.h and other ones referenced by header file. I have rewritten Joby's example below, with some comments for the beginners.

# include &lt;avr/io.h&gt;

int main (void)
{
    // set all pins on PORTB for output
    DDRB = 0xFF;

    // set port pin PORTD2 as input and leave the others pins 
    // in their originally state (inputs or outputs, it doesn't matter)
    DDRD &amp;= ~(1 &lt;&lt; PD2);        // see comment #1

    while (1) 
    {
        if (PIND &amp; (1&lt;&lt;PD2))    // see comment #2
            PORTB |= (1&lt;&lt;PB2);  // see comment #3
        else
            PORTB &amp;= ~(1&lt;&lt;PB2); // see comment #4
    }
    return 0;
}


/*

comments for beginners

comment #1: (1 &lt;&lt; PD2) generates the binary 00000100.
              The operation "~" flips all the digits, i.e., 
              the binary now is 11111011. Finally the &amp;= 
              applies the logic "AND" between DDRD and 11111011
              and the result is placed again in DDRD memory. 
              Note: What the operator "AND" does is for each bit 
              in the DDRD memory, it compares with the binary number
              above. If the bit in DDRD is 0 and the bit in the
              binary at the same bite position is 1, then the
              resulting bit is 0, if the DDRD is 1 and the 
              bit in the binary is 1, the resulting bit is 1, 
              and if the bit in the DDRD is 1 or 0 and
              the bit in the binary is 0 then the resulting 
              bit is always 0. In summary, the command DDRD &amp;= ~(1 &lt;&lt; PD2)
              changes only the bit PD2 to zero and leave the other ones 
              (zeros or ones) untouched. It seems a little
              bit complicated, but after you get used to it, it
              is the best way of changing a bit in a bite without
              changing the other bits.

comment #2: (1 &lt;&lt; PD2) generates the binary 00000100.
              Using the same logic "AND" described in 
              comment #1, the command "PIND &amp; 0000100" checks
              only if the PIND2 (our input pin where the push button
              is connected to) is set to high or not. All the other 
              pins will be FALSE since the binary bits are set to 0, 
              and since the binary bit #2 is set to 1, the IF statement 
              will be TRUE only if the PD2 input is set to high 
              or FALSE if the PD2 input is set to low. 

comment #3: Following the logic explained in comment #1, this
              command sets output pin PINB2 in port PORTB to
              high voltage. If your LED is correct connected to
              this pin port with a resistor of ~300 ohms, and that 
              resistor is connected to the ground, the LED should turn on.

comment #4: The LED should turn off for the same reasons explained
              in the previous comments.

Final considerations:

a) To avoid voltage oscillation in the input pin PD2 when the 
   push button is not pressed (open circuit), I strong recommend
   to place a pull-down resistor (1 kOhm or higher), so that the 
   LED does not light up accidentally due to this random voltage 
   oscillation.

b) A disclaim note: The ideas described here are to be used as 
   educational only and they should NOT be used in any real system 
   before consulting an expert in electronics.

*/