博客文章 -

Seven Segment Display Operation by Using Atmega32 and CD4511B

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

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.                               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. 

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,you also can get more information from the data-sheet of CD4511B

Hard wiredInput coming from MCUOutput to the seven-segment
LEBLLTDCBAabcdefgNumber displayedComment
Xx0xXxx11111118Used for testing the display
X01xXxx0000000BlankUsed for testing the display
011000011111100
011000101100001
011001011011012
011001111110013
011010001100114
011010110110115
011011000111116
011011111100007
011100011111118
011100111100119
01110100000000Blank
01110110000000Blank
01111000000000Blank
01111010000000Blank
01111100000000Blank
01111110000000Blank

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.

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

Video