Seven Segment Display operation using Atmega32 and CD4511B

Seven segment display is a frequently used device found in several applications such as queuing systems, some types of clocks and calculators. So in this article, we explain how to Interface a 7 Segment Display to the AVR Atmega32 MCU and get it working.

Note: We have published several other interfacing tutorials of 7 segment displays like Interfacing 7 segment to 8051, Interfacing  Arduino to 7 Segment Display, and a Proteus Tutorial on 7 Segment display.

Let’s first have a look on the seven-segment display and its pinout.

Pin Out Diagram of 7 Segment Display

The Seven-segment consists of 7 LEDs arranged in a way that allows constructing a display of the numbers of (0-9). It has 10 pins assigned as follows:

  1. 7 pins act as the Vcc for the 7 LEDs (1 pin for each LED, assuming that we are dealing with common cathode seven segment display)
  2. 1 pin is the VCC for decimal point display at the lower right corner.
  3. 2 pins represent a common ground to all the LEDs.
seven segment LED display
7 segment LED display

There are 2 types of seven-segment, that are “common anode” and “common cathode”. In common anode seven segment, VCC is common for all the LEDs and each has a different pin for the low voltage (that is ground). In the case of a common cathode, all LEDs have a common ground and each has a different pin for the high voltage (Vcc). In this tutorial, we will be using a common cathode 7 Segment display.

Interfacing 7 Segment Display with AVR Atmega32:

The straightforward way to do that is to connect each pin from the seven-segment to a pin on the MCU and use the software to control the LEDs lighting and display the numbers we want. However, this way is not efficient as it wastes a lot of valuable MCU pins. Imagine that you want to connect 2 seven-segment devices to display the numbers (0-99), in this case, you will need to use 14 pins of the MCU I/O pins which may leave you in a shortage of pins for other external peripherals.

Fortunately, there is a better way to do it, using the CD4511B IC (BCD to 7 Segment Decoder), shown in the below picture.

CD4511B-IC-PIC

This is an easy to use IC that takes the number you want to display as an input in BCD (Binary Coded Decimal) format and outputs the 7 bits needed to illuminate the seven-segment with the desired number. The below diagram clarifies the input and output to the CD4511B.

CD4511-BlockDiagram_2

The input pins (A, B, C, D) take the input number as BCD and the output pins (a, b, c, d, e, f, g) are the 7 bits output that will be connected to the seven-segment as will be demonstrated in the schematic.

For more clarity, the below table shows the inputs and corresponding outputs of the CD4511B:

Hard wired Input coming from MCU Output to the seven-segment
LE BL LT D C B A a b c d e f g Number displayed Comment
X x 0 x X x x 1 1 1 1 1 1 1 8 Used for testing the display
X 0 1 x X x x 0 0 0 0 0 0 0 Blank Used for testing the display
0 1 1 0 0 0 0 1 1 1 1 1 1 0 0
0 1 1 0 0 0 1 0 1 1 0 0 0 0 1
0 1 1 0 0 1 0 1 1 0 1 1 0 1 2
0 1 1 0 0 1 1 1 1 1 1 0 0 1 3
0 1 1 0 1 0 0 0 1 1 0 0 1 1 4
0 1 1 0 1 0 1 1 0 1 1 0 1 1 5
0 1 1 0 1 1 0 0 0 1 1 1 1 1 6
0 1 1 0 1 1 1 1 1 1 0 0 0 0 7
0 1 1 1 0 0 0 1 1 1 1 1 1 1 8
0 1 1 1 0 0 1 1 1 1 0 0 1 1 9
0 1 1 1 0 1 0 0 0 0 0 0 0 0 Blank
0 1 1 1 0 1 1 0 0 0 0 0 0 0 Blank
0 1 1 1 1 0 0 0 0 0 0 0 0 0 Blank
0 1 1 1 1 0 1 0 0 0 0 0 0 0 Blank
0 1 1 1 1 1 0 0 0 0 0 0 0 0 Blank
0 1 1 1 1 1 1 0 0 0 0 0 0 0 Blank

Using the CD4511B IC allows us even to connect more than 1 seven-segment on the same 4 pins of the MCU. In such case, we will add a BJT transistor between the cathode of each seven-segment and the ground and use the base of this BJT as an enable bit for each seven-segment as demonstrated in the schematic.

Interface AVR to 7 Segment Display

In such case, we save around 10 pins, as we connect 2 seven-segments with only 4 MCU pins.

Now, according to the above schematic, in order to illuminate the two seven-segments at the same time, we need to follow these steps:

  1. Write BCD of the number we want to display on the first seven-segment on PORTC pins (PC4-7)
  2. Write 1 to PORTC pin 2 (PC2) to enable the first segment.
  3. Allow a delay of 10 ms.
  4. Write 0 to PORTC pin 2 (PC2) to disable the first seven-segment.
  5. Write BCD of the number we want to display on the second seven-segment on PORTC pins (PC4-7)
  6. Write 1 to PORTC pin 3 (PC3) to enable the second seven-segment.
  7. Allow a delay of 10 ms.
  8. Back again to step1.

You might think that this sequence will cause the seven-segments to blink as we enable and disable them, but in fact you will not notice this blinking.

The persistence of the seven-segments LEDs will cause it to stay illuminated after being disabled until it is enabled again in the next cycle.

In our program, we will define a counter that counts from 0 to 99 and displays the counting on the two seven-segments connected as above.

Below is the program code, circuit picture and video.

Program/Code

#define F_CPU 8000000UL

#include <avr/io.h>

#include <util/delay.h>

void Sev_Seg (char Number);


void Sev_Seg (char Number) // Function to write the BCD of a number to the seven segment pins (PC4-7)

{

  switch(Number)    

  {

         case 0:

         { 
                PORTC&=~(1<<5)&~(1<<6)&~(1<<7)&~(1<<4);

                break;

         }

         case 1:

         { 
                PORTC|=(1<<4);

                PORTC&=~(1<<5)&~(1<<6)&~(1<<7);

                break;

         }

         case 2:

         { 
              PORTC|=(1<<5);

              PORTC&=~(1<<4)&~(1<<6)&~(1<<7);

              break;

         }

         case 3:

         { 
                PORTC|=(1<<4)|(1<<5);

                PORTC&=~(1<<6)&~(1<<7);

                break;

         }

         case 4:

         { 
                PORTC|=(1<<6);

                PORTC&=~(1<<4)&~(1<<5)&~(1<<7);

                break;

         }

         case 5:

         { 
                PORTC|=(1<<4)|(1<<6);

                PORTC&=~(1<<5)&~(1<<7);

                break;

         }

         case 6:

         {

                PORTC|=(1<<5)|(1<<6);

                PORTC&=~(1<<4)&~(1<<7);

                break;

         }

         case 7:

         {

                PORTC|=(1<<4)|(1<<5)|(1<<6);

                PORTC&=~(1<<7);

                break;

         }

         case 8:

         {

                PORTC|=(1<<7);

                PORTC&=~(1<<4)&~(1<<5)&~(1<<6);

                break;

         }

         case 9:

         {

                PORTC|=(1<<7)|(1<<4);

                PORTC&=~(1<<5)&~(1<<6);

                break;

         }  } }



int main(void)

{

    char count=0; // This is the variable that will be displayed on the seven-segment

       char i=0;

       DDRC|=0b11111100; // Set direction for port B as output

       PORTC&=0b00000011; // Set the all the seven segment pins to 0 in the beginning


       while(1)

    {

       for (count=0;count<=99;count++) // This loop is to increment the number that will be displayed

              {




                     for (i=0;i<=17;i++) // This loop introduces some more delay so that the counting is slow enough for our eyes to recognize it

                     {

                           Sev_Seg(count%10); //write the first digit of "count" value to the first seven-segment

                           PORTC|=(1<<2); //Enable the first seven-segment

                           _delay_ms(10);

                           PORTC&=~(1<<2); //disable the first seven-segment

                           Sev_Seg(count/10); //write the second digit of "count" value to the second seven-segment

                           PORTC|=(1<<3); //Enable the second seven-segment

                           _delay_ms(10);

                           PORTC&=~(1<<3); //disable the second seven-segment

  } }   } }

Photograph

7-Segment_AVR

Video

Author

2 Comments

  1. Mukund Parelkar

    This 4511 is from the era of BABA AZAM. We had used it in 1970 in engineering project. At least used Intersil 7218 which can display 8 x8 display. With the same number of output pins you can get 8×8 display. If you use IIC BUS, only two output pins will be used.
    I doubt whether you will get CD4511 in the market.

    • jojo

      @Mukund – Thanks for the comment. The IC is still available in the market(online and offline). It’s still good to have an idea about obsolete components. Let me know if you would like to contribute to our website by writing articles.