Once you have your programming rig set up and you are ready to start programming your first AVR chip, the first thing you’ll want to try is lighting or flashing an LED – the ‘hello world’ of embedded hardware. So we are going to look at the three different ways of controlling output pins on your AVR using some simple C code.

 Configuring pins as outputs

Your AVR microcontroller will likely have a number of GPIO (General Purpose Input/Output) pins – these are pins on the microcontroller which can, as the name suggests, be used for either inputs or outputs, depending on how they are configured.

For this tutorial, I will use the ATMega328p as an example chip. Here is the pinout for this particular microcontroller:

On this ATMega328p, all of the pins which are labelled starting with are GPIO pins (PB1, PB4, PC2, PD5 etc.)

The first step is to select a pin you’d like to use and configure it as an output. Let’s say we want to control pin PB2 for example – here is some code we could use to configure it as an output annotated with explanations:

Here we have set the values of the Data Direction Register for PORT B to all be ‘1’. This configures all of the pins to be outputs. Similarly, if we wanted to use them all as inputs, we would set them all to have the value ‘0’.

This is fine is you are only using outputs on one particular port, but if you require a mix of inputs and outputs on a single port, we require the ability to set just a single select bit as a ‘1’. This can be achieved by shifting a bit into the register until it is where we want it to be using the bitwise (<< left shift, or >> right shift) operator. So to set PB2 only as an output we could write instead :

DDRB |= (1 << PD2)

The vertical line being there as a bitwise OR, so that the rest of the register remains unchanged. Using many AVR compilers which use the avr-libc headers, _BV() is defined as being (1 << ) so we can conveniently also write:

DDRB |= _BV(PB2)

The ‘BV’ standing for ‘Bit Value’.

Turning pins on and off

Now everything is configured correctly, it gets to the exciting bit – actually turning pins on and off. This can be done in a very similar way, except, instead of writing to the DDR we write to the PIN. For example to now turn on PB2 we could use:

PINB |= (1 << PD2);

or

PINB |= _BV(PB2);

from now on I will use the ‘_BV()’ notation for convenience, but both achieve the same outcome.

In this is all very well in it’s self, but now lets look at how we can flash an LED. Here is some sample code to flash an LED annotated with an explanation of how it works.

Note the synax to turn off a pin is to use a bitwise AND with the pin, and a bitwise NOT (~). ie.

PINB &= ~(1 << PD2)

or

PINB &= ~_BV(PB2)

If an LED is then connected to PB2 (via a protective resistor! to ground) we will then see the LED flashing on and off every second indefinitely, as per the program we wrote above.

There are no comments.

Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">