If you are New To C then you can consider this a crash course introduction to the language.
C is really not all that hard, so don't be intimidated. You will have to learn to just accept some things in the beginning, and then come back and really learn how they work later on. This approach will get you some real nice results fast, and hopefully keep the frustration factor to a minimum.
Skeleton File
Some aspects of programming are just plain tedious. We always start new AVR C programs with a skeleton file that sets up everything for us, and gets us ready to solve the real problems in a project. We will show you our skeleton file, and then explain exactly what each part does.
// ********************************************************************************
// Includes
// ********************************************************************************
#include <avr/io.h>
#include <avr/interrupt.h>
#include <stdbool.h>
#include <avr/eeprom.h>
#include <stdio.h>
#include <string.h>
#include <avr/pgmspace.h>
// ********************************************************************************
// Macros and Defines
// ********************************************************************************
// ********************************************************************************
// Function Prototypes
// ********************************************************************************
// ********************************************************************************
// Global Variables
// ********************************************************************************
// ********************************************************************************
// Main
// ********************************************************************************
int main(void) {
ÃÂ ÃÂ ÃÂ ÃÂ // initialize code
// main loop
while (true) {
// do stuff here
}
}
You can download the complete source code here.
So Many Comments, So Little Code
Everything in green is a comment and does not contribute to the code size or execution. It is simply for us human processors. For a little skeleton file like this, the comments seem overwhelming. But when your programs get bigger, these green comments are really going to make you happy as they helpfully divide your code up into digestible sections. Let's talk about each of the commented sections briefly.
Includes
Include files, colored in blue here, are how you gain access to the features that are built in to C. You do not need them if you don't want to use them, but they sure make life easier. Including them has zero effect on code size or speed until you actually call on the features that are in them, so it is harmless to include them in every program that you write for now. Here is what each of these includes is for.
- io.h defines the ports that you can use, such as PORTA, PORTB and so on.
- interrupt.h has some useful macros and routines for dealing with internal and external interrupts
- stdbool.h defines true and false so that you can use them in your code. They are optimized for size.
- eeprom.h has functions for reading and writing the on board EEPROM.
- stdio.h is useful for serial port communications, such as printf and scanf.
- pgmspace.h is used to store large strings and other data in Flash until needed, instead of in RAM
To start out with, you should simply include all of these in your program. Later on you can wean out the ones that you don't use. Try leaving them out and hit compile to see all the errors that you get. Not nice at all.
Macros and Defines
Defines are a way of defining a value in your program for your own use. While there are no Macros or Defines listed in the skeleton, there will be in other projects and this is where they will go. Defines are a way of defining something once at the top of your files, and then using it multiple times later on. The precompiler replaces the defines throughout your program with what you define as a replacement before the compiler gets its hands on your code.
They are constant values that never change in your program. For instance, if you are creating a program that turns lights on and off, and you know that you are going to have a maximum of 8 lights ever hooked up, then you might have this code at the top of your program in the Defines section:
#define MAX_LIGHTS 8
Later on in your code you can reference MAX_LIGHTS knowing that the precompiler will later replace it with 8.
Function Prototypes
This is where you will predefine all the functions that you use in your program. In C all functions must be predefined for the compiler. While these sound complicated, they are not. We will get to them later on.
Global Variables
If you need global variables in your program, declare them here. Keep in mind that the C startup code will initialize all global variables for you, so don't waste precious code space reinitializing them.
Main
This is where your code starts. The main function is defined with this line:
int main( void ) {
Put your code after this, but before the last curly brace }. The first line in the main code block is a comment that says initialize code. This is just a reminder to put any initialization code up there, such as turning ports off or firing up timers, turning on interrupts, or starting the UART. Inside the main code block, there is an infinite loop.
while(true) {
In microprocessors code execution never ends, so it makes sense to encapsulate your entire program in an infinite loop. Otherwise, when your code is done running, there is no telling what random the microprocessor will go off and find to run. Bad things may happen if you don't wrap your code in an infinite loop, so definitely get used to it.
Moving On To Some Port I/O
Hopefully at this point you understand most of what is included in this skeleton file. In our next guide we put this file to good use making an LED blink. There isn't much more code to learn and you'll understand exactly what is going on. Continue on to read about Port Output on the AVR. Or head back to our index of AVR Guides here.