6 Digits LED 7-Segment Multiplexing using PIC16F627A




In the post ‘LED 7-Segment Multiplexing‘, I have explained about the concept and benefits of multiplexing. Multiplexing implementation is very similar to driving Led Dot Matrix. I use Timer0 interrupt for switching through each digit. Timer0 or TMR0 is an 8-bit timer which overflows every 256 (0xFF) counts. It’s known that the refresh rate above 50Hz would be enough for human’s eyes to see the display without recognizing the flickering. If I set TMR0 with 1:8 Prescaler, the multiplexing frequency will be

4MHz(internal OSC.)/4(working OSC)/8(prescaler)/256(max counts of TMR0)/6(number of digits) = 81.3 Hz which is good for a display.

Just an example, I have implemented (in Proteus) a 999999-second counter by using 6 Digits LED 7-Segment Multiplexing technique. There are 2 main components in the project, PIC16F627A or PIC16F628 and 6 x LED7-segment display. The schematic shows below. The crystal is 32.768KHz as usual. There is a 10KOhm pull up resistor at RA4 pin as this pin is an open-drain pin as I described in “Open-Drain RA4 pin on PIC Microcontroller“.

The source code in MikroC is listed below: (.hex is also available, please feel free to contact me)

6 Digits LED 7-Segment Multiplexing schematic

//PIC16F627A
//4MHz Internal OSC
//MUX by the MUC itself with Interrupt
//TMR0 .. check the prescelar+delay in scan routine as they are related
//[email protected]
unsigned short number [10] = {
0x5F0x060x9b0x8f0xC60xCd, 0xDD0x07,
0xDf, 0xCf
};
unsigned short digit [6];
unsigned short counter;
unsigned short shift_register;
unsigned short x1;
unsigned short x2;
unsigned short x3;
unsigned short x4;
unsigned short x5;
unsigned short x6;
unsigned short tick;
void interrupt ()
{
    if (INTCON.T0IF)
    {
        //Scan digits with TMR0
        INTCON.T0IF = ;
        if (counter == 5)
        {
            PORTA = number [digit [counter]];
            Delay_us (500);
            shift_register = 0x01;
            PORTB = ~shift_register;
            PORTA = 0x00;
            counter = ;
        } else
        {
            PORTA = number [digit [counter]];
            Delay_us (500);
            shift_register = shift_register << 1;
            PORTB = ~shift_register;
            PORTA = 0x00;
            counter ++;
        }
    }
    if (PIR1.TMR1IF)
    {
        TMR1H = 0x80;
        PIR1.TMR1IF = ;
        tick = 1;
        //update current time
        x6 ++;
        if (x6 > 9)
        {
            x6 = ;
            x5 ++;
            if (x5 > 9)
            {
                x5 = ;
                x4 ++;
                if (x4 > 9)
                {
                    x4 = ;
                    x3 ++;
                    if (x3 > 9)
                    {
                        x3 = ;
                        x2 ++;
                        if (x2 > 9)
                        {
                            x2 = ;
                            x1 ++;
                            if (x1 > 9)
                            {
                                x1 = ;
                            }
                        }
                    }
                }
            }
        }
    }
}
void main ()
{
    //Digital I/O for PORTA
    CMCON = 0x07;
    TRISA = 0x00;
    PORTA = 0x00;
    TRISB = 0x00;
    PORTB = 0x00;
    //Internal Clock 4MHz
    PCON.OSCF = 1;
    counter = ;
    // Enable TMR0
    OPTION_REG.T0CS = ;
    // Enable Prescaler
    OPTION_REG.PSA = ;
    // PS0,1,2 = 010 = 3
    // 3 means 1:8 prescaler
    // 1:2, 1:4, 1:8, 1:16, 1:32, 1:64, 1:128, 1:256
    OPTION_REG.PS2 = ;
    OPTION_REG.PS1 = 1;
    OPTION_REG.PS0 = ;
    INTCON.T0IF = ;
    INTCON.T0IE = 1;
    INTCON.GIE = 1;
    INTCON.PEIE = 1;
    T1CON = 0x0F;
    TMR1H = 0x80;
    TMR1L = 0x00;
    // Enable TMR1 interrupt
    PIE1.TMR1IE = 1;
    shift_register = 0x01;
    x1 = ;
    x2 = ;
    x3 = ;
    x4 = ;
    x5 = ;
    x6 = ;
    while (1)
    {
        if (tick)
        {
            tick = ;
            //update digits
            digit [] = x1;
            digit [1] = x2;
            digit [2] = x3;
            digit [3] = x4;
            digit [4] = x5;
            digit [5] = x6;
        }
    }
}

Source : 6 Digits LED 7-Segment Multiplexing using PIC16F627A

READ  Make your own PIC Programmer using PIC12C508

JLCPCB – Prototype 10 PCBs for $2 (For Any Color)
China’s Largest PCB Prototype Enterprise, 600,000+ Customers & 10,000+ Online Orders Daily
How to Get PCB Cash Coupon from JLCPCB: https://bit.ly/2GMCH9w




Current Project / Post can also be found using:

  • mikroc 7 segment display code
  • digital clock circuit diagram using led display
  • pic16f627a circuits
  • how to put another 7seg in pic16 proteus

Comments (1)

  • naseer najibi

    Dear Sir,

    Thanks for providing detailed information about the counter.

    I have made a pcb and used your software for a project ,

    but the problem was that the segments did not have enough time to be on an give a bright display

    so i worked on software and modified it as following:

    1. I used a 1 msec interrupt timer.

    2.A pic16f887 with internal 8 mHz is used.

    3.modified the circuit so that it can be used for various counting needs.

    4.have added one more digit so that now it is 7 digits.

    and after all the display is very bright and very visible with a very low visible flicker.

    If any body needs the modified software and circuit diagram plus pcb

    Please feel free to contact me I will provide it free of cost.

    Reply

Leave a Comment

*
= 5 + 3

Read previous post:
Digital Clock using PIC16F887
Making your own Digital Clock using PIC16F887

Small LED dot matrix development board I was very busy for the past two months so this blog just didn't...

Close
Scroll to top