Difference between revisions of "AVR Programming"

From CCRMA Wiki
Jump to: navigation, search
(No difference)

Revision as of 15:10, 21 June 2007

Anatomy of a C program for AVR

The following presents a rough overview and breakdown of a demo program from the avrlib-demos. The code is in the avrlib-demos in the button directory in the file button.c. Details of C syntax and AVR-specific commands will follow.

  • The first portion of a C program is usually a bunch of comments that describe the file. Usually this includes the name, author, and date of the file; a revision history; and directions on how to use the file.
      //---------------------------------------------------
      //---------------------------------------------------
      //
      //  AVRLIB-DEMO
      //  For avrlib and avrmini development board.
      //
      //
      //  File:     button.c
      //  Author:   Wendy Ju
      //            based on code written by Michael Gurevich & Matt Wright
      //
      // Revision History:
      // When           Who               Description of change
      // -----------  -----------         -----------------------
      // 04-Oct-2004  Wendy Ju            Created a new instance
      // 01-Jun-2006  Michael Gurevich    makefile->mega32, superfluous #includes
      //
      //---------------------------------------------------
      //  USING THE AVRMINI DEVELOPMENT BOARD, CONNECT
      //  THE LED/PUSHBUTTON JUMPER TO THE PORT B JUMPER.
      //---------------------------------------------------
      //
      //---------------------------------------------------
      //  This program will cause LED 0 to light when corresponding
      //  pushbutton 4 is pressed.
      //---------------------------------------------------
  • Next are #includes. They tell the compiler where to look for other bits of code you are using that do not reside in this file. They are normally ".h" or header files that contain macros and function prototypes. Before a the .c file is compiled, the contents of the #includes are literally copied into the file.
      // compiler includes
      #include <avr/io.h>

      // avrlib includes
      #include "global.h"
  • #defines are "macros". Before the program is compiled, the argument of the #define is simply substituted everywhere the name is used. They are handy for giving meaningful names to numbers and for changing a single value that may be used numerous times in a program without having to change every instance.
      #define DELAY 1000
  • Function prototypes give the name, arguments and return type of functions that will be used later in the program. They can be included in header files or in the .c file before the function is defined.
      int checkButton(int whichButton);
      void setLED(int whichLED, int on);
  • The main function is literally the main part of the code. There can only be one main function in the final compiled program. The code inside the main function is executed sequentially, one line at a time.
      int main(void) {

        // set LED pins as outputs,  button pins as inputs
        outb(DDRB, 0x0F);

        // Turn off LEDs - looking at the circuit
        // you can see that they are off when pulled high
        outb(PORTB, 0xFF);

        while(1) {  // loop forever
          setLED(0, checkButton(4));
          //sampling delay goes here
        }

        return 0;
      }
  • Finally, there are function definitions. These are pieces of code that are called from the main function or from other functions, that have a specific functionality that may want to be used over and over.
      int checkButton(whichButton) {
        // On our boards the four buttons are numbered 4, 5, 6, and 7

        return (! bit_is_set(PINB,whichButton));
        /* Logical negation is because when the button is pushed, the pin
           is drawn to ground, so the button is "on" when the bit is zero. */
      }

      void setLED(int whichLED, int on) {
        // On our board the four buttons are numbered 0, 1, 2, and 3

        if (on) {
          //light the LED
          cbi(PORTB,whichLED);
        } else {
          //turn off the LED
          sbi(PORTB,whichLED);
        }
      }