Monday 8 August 2016

Lesson 10 Multiplexing of Seven Segment Display with PIC Microcontroller - MikroC

In the previous tutorial we showed how to interface Seven Segment Display(SSD) with PIC microcontroller. For most applications like in digital clocks, meters, etc, it usually require more SSD units.
One SSD takes up 7 i/o ports of the microcontroller, that means 2 SSD will consume 14 i/o ports and 3 will take up 21 i/o ports excluding the decimal connection. This is not reasonable, being that the SSD unit can be just a part of a big project you intend to build.

There's a technique that can be used to serve up i/o ports of the microcontroller. This is called multiplexing.
Multiplexing uses Persistence of Vision of human eyes. Human eyes cannot detect visual changes at a rate of 25 frames/sec. This means any transition effect in which the time difference is less than 1/25 sec, the human eye will not notice it.

This concept is used in Multiplexing of SSD. Only one out the  4 SSD units  used in this project comes ON at a time, but they change their ON/OFF condition very fast creating the impression that all the digits are ON at the same time. The Proteus Schematic is shown below

Proteus Schematic

In the Proteus Schematic above, SSD is connected to PORT B and the transistors (which act like a switch) are connected to PORT A.
The 1st byte which represent Unit digit is sent to the SSD via PORT B and the 1st transistor is activated at the same time, after a short time it is turned OFF.
The tens digit is sent to the SSD, and the corresponding transistor is activated at the same time, after a short time, it is turned OFF. This same is repeated for the hundred and thousand byte.
The whole process is continuously repeated at high speed for all digit and their corresponding transistors.

*** Please note on Easy PIC V7, the SSD unit is connected to PORT D. In our Proteus design we used PORTB. Also the code below is for 18F45K22 which is the chip that comes with Easy PIC V7. To use with 16F877A comment out ANSELA and ANSELD

MikroC Code:

/**********************************
Project Name :
   Multiplexing of 7 segment display with PIC 18F45K22
Author : Promise
Description :
   This project demonstrate multiplexing of 4 7 segment display. it counts from 0000 - 9999
Test configuration:
   MCU:  PIC 18F45K22
   Oscillator: XT 8.0000 MHz
   Dev Board : Easy Pic v7
 turn on switches SW4.0, SW4.1, SW4.2, SW4.3
***********************************/


unsigned int unit,tens,hundreds,thousand ;
unsigned int counter = 0;
unsigned int digit = 0;


 unsigned int display(unsigned int digit1) {

   unsigned int my_digit;
   unsigned int array[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; // array holding common cathode 7 segment look up table for 0-9
   my_digit = array[digit1];
   return (my_digit) ;
     
     }
 

 void short_delay(){    // delay function to control how digit is incremented

     if(counter<100){
      counter++  ;
      if(counter==100){
      digit++ ;
      counter = 0;  }
      if(digit==9999){
      digit = 0;
      }
  }
           }

void main() {

 ANSELA = 0;
 ANSELD = 0;
  TRISD = 0x00;    // set PORTD as output
  TRISA = 0x00;

  TRISA.F0 = 0;    // set PORTA bit 0-3 as output
  TRISA.F1 = 0;
  TRISA.F2 = 0;
  TRISA.F3 = 0;

   PortA.F0 = 0;  //turn off PORTA bit 0-3
   PortA.F1 = 0;
   PortA.F2 = 0;
   PortA.F3 = 0;

 while(1) {
   
  short_delay();                    // call delay function

   unit = digit % 10 ;               //extract unit from digit
   PORTD = display(unit);            // send  unit value to PORTD
   PortA.F0 = 1;                     // turn ON 1st 7 segment (LSD 7 Segment display)
   PortA.F1 = 0;
   PortA.F2 = 0;
   PortA.F3 = 0;
   delay_ms(1);
   PortA.F0 = 0;

   tens =  (digit / 10) % 10 ;        //extract tens from digit
   PORTD = display(tens);              // send tens value to PORTD
   PortA.F0 = 0;
   PortA.F1 = 1;                       // turn ON 2nd 7 segment
   PortA.F2 = 0;
   PortA.F3 = 0;
   delay_ms(1);
   PortA.F1 = 0;

   hundreds =  (digit / 100) % 10;    //extract hundreds from digit
  PORTD = display(hundreds);          // send hundreds value to PORTD
   PortA.F0 = 0;
   PortA.F1 = 0;
   PortA.F2 = 1;                      // turn ON 3rd 7 segment
   PortA.F3 = 0;
   delay_ms(1);
   PortA.F2 = 0;

    thousand =  digit / 1000 ;        //extract thousand from digit
  PORTD = display(thousand);           // send  thousand value to PORTD
   PortA.F0 = 0;
   PortA.F1 = 0;
   PortA.F2 = 0;
   PortA.F3 = 1;                       // turn ON 4th 7 segment
   delay_ms(1);
   PortA.F3 = 0;
   }
}

2 comments:

  1. Replies
    1. ANSELA and ANSELD is used to configure the adc pins of PORT A and PORT D to be digital for 18F45K22. For 16F877A comment that line of code and replace with ADCON1 =0x07; thank you

      Delete