Pages

Thursday, July 16, 2020

7-segment display with AVR ATmega16


Introduction:-

First lets understand what seven segment (also known as 7-segment) display is. It is a group of 8 LED (7 segments & 1 dot) of which either all anode or all cathode are common (short). So, each seven segment has 9 pins ( 8 input pins on which we send signals to glow the LED & 1 common pin).




Common Anode 7-segment display:-
Common Anode 7-segment displays are those 7-segment displays in which all led have their positive terminal common & there are separate pin available for each negative terminal of LED. In order to ON any led, you need to give positive voltage on common pin of 7-segment & give ground on particular pin.

Common Cathode 7-segment display:-
Common Cathode 7-segment displays are those 7-segment displays in which all led have their negative terminal common & there are separate pin available for each positive terminal of LED. In order to ON any led, you need to give ground voltage on common pin of 7-segment & give positive voltage on particular pin.

Universal assumptions:-
7-segment display have 8 LED which have name a,b,c,d,e,f,g,h as mentioned in the following image.



Hardware:-

A common cathode 7-segment display is connected with group ‘B’ of AVR ATmega16.


As already shown in schematic, following are the connections of 7-segment display & ATmega16 microcontroller:-


a  ->  PB0
b  ->  PB1
c  ->  PB2
d  ->  PB3
e  ->  PB4
f   ->  PB5
g  ->  PB6
h  ->  PB7 

Theory:-

In this tutorial, I am going to display numbers 0 to 9 using 7-segment display. As clear from the schematic, following should be the value of PORTB to display numbers:-
0         -> PORTB should be 0b00111111
1         -> PORTB should be 0b00000110
2         -> PORTB should be 0b01011011
3         -> PORTB should be 0b01001111
4         -> PORTB should be 0b01100110
5         -> PORTB should be 0b01101101
6         -> PORTB should be 0b01111101
7         -> PORTB should be 0b00000111
8         -> PORTB should be 0b01111111
9         -> PORTB should be 0b01101111


Let’s write a program to display numbers 0 to 9 on seven segment display:-

Step1:- Define frequency on which we are going to work:-
#define F_CPU 1000000UL
Actually, ATmega16 can work up to 20MHz. Also, this microcontroller can generate 1,4 & 8 MHz of frequency internally but if you want more frequency then you have to connect crystal oscillator externally ( on pin 12 & 13).

Step2:- Declare input-output library as well as delay library:-
#include <avr/io.h>
#include <util/delay.h>
Step3:- Let’s define seven segment values which PORTB should have to display numbers:-
char numbers[10] = {0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110, 0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111};
Step4:- Declare a display function in which we will display the number using a switch case:-
void display (int num)
{
     If(num < 10)
    {
        switch(num)
        {
            case 0:
                PORTB = number[0];
                break;
            case 1:
                PORTB = number[1];
                break;
            case 2:
                PORTB = number[2];
                break;
            case 3:
                PORTB = number[3];
                break;
            case 4:
                PORTB = number[4];
                break;
            case 5:
                PORTB = number[5];
                break;
            case 6:
                PORTB = number[6];
                break;
            case 7:
                PORTB = number[7];
                break;
            case 8:
                PORTB = number[8];
                break;
            case 9:
                PORTB = number[9];
                break;
        }
    }
}  
Step5:- In main() function, define output pins:-
DDRB=0b11111111;

Step6:- In infinite loop, run a for loop which will run from value 0 to 9 and call display function according to the current value of the for loop, Also, make sure that there is some delay provided after calling the display() function so that number is displayed for some time.
int count;
while(1)
{
    for(count = 0; count <=9; count++)
    {
        display(count);
        _delay_ms(1000);
    }
}

Final program:-


#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
char numbers[10] = {0b00111111, 0b00000110, 0b01011011, 0b01001111, 0b01100110, 0b01101101, 0b01111101, 0b00000111, 0b01111111, 0b01101111};
void display (int num)
{
     if(num < 10)
    {
        switch(num)
        {
            case 0:
                PORTB = number[0];
                break;
            case 1:
                PORTB = number[1];
                break;
            case 2:
                PORTB = number[2];
                break;
            case 3:
                PORTB = number[3];
                break;
            case 4:
                PORTB = number[4];
                break;
            case 5:
                PORTB = number[5];
                break;
            case 6:
                PORTB = number[6];
                break;
            case 7:
                PORTB = number[7];
                break;
            case 8:
                PORTB = number[8];
                break;
            case 9:
                PORTB = number[9];
                break;
        }
    }
}  

int main(void)
{
    DDRB=0b11111111;
    int count;
    while(1)
    {
        for(count = 0; count <=9; count++)
        {
            display(count);
            _delay_ms(1000);
        }
    }  
}

Click Here to download the code.


No comments: