AVR Register Manipulation (Accessing I/O Memory)


Hi friends in this tutorial we are going to learn practical use of registers. I hope you have already gone through my earlier tutorial about registers. If not please check it, link is here.

A register is a special storage space in which the state of the bits in the register has some special meaning to the AVR micro-controller. Most of the registers are 8-bits wide (there are a few exceptions).REGISTER

Each one has a name and individual bits may also have unique names or identifiers. All of the register and bit names are described in their respective Data sheets. The AVR library will define identifiers for the register names and bit names so that they can be easily accessed in C.

The basics or AVR programming is to manipulate different bits in various registers. Everything from configuring the AVR device’s built-in peripherals to using the AVR’s pins for digital I/O is done by manipulating bits in these registers.

Access to a Register

As we discussed earlier, the names of the registers are defined in the header file of respective chip. When we need to access any register using C, first thing we got to do is add header files at the start of the program. If you do not know the name of the controller specific header file, just add common header file.

#include <avr/io.h>

As we have added a header, now we have acces to all the registers in particular controller.

Write to a Register

Following assignment is self explanatory and therefore, very little explanation here. Atmel provides a very good article “AVR035: Efficient C Coding for AVR” which you can download it here

 

/* We will make PORTB all pins as output pins, by setting DDRB = 0xff;*/

       DDRB = 0xff;

         //Set(write to register) PORTB to 0x06, so bits one and two high(1), 
         //remaining all low(0)

       PORTB = 0x06;

       //To clear a port

       PORTB = 0x00;

Change of register contents

 

       PORTB |=(1<<PINB0);        // To set(write) a pin high

       PORTB &= ~(1<<PINB0);      // To unset(write) a pin low

 

This was just about PORT, what about using peripheral registers. Let us try and set or unset them.

 

ADCSR &= ~(1<<ADEN); /* Clear ADEN bit in ADCSR register */

TCCR0 = 0x4F; /* Write a value to an I/O location*/

ACSR &= ~(0x0C); /* Clear bit 2 and 3 in ACSR register*/

/* Set and clear bits in I/O registers can also be declared as macros */

I expect you to have knowledge of macros, following way you can set the macros to do the bit operations. If you don’t have sufficient knowledge about macros, please follow this tutorial here.

 

#define SETBIT(ADDRESS,BIT) (ADDRESS |= (1<<BIT))

#define CLEARBIT(ADDRESS,BIT) (ADDRESS &= ~(1<<BIT))

/* Macro for testing of a single bit in an I/O location*/

#define CHECKBIT(ADDRESS,BIT) (ADDRESS & (1<<BIT))

#define BIT_FLIP(ADDRESS,BIT) ((ADDRESS)^=(BIT))

#define BIT(x) (0x01 << (x))

 

Now we have declared the macros, let’s try and use them in an example.

/* Example of usage*/
if(CHECKBIT(PORTD,PIND1)) /* Test if PIN 1 is set*/
{
CLEARBIT(PORTD,PIND1); /* Clear PIN 1 on PORTD*/
}
if(!(CHECKBIT(PORTD,PIND1))) /* Test if PIN 1 is cleared*/
{
SETBIT(PORTD,PIND1); /* Set PIN 1 on PORTD*/
}
Guys if you like this tutorial, please guide us for a new topic you are interested in…Please do like the page on facebook….Thanks!

 

Related posts:

About author

This article was written by admin

Admin has over twenty years experience in the electronics industry, largely dedicated to embedded software. A frequent presenter at conferences and seminars and author of numerous technical articles. Working presently as Development Manager in India. A firm Believer in Knowledge grows when it shared.

Comments

Comments (1)
  1. Ben says - Posted: July 12, 2013

    Thank you.

Leave your comment

Your email address will not be published. Required fields are marked *