Programming AVR: a helpful header file with input/output macro functions


avriomacros.txt (1387Bytes)
iomacros.h.txt (2076Bytes)


Programming AVRs can be difficult for people with little experience in C programming. I think one of the things that is tricky is understanding bitwise operators. Bitwise operators such as |, &, <<, and >> are commonly used for declaring programmable digital IO as either inputs or outputs, setting outputs high or low, reading a digital input, and also setting internal pullup resistors.

This is why I created a header file with macro functions to accomplish these basic input and output tasks, and also because I was tired of copying and pasting the code from old projects, and I also think it looks cleaner. Using the avriomacros.h header file with an avr project is fairly simple and straight forward with AVR Studio:

  1. copy and paste the header file in the same folder as the c file
  2. right click the header files folder icon in AVR Studio project tree and click add existing header files (see picture)
  3. browse and select avriomacros.h
  4. put #include "avriomacros.h" at the top of the c file

Examples of using avriomacros.h:

with the following input defined:

#define BUTTON        PB2

and output defined (note that both reside with register B):

#define LED            PB3

to define the button as an input:


to define the LED as an output:


where the first input is the bit (or pin) and the second input is the register (using register B which is the "B" in "PB2")

to turn on the LED:


to set the internal pullup resistor for the button:


to read the value or state of the button input:



The other macro functions are similar, just see the attached header file for a description of each. The file "avriomacros.txt" needs to be renamed to "avriomacros.h" to use- I had to change it due to file extension restrictions when uploading to LMR.

In case anyone is interested in what the dual ## signs do in the macros see the bottom of this post on the C preprocessor, specifically Pasting Tokens. Please also note I'm open to criticism!


The previous macro functions worked fine but it was not ideal as it required knowing which port a pin is on, which resulted in looking up pin declarations a lot (if say LED was defined as PB3 then I would know to use port B when calling the macro to turn it off or on).

The new and improved iomacros.h header file will keep track of the port bit for you, it basically requires #define'ing your IO as pin,port (separated by a comma).

Here is the sample usage, which is documented in the header file:

#include <avr/io.h>
#include "iomacros.h"

#define LED        3,B                // declare LED pin and port
#define BUTTON    2,B                // declare BUTTON pin and port

int main (void) {

    out(LED);                    // set LED as an output
    in(BUTTON);                    // set BUTTON as an input
    pullup(BUTTON);                // activate internal pullup resistor for BUTTON
    while(1) {                    // forever loop

        if(get(BUTTON) == 0)    // if button is pressed...
            on(LED);            //     turn on LED
        else                    // otherwise
            off(LED);            //     turn off LED

See the link at the top to download iomacros.h


That reminds me that I had a

That reminds me that I had a AXON2 had been in the corner with heavy dust because I couldn’t find the proper way to connect the AVR programmer to it and bootloader is not working with win7.

Glad to have you post some tips for AVR. looking forward to see more :wink:

Nice little macROSE :smiley:

Nice little macROSE :smiley: anyway this pushes me more into dust :slight_smile: but :smiley: it will be really big help for beginners :smiley:

thanks djhesit8, what do you

thanks djhesit8, what do you mean when you say it  pushes you more into dust?

I mean that I have learned

I mean that I have learned AVR from 0… for me is easier to use |= etc than this :slight_smile: and for sure macro can be made in the soft you ar using… :slight_smile: for me is more simple using the basic AVR GCC code than this macro :slight_smile: but as I see, for beginners it is more easier to use this :slight_smile:

Ok I see, I still end up

Ok I see, I still end up using bitwise operators to set registers for UARTs, interrupts, timers, PWM, etc, but for the basic IO stuff I use these macros as it is quicker for me to write and read, especially when coming back to code that was written in the past.  It especially saves me a lot of time when I use all of the pins on a high pin count AVR.