Saturday, February 25, 2012

Interfacing 7 segment displays with AVR (ATmega32)

Recently, I had the opportunity to give a workshop on AVR microcontroller in American International University of Bangladesh (AIUB). I had prepared some codes for the conference, which I will share here.

7 Segment displays can be readily interfaced to the AVR by applying high or low output to their pins from an AVR. For my circuit I had used a common anode 7 seg display.






This figure shows the basic connection. To increase port usage, multiple 7 segment displays can be time multiplexed and the anode pin is controlled with a seperate pin. (This technique was actually shown to me first by my friend UM Omee)

The same block is copied to form this structure:



Finally the 7 segment displays are driven with the help of a ULN2803 IC. The 2803 is a combination of 8 darlington pair ICs, each capable of sinking 1000mA current. 

The final circuit is shown as follows:



For accessing single pins of the portA, the SFR_MEM_ADDR command is used. The given code example uses only two seven segment displays. It is essentially a mod 100 counter.

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


/* Code for single pin addressing */
typedef struct 
{ 
  unsigned char bit0:1; 
  unsigned char bit1:1; 
  unsigned char bit2:1; 
  unsigned char bit3:1; 
  unsigned char bit4:1; 
  unsigned char bit5:1; 
  unsigned char bit6:1; 
  unsigned char bit7:1; 
}io_reg; 

#define D0      ((volatile io_reg*)_SFR_MEM_ADDR(PORTA))->bit4
#define D1      ((volatile io_reg*)_SFR_MEM_ADDR(PORTA))->bit5
#define D2      ((volatile io_reg*)_SFR_MEM_ADDR(PORTA))->bit6
#define D3      ((volatile io_reg*)_SFR_MEM_ADDR(PORTA))->bit7

/* Code for 7 seg display */
static unsigned  char SEVEN_SEG[] = {
0x3F,
0x06,
0x5B,
0x4F,
0x66,
0x6D,
0x7D,
0x07,
0x7F,
0x6F,
0x77,
0x7C,
0x39,
0x5E,
0x79,
0x71};


int main (void) {
unsigned char num = 0x01;
int i;

DDRB = 0xFF;
DDRA = 0xFF;



while (1) {

 num ++;
 if (num> 99) num = 0;


 for (i=0; i<10; i++) {
  D0=0;
  D1=0;
  PORTB = SEVEN_SEG[num%10];
  D0=1;
  D1=0;
  _delay_ms(10);
  D0=0;
  D1=0;
  PORTB = SEVEN_SEG[num/10];
  D0=0;
  D1=1;
  _delay_ms(10);
  }
 }

}

So this is how the output looks like in Proteus:


Researcher and academician by Trade. Hobbyist webdeveloper, photographer and ametuer musician.

8 comments:

  1. do u help me to burn hex file into AT89C51 uc?

    ReplyDelete
  2. excellent post about seven segment driving. especially the proteus simulation, the way shown is very nice. but i think u shouldn't provide delay of 1 sec

    ReplyDelete
  3. Thank you very much its working

    ReplyDelete
  4. Sajid, I want to build this project, but what is the value of the crystal and the value of the fuse bits? You you help me on these? Tq

    ReplyDelete
  5. Is the Proteus/isis project available. Thank you.

    ReplyDelete
  6. Thx, nice code.
    Sad that y finish to write your blog, it was pretty useful.

    Best regards
    Toby, online data room

    ReplyDelete
  7. good night.. I'm useing the Max7221 but I've a question:
    I put tow ic of max7221 and connect the output of the first one to input of the second and connect ss and clk.. my question is how I chose the second Ic to write data on it... the second 8 7segments
    on avr studio - spi
    thank you

    ReplyDelete

Visit My Official Website at BUET

Contact Me
Sajid Choudhury
+9665650
Dhaka, Bangladesh