Here we are going to discuss about:
  • Controlling any output port by handling input pin
  • Masking bits to one of I/O register
  • Taking control of output using if()/else statement; here we use a led that will be turned on when button is pushed, off otherwise.
Any microcontrollers must have their PORTs (to mean their terminal i/o or simply we may call it ‘port’ or ‘pin’) to communicate with external device or to exchange informations. Each pin of any ports here simply have two basic purposes; to be output and/or input. As we know how to use one of the its pin for handling output.

Related posts:
Now we will use one of the pin to handle input.
Before we go, just make the circuit below (using our beloved proteus simulation):
Figure 1. Circuit mcu, push-button, resistor, and led
On the circuit above, mcu atmega8535 is used, then the pin we are going to use to handle input is PORTD – PD0, and led is attached to PORTA – PA0. Note that PD0 and PA0 here means the least-significant bit (or simply the first bit of the PORTx register – it starts from 0).

There is one component left above that I am going to explain next along with the program for simplicity.

Now type the program bellow:
#include <avr/io.h>
int main()
{
 DDRA |= 0x01;
 while(1)
 {
  if((PIND & 0x01) == 0)
   PORTA |= 0x01;
  else
   PORTA &= ~0x01;
 }
 return 0;
}
As we know a bit about header file and accessing DDRx register – Data Direction Register on previous article (linked above), here we just discuss about the flow of the program and PINx register – PORT x Input Pin.
The if(){} else{} on the line above is in the while loop which has argument ‘1’ meaning that it runs forever. Now in the if() syntax,
if((PIND & 0x01) == 0)
PIND regeister has its 8-bit sequence bit, see figure bellow
Figure 2. PIND register – bits.
The parameter-list inside if() means that It is masked by 0x01 in hexadecimal format (or 0b00000001 in binary format) that refers to the circuit on figure 1 above, and then the expression result that has been masked is compared by 0 (or false logic in this case). When the result of the masked expression (PIND & 0x01) is zero (false-logic), the statement inside if() will be executed, i.e.,
PORTA |= 0x01; //led is turned on
otherwise, the statement inside else will be executed, i.e.,
PORTA &= ~0x01; //led is turned off
So some of you might ask, why we compared it by 0 (zero), in if((PIND & 0x01) == 0)?.. This is where the push-button and 1k-resistor have a role. When the push-button is not pushed, the logic of the pin (PD0) will be 1 (true logic) that is caused by the resistor connected with vcc (5v) to the PD0. On the contrary if pushed, the logic of the pin (PD0) will be 0 (false logic) that is caused by the ground that connects to the push-button. For this case, the resistor above has a role to be ‘pull-up resistor’ (it’s just a term) meaning that the PD0 will be tolerant when its push-button connected to be false-logic (grounded).

Note:
Instead of (PIND & 0x01) == 0 expression, we can use another one that has the same purpose:
!(PIND & 0x01)