Output (Hello World)

There is always a Hello World example to start learning something. This one is the hello world for AVR controllers.

Objective : Animate some LEDs using the digital output pins of an AVR microcontroller.

REMINDER : If you haven’t read the Conventions, read it before going any further.

Parts list :

  1. ATmega8 – 1pcs
  2.  Resistor –
    1. 1K – 8pcs
    2. 10K – 1pcs
  3. Capacitor –
    1. 0.1 uF 25 V electrolytic – 1pcs
  4. LED – 8 pcs

We are going to use ATmega 8 controllers. There are 2 versions of it – ATmega8A, ATmega8L. The version is for high power(4.5-5.5V) high speed(max 16MHz) and is for low power(2.8-5.5V) low speed(max 8MHz). Reader can use anyone of them as I will be using it at 1MHz speed. Well of course you can vary the clock speed within some range.

Let me first explain the meaning of 1MHz cpu clock speed – it means the controller will take 1 clock cycle to execute 1 instruction. So for 1MHz speed, the cpu will execute 1M instructions per second. And thanks to the manufacturer, this clock can be generated internally.

In ATmega series, the width of the internal registers is 8bit. So the input/output pins of the controller are divided into groups of 8 pins. You can consider a byte analogous to the pins like this –

MSB LSB
7 6 5 4 3 2 1 0
I/O Pin 7 I/O Pin 6 I/O Pin 5 I/O Pin 4 I/O Pin 3 I/O Pin 2 I/O Pin 1 I/O Pin 0

You can see the pin numbers associate to the bit positions. So if you want to use I/O pin 3, you need to use the 4th bit of the respective register.

If you look at the pin diagram of ATmega8 from the datasheet, there are total 23 I/O pins which are grouped into 3 groups – Port B, C and D. Group B and D each has 8 pins while the group C has 7 pins. Pins are marked like this- PC0, PB3, PD4. According to the datasheet the 8th bit for group C should be read as zero.

There are 3 registers for each group to control the pins. They are –

  1. DDRx – Data Direction Register of group x(B,C or D)
  2. PORTx – Data Register of group x
  3. PINx – Port Input Register of group x

Let’s say we want to output 5V to the 5th pin of group B. To do that we follow this procedure in the code –

  1. Define the data direction of the target pin –
    DDRB |= (1<<PB5);
  2. Write 1 to the target pin to output 5V –
    PORTB |= (1<<PB5);

If you don’t understand the above, please learn the bitwise operators of C first. They are frequently used in microcontroller programming. Here’s the wiki link for the bitwise operators of C.

Let’s move towards our target now. We want to animate 8 LEDs like this –

00000001
00000010
00000100
00001000
00010000
00100000
01000000
10000000
01000000
00100000
00010000
00001000
00000100
00000010
00000001

The 1s are the LEDs which are lighting. To make it visible, we will delay some time(100ms) after lightening up one LED. There’s a built-in macro for this –

_delay_ms(x)

x refers to the milliseconds to be delayed. Now create the following circuit –

Screenshot from 2016-03-09 08-44-56

CAUTION : Check the power buses before powering up the circuit.

Now create a project and name it as output-hello_world. You can download the project from here.

You already have some idea about the code. Lets fill it up –


#include <avr/io.h>
#include <util/delay.h>

int main(){
    DDRB = 0xFF;
    while(1){
        for(uint8_t rotator=0x01; rotator < 0x80; rotator<<=1){ 
            PORTB = rotator;
            _delay_ms(100);
 	}
 	for(uint8_t rotator=0x80; rotator > 0x01; rotator>>=1){
	   PORTB = rotator;
	   _delay_ms(100);
	}
    }
    return 0;
}

Create a main.c file inside firmware/src and copy-paste the above code or you can always go to the Repository and browse the project files. Though I have used = to assign values to the registers, it’s better approach to use |= instead.

All done ! Now program your controller and see what happens. Here’s a demo of this project –

Let’s talk about the electrical characteristics of this circuit. Datasheet says, the max output current of a output pin is 40mA. But an LED requires much less current than that. So we include a resistor between the pin and LED, say it’s R. Let’s say the current through an LED is I and the output voltage of the pin is V(=5V). So applying KVL gives us –

V = IR + 1.8 [voltage drop across the LED is assumed 1.8 V for a Red LED]

=> I = (V – 1.8)\R = (5-1.8) \1000

=> I= 3.2mA

This current is enough to light up the LED. If you need to limit the current more, change the R value. But limiting current will result in decreasing radiance. This becomes a great deal when using thousands of LEDs.

It’s not much, but it’s a start. There are a lot more features waiting for you to be experimented. So what are you waiting for ?

TASK : Can you do some more animations ? Use your imagination.

TASK : Explore the project files , Makefiles for better understanding.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s