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.


Wednesday, July 15, 2020

Button with AVR ATmega16


Hardware:-

An LED is connected on PB0 pin & and a button is connected on PA0 pin such that when button is pressed, input value will be logic 0 else it will be logic 1

Theory:-

In this tutorial, we will light up the led when button pressed & keep led off when button is free.
In order to achieve the aim, we need to do following things:-
1)      Read the state of the button
2)      Update the state of LED according to button.

Read the state of the button:-
To read the button, first of all microcontroller pin on which button is connected needs to be declare as input. AVR have register with name DDRx ( Data Direction Register), where x can be A,B,C or D depending on what pin group we are using.  DDRx is a 8 bit register in which each bit is associated with one particular pin of group x ( LSB bit associated with pin0 of the group & MSB bit associated with pin7 of the group). If DDRx bit is defined as logic ‘1’ then pin will act as output pin & if DDRx bit is defined as logic ‘0’ then pin will act as an input.
In our case, as button is connected with PA0 pin, so, we have to declare as input pin:-
DDRA = 0b11111110;
As we are not going to use pins PA7 to PA1, so we can declare them as input or output, It doesn’t matter. I have declared them as output so that you can easily differentiate it with PA0 ( button pin ).

Till now we have only declare input pin, but we didn’t read the input value yet. In order to read input value of pins, AVR have register with name PINx, where x can be A,B,C or D depending on what pin group we are using.  PINx is a 8 bit register in which each bit is associated with one particular pin of group x ( LSB bit associated with pin0 of the group & MSB bit associated with pin7 of the group). If PINx bit is logic ‘1’ then pin is receiving 5V on it & if PINx bit is logic ‘0’ then pin is receiving 0V on it. Let’s take a variable to store the PINx value.
char input;
Note:- The reason I have taken char type input is that, both char & PINx are of 8-bit (1 byte).
Now lets the PINx value. As button is connected at PA0, so x = A:-
input  = PINA;
We are not done with reading the input value yet. The variable input is reading all bit of PINA, but we are interested only in PA0. To hide remaining bits value, let’s apply ‘&’ operation such that the result is only having PINA0 value:-
input = PINA & 0b00000001;

Update the state of LED according to button:-
To declare the output value of LED, first of all we need to declare LED pin as output:-
DDRB=0b00000001;
As we are not going to use pins PB7 to PB1, so we can declare them as input or output, I doesn’t matter. I have declared them as input so that you can easily differentiate it with PB0 ( LED pin ).
Now, in an infinite loop, keep LED ON when button is pressed & keep LED OFF when button is released.

while(1)
{
    if(input == 0b00000000)   // button is pressed
    {
        PORTB = 0b00000001;
    }
    else                                     // button is released
    {
        PORTB = 0b00000000;
    }
}

Now, we have discussed the different aspects of the program. It’s time to integrate all of them & right down a final program. But before that, lets simplify each step of the program:-



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:-
#include <avr/io.h>

Step3:- In main() function, define output & input pins:-
DDRB = 0b00000001;
DDRA = 0b11111110;

Step4:- Declare a variable to store input (button) value:-
char input;

Step5:- In an infinite loop, check input value & set LED state accordingly:-
while(1)
{
    input = PINA;
    If(input == 0b00000000)   // button is pressed
    {
        PORTB = 0b00000001;
    }
    Else                                       // button is released
    {
        PORTB = 0b00000000;
    }
}

Final program:-

#define F_CPU 1000000UL

#include <avr/io.h>

int main(void)

{

    DDRB = 0b00000001;

    DDRA = 0b11111110;

    char input;

    while(1)

    {

        input = PINA;

        if(input == 0b00000000)   // button is pressed

        {

            PORTB = 0b00000001;

        }

        else                                      // button is released

        {

            PORTB = 0b00000000;

        }

    }

}



Click Here to download the code.

LED Blinking with AVR ATmega16

Hardware:-

8 LED are connected on group B ( i.e PB0 to PB7).

Theory:-
In AVR, in order to blink led we need to do the following things:-

1)      Declare those pins as an output on which LED are connected
2)      Keep changing state of output ( change logic 0 to 1 & vice versa) with some delay.

Declare pin as output:-
In order to declare pin as a general-purpose output pin, AVR have 'register' with name DDRx ( Data Direction Register), where x can be A, B, C, or D depending on what pin group we are using.  DDRx is an 8-bit register in which each bit is associated with one particular pin of group x ( LSB bit associated with pin0 of the group & MSB bit associated with pin7 of the group). If DDRx bit is defined as logic ‘1’ then the pin will act as output pin & if DDRx bit is defined as logic ‘0’ then the pin will act as an input.
          In our case, as all led are connected with group B, so, we have to declare pins of the group be as output pins:-
DDRB = 0b11111111;

Define output value:-
In order to define the output value of pins, AVR have 'register' with name PORTx, where x can be A, B, C, or D depending on what pin group we are using.  PORTx is an 8-bit register in which each bit is associated with one particular pin of group x ( LSB bit associated with pin0 of the group & MSB bit associated with pin7 of the group). If PORTx bit is defined as logic ‘1’ then pin will have logic high on the pin & if PORTx bit is defined as logic ‘0’ then pin will have logic low on the pin.

Let’s define logic high on all LED pins:-
PORTB=0b11111111;

Also, let’s define logic low on all led pins:-
PORTB=0b00000000;

Providing delay in the program:-
To provide a delay in the program, there is an inbuilt library “delay.h”. We need to declare this library as follows:-
#include <util/delay.h>

Now, to declare a delay, we have following function:-
_delay_ms(milliseconds);
So, to define 1 second, the value of “milliseconds” will be “1000”:-
_delay_ms(1000);


Now, we have discussed the different aspects of the program. It’s time to integrate all of them & right down a final program. But before that, lets simplify each step of the program:-

Step1:- Define the 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:- In main() function, define output pins:-
DDRB=0b11111111;

Step4:- In an infinite loop, toggle the state of output with some delay:-
PORTB=0b11111111;
_delay_ms(1000);
PORTB=0b00000000;
_delay_ms(1000);

Final program:-

#define F_CPU 1000000UL
#include <avr/io.h>
#include <util/delay.h>
int main(void)
{
    DDRB=0b11111111;
    while(1)
    {
        PORTB=0b11111111;
        _delay_ms(1000);
        PORTB=0b00000000;
        _delay_ms(1000);
    }
}


Click Here To Download the code.

Monday, July 6, 2020

HOME

The world is moving towards virtuality in leaps and bounds. As a result, learning IOT & gain knowledge of Microcontrollers, Linux systems, coding languages such as C, C++, Python, etc are really needed to boost your career.
             This blog is an attempt to provide a platform for those who really keen to learn & give something great to society. Keep following this blog to gain valuable knowledge that might change you career.






Our latest videos:-