Sunday, 5 April 2015

ARDUINO UNO I/O PORT PROGRAMMING

ARDUINO UNO I/O PORT PROGRAMMING

Hello readers, today I will discuss with you about the three important registers that are associated with Arduino Uno (ATMEGA 328). They are PORT register, DDR (Data Direction register) and PIN register. Arduino Uno board has 3 ports namely PORTB, PORTC and PORTD.

PORTB occupies pin number (8 to 13)
PORTC occupies analog pins (A0 to A5)
PORTD occupies digital pins (0 to 7)

DDR register is used to set the direction of the PORT. Any port pin can be configured as input pin or an output pin.  To understand how we can set the direction of a particular port pins let’s see some of the examples-
If we write
DDRB = B00111111; then PORTB pins (PB0 to PB5) are configured as output port pins.
DDRB = B00000001; then PB0 is configured as output port pins and PB1 to PB5 pins are configured as input pins.

So it’s quite clear that if it is required to set a port pin as i/p pin then write 0 to the corresponding port pin position in DDR register and for configuring a port pin as o/p pin then write 1 to the corresponding port pin position in DDR register.  

PORT register is used for assigning the value on to a particular port.

For example-
PORTB = B00111111; then all pins of PORTB are set to HIGH level.
PORTB = B00111100; then PB0 and PB1 are reset to LOW level and PB2 to PB5 are set to HIGH level. 

PIN register
The status of the i/p port pins can be read from the PIN register. This register can only be read and each port has its own corresponding PIN register, PORTA has PINA, PORTB has PINB and PORTC has PINC register.

Now after understanding the role of different registers associated with i/o functionality of ports, let’s develop some examples to get used to the usage of these registers.

Consider that PORTB has six LED’s connected to it as shown in figure below- 


Circuit Diagram-

Figure 1 Circuit showing 6 LEDs connected to PORTB

Now it is required to blink these six LEDs after every 1 second. To do this task first in the setup() function the directions of PORTB pins has to be configured as i/p pins and then in the loop() function PORTB can be assigned values. The complete code is given below-

Code for blinking six led’s connected on PORTB every 1 second-

void setup()
{
  DDRB = B00111111; // Initialize PORTB data direction register PB0 to PB5 configured as o/p pins
}


void loop()
{
  PORTB = B00111111; // assign value to PORTB making all pins high
  delay(1000);  // delay of 1 sec
  PORTB = B00000000;         // assign value to PORTB making all pins low
  delay(1000);  // delay of 1 sec
}


Similarly readers can try other simple programs like  led flashing pattern from right to left or from left to right using shift left (<<) and shift right operator (>>).

One simple loop() body for blinking the leds from left to right can be-

void loop()
{
   int m;
  PORTB = B00000001; // make PB0 high
  delay(1000); // 1 sec delay
  for(m=0;m<5;m++)
  {
  PORTB = PORTB<<1; // shift left
  delay(1000); // 1 sec delay
  }



Now let’s analyze some of the examples in which PIN register is used to read the status of a port.

Assume that an active low switch is connected to pin 13 and a led is connected to pin 12 of arduino. The default state of the pin 13 is high and the default state of pin 12 is low. It is required that when switch is pressed the LED should glow and when it is released then the led should remain in the off state. The circuit diagram for demonstrating this problem is shown below-

Figure 2 Circuit showing a button connected on pin 13 and an led connected on pin 12

The following arduino code can be used to read the status of a button-

byte temp; // define a temporary variable to hold the status of port pins

void setup()
{
  DDRB = B00000010; // configure PB0 as i/p and PB1 as o/p pins
}


void loop()
{
  temp = PINB & B00000001; // check the status of port pins using simple and operation
  if (temp == B00000001) // check the status of temporary variable temp which stores the status of                                                    //PORTB
  {
   PORTB = B00000000;  // assign this value to PORTB
  }
 
  // if switch is pressed then else block is executed
  else
  {
    PORTB = B00000010;
  }
 
}

So here a temporary variable temp is used to check the status of i/p and temp variable is assigned the value as-
temp = PINB & B00000001;

If switch is not pressed then temp will have the value of B00000001 as PB0 i/p pin is high. When switch is pressed then i/p pin PB0 becomes low and so “and” operation will make temp value as B00000000.  

Note- 

Assigning a port pin value using digitalWrite() function is an easier method instead of using PORTB value assignment but if you need to set more than one pin to logic high then you need to write individual statements of digitalWrite() for individual pins and this means that all pins will not be raised to logic high at the same time though that delay is very small but can create certain performance issues when a port pin is driving a heavy load with the help of interfacing circuits. Assigning values to a complete port using port value assignment strategy can remove this delay and all the pins can be raised to logic high at the same time.

THNAKS FOR READING…….

UMESH DUTTA

1 comment: