MCU Examples.com
PIC Microcontroller Project Examples, free source codes and resources collection.


 

Using multiple seven segment displays with PIC MCU

( Multiplexed seven segments operation with PIC )

Seven segment displays has several advantages over LCD displays. Most notably they have great visibility over long distance and in higher environment lights, wide viewing angle and more stable in higher and lower temperatures. However with standard seven segment displays we can only display digits and several English letters.  

These displays available in single display units as well as multiple units. Also common anode and common cathode types are commonly available.

This example demonstrates usage of 4 common anode seven segment display units. It operates in each relevant cathodes of all segment display units connected together and each common anode of display unit is controlled via 2N3906 PNP transistor through PICs PORTB 0:3 pins.

Program uses interrupt to generate 10mS time base and for each 10mS, it will enable one seven segment display unit via PORTB 0:4 control lines. Then relevant display data will be sent via PORTD to individual segment LEDs. Up to 6 seven segment LED displays can be handled using this method without significant loss of brightness of each LED segment. This method turns on each seven segment display unit for one in four times. However due to the persistence of vision of human eye and brain, a human can only observe continuously lit up digits instead of only one at a time. Any way for this method to work properly without any blinking, proper timing for each display is important and hence interrupt used here in this example.

This program count seconds using same 10mS interrupt and updates value on seven segment displays to show seconds.

Since this example uses common anode seven segments we have to set segment select lines to HIGH and each segment line to LOW to lit up LED segment.

 

MPLAB project source available at end of the page and OrCAD project is available upon request. (USE forum)









//
// Designed by www.MCUExamples.com
// rasika0612@gmail.com
// Using seven segments, multiplexed mode with 4 seven segment display units
// Timer2 used with interrupt to generate 10mS intervals
// Program will count seconds from 0 to 9999 and roll back
//

#include <p18f4520.h>

#pragma config OSC         =    HS     // 20MHz Crystal, (HS oscillator)
#pragma config PBADEN      =    OFF // PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config WDT         =    OFF // watch dog timer off
#pragma config LVP         =    OFF // Low voltage program off


#define SegmentPORT LATD  // Seven segment LEDS connected to PORTD
#define SEG1 LATBbits.LATB0 // define common pins for each seven segment unit
#define SEG2 LATBbits.LATB1
#define SEG3 LATBbits.LATB2
#define SEG4 LATBbits.LATB3



void InterruptHandlerLow ();
void init_Timer2(void);
void DisplayDigit(unsigned char digit);

unsigned char Segments[4]={0,0,0,0}; // initial values of 4 segments are zeros

unsigned char next_segment=0; //We will start with segment1
unsigned char ticks_10mS=0;

//7Segment LED patterns for digits 0 to 9
                            /*  0     1       2    3    4     5      6       7    8     9  */
unsigned char Value2Pattern[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x98}; 


void main()
{    
    unsigned int number=0,temp;
    TRISD=0;    //make PORTD all out put
    TRISB=0xf0; //make PORTB pins 0:4 o/p and others input( we need only 0:4 pins)
    
    init_Timer2(); //init timer2

    while (1) // count seconds from 0 to 9999 and roll back to 0

    {
        if(ticks_10mS==100)
        {
            ticks_10mS=0; //Start from zero again            
            if(number<9999)
                number++;
            else
                number=0;
            
            Segments[0]=number/1000; // gets 1000's value of number to Segments[0]
            temp=number%1000;
            Segments[1]=temp/100;     // gets 100's of number value to Segments[1]

            temp=temp%100;
            Segments[2]=temp/10;    // gets 10's value of number to Segments[2]
            Segments[3]=temp%10;    // gets 1's value of number to Segments[3]                
        }    
    }
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

#pragma code InterruptVectorLow = 0x18
void InterruptVectorLow (void)
{
  _asm

    goto InterruptHandlerLow //jump to interrupt routine
  _endasm
}

//----------------------------------------------------------------------------
//----------------Low priority interrupt routine------------------------------

#pragma code
#pragma interrupt InterruptHandlerLow


void InterruptHandlerLow ()
{
    if(PIR1bits.TMR2IF==1)    //is this interrupr is due to Timer2 
    { //Yes this is due to timer2
        PIR1bits.TMR2IF    = 0;  // We must clear timer2 int flag by software, sodoing it here
        DisplayDigit(next_segment++); // call seven segment handler which will display digits
        ticks_10mS++;     // we count 10mS units so that we know when ticks_10mS reach 100 we have 1S time

    }
}

//----------------------------------------------------------------------------
//----------------------------------------------------------------------------

void init_Timer2(void)
{
    PR2=223; // with 20Mhz Crystal, this value will generate 9.99mS interrupts
    T2CON=0b01101110; //Turn on timer2 with 1:14 post scale and 1:16 prescale
    
    /*Configure interrupt for Timer2 module*/

    RCONbits.IPEN=1;  //Enable interrupt priority levels
    IPR1bits.TMR2IP=0;//Enable interrupt priority levels for Timer2 module with low priority to timer2
    PIE1bits.TMR2IE=1;//Enable Interrupt for Timer2 Module
    INTCONbits.GIEL=1;//Enable global interrupts
    INTCONbits.GIEH=1;//Enable global interrupts
}

//----------------------------------------------------------------------------

//----------------------------------------------------------------------------

// Seven segment display handler function
// this function takes seven segment number to display as parameter (1 to 4 for this example)
// then will take appropiate number to display from array Segments[]
// Segments[] array has four elements which represents each segment and can have numer 0 to 9
// This function uses Value2Pattern array to resolve 
// 7segment display pattern for given number with in 0 to 9

void DisplayDigit(unsigned char digit)
{
    switch (digit)
    {
        case 0:
                SEG4=0;// turn off last segment

                SEG1=1;// turn on this segment
                break;
        case 1:
                SEG1=0;// turn off last segment
                SEG2=1;// turn on this segment
                break;
        case 2:
                SEG2=0;
                SEG3=1;
                break;
        case 3:
                SEG3=0;
                SEG4=1;
                break;
    }

    /*now we have selected correct seven segment unit for this turn*/

    SegmentPORT=Value2Pattern[Segments[digit]];//Display respective digit pattern
    
    if(digit==3)//If we displayed on 7segment unit 4 we have to reset next_segment counter to start over
        next_segment=0;
}


 

You can download MPLAB project files here


 

Custom Search