Skip to main content

Experiment No. 5: Multiplexed Seven Segment Displays

In this experiment, we are going to learn how to interface more than one 7-segment LED display to a PIC Port using multiplexing technique. We are going to interface a 4-digit common cathode seven segment display to our PIC board. The multiplexing circuit is already built up in the board using 4 transistors and few resistors (Read Make Your Own PIC Development Board). The basic idea of multiplexing is that all seven segment displays are connected to the microcontroller in parallel and the microcontroller alternately prints ones, tens, hundreds, and thousands digits, selecting one at a time. The switching among the digits is so fast that it gives an impression of simultaneous light emission.

Experimental Setup:

1. Connect RA0 through RA3 to 7-Segment Digit Select headers DG1, DG2, DG3, and DG4 using jumper wires.
2. Insert 7FR5641AS 4-Digit Seven Segment module in to its place on the board.




Software:
/*
 * Project name:
     4-Digit UP Counter with Four 7-Segment Display Multiplexing
 * Copyright:
     (c) Rajendra Bhatt, 2009.
 * Description:
     This code is an example of multiplexing 4 Seven Segment Displays.

 * Test configuration:
     MCU:             PIC16F628A
     The common cathode of four seven segment dispalys are
     connected to RA0, RA1, RA2 and RA3
*/
//-------------- Function to Return mask for common cathode 7-seg. display
unsigned short mask(unsigned short num) {
  switch (num) {
    case 0 : return 0x3F;
    case 1 : return 0x06;
    case 2 : return 0x5B;
    case 3 : return 0x4F;
    case 4 : return 0x66;
    case 5 : return 0x6D;
    case 6 : return 0x7D;
    case 7 : return 0x07;
    case 8 : return 0x7F;
    case 9 : return 0x6F;
  } //case end
}
unsigned short i, DD0, DD1, DD2, DD3, NUM  ;
void main() {
  CMCON  |= 7;      // Disable Comparators
  TRISB = 0x00;    // Set PORTB direction to be output
  PORTB = 0xff;    // Turn OFF LEDs on PORTB
  TRISA0_bit = 0;  // RA.0 to RA3 Output
  TRISA1_bit = 0;
  TRISA2_bit = 0;
  TRISA3_bit = 0;
  TRISA4_bit = 1;      // RA.4 is Input only

  NUM   =    0;  // Initial Value of Counter

  do {
  DD0 = NUM%10;  // Extract Ones Digit
  DD0 = mask(DD0);
  DD1 = (NUM/10)%10; // Extract Tens Digit
  DD1 = mask(DD1);
  DD2 = (NUM/100)%10; // Extract Hundreds Digit
  DD2 = mask(DD2);
  DD3 = (NUM/1000);  // Extract Thousands Digit
  DD3 = mask(DD3);

  for (i = 0; i<=50; i++) {
      PORTB = DD0;
      RA0_bit = 1;          // Select Ones Digit
      RA1_bit = 0;
      RA2_bit = 0;
      RA3_bit = 0;
      delay_ms(5);
      PORTB = DD1;
      RA0_bit = 0;
      RA1_bit = 1;        // Select Tens Digit
      RA2_bit = 0;
      RA3_bit = 0;
      delay_ms(5);
      PORTB = DD2;
      RA0_bit = 0;
      RA1_bit = 0;
      RA2_bit = 1;         // Select Hundreds Digit
      RA3_bit = 0;
      delay_ms(5);
      PORTB   = DD3;
      RA0_bit = 0;
      RA1_bit = 0;
      RA2_bit = 0;
      RA3_bit = 1;         // Select Thousands Digit
      delay_ms(5);
      }
      NUM = NUM + 1 ;
  } while(1);                             // endless loop
}

Experimental Output Video:


Comments

  1. Hi Raj this project is very helpfull for me in stepping into programming BCD 7 segment project .I manage to run this code well on my board, thanks a lot. Raj, i am also looking to apply timers/interrupt concept to run the same project, could you please post any codes on for this projects applying timers/interrupts?

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. I built a dev board based on your posting but my 4 7-segment leds show 4 zero's and counts to 255 then resets and starts over.... any idea?

    ReplyDelete
  4. This is because the variable NUM is defined as unsigned short (which is 8-bit), so it can hold values only up to 255. Try replacing

    unsigned short i, DD0, DD1, DD2, DD3, NUM ;

    with

    unsigned short i, DD0, DD1, DD2, DD3;
    int NUM;

    and see what happens.

    ReplyDelete
  5. How to drive only using MPLAB assembly code?

    ReplyDelete
  6. Hello RAJ
    Can you please tell me what changes are to be made in above program while using a common anode multiplexed seven segment display?

    ReplyDelete
  7. For common anode display, first you need to make some changes in the circuit (which I hope you would be able to do). Next you have to redefine the return values in the mask() function. Here are the changes:

    unsigned short mask(unsigned short num) {
    switch (num) {
    case 0 : return 0xC0;
    case 1 : return 0xF9;
    case 2 : return 0xA4;
    case 3 : return 0xB0;
    case 4 : return 0x99;
    case 5 : return 0x92;
    case 6 : return 0x7D;
    case 7 : return 0x82;
    case 8 : return 0x80;
    case 9 : return 0x90;
    } //case end
    }

    ReplyDelete
  8. Thanks for telling changes in software. In hardware, I used NPN transistors to switch all segments of the seven segment Display and I connected the selector pins directly to PORTA pins. Can you please tell me whether I changed my hardware correctly or there are to be some further modifications in the hardware?

    Thanks in anticipation.

    ReplyDelete
  9. Sorry, I have made mistake with number 6 & 7. The correct numbers for Common Anode are
    switch (num) {
    case 0 : return 0xC0;
    case 1 : return 0xF9;
    case 2 : return 0xA4;
    case 3 : return 0xB0;
    case 4 : return 0x99;
    case 5 : return 0x92;
    case 6 : return 0x82;
    case 7 : return 0xF8;
    case 8 : return 0x80;
    case 9 : return 0x90;
    } //case end

    ReplyDelete

Post a Comment

Popular posts from this blog

Contact less tachometer using PIC16F628A

Introduction Tachometer is a device that gives you the information about the rotational speed of any shaft or disc. It usually measures the speed in revolutions per minute (RPM). Today we are going to make a simple tachometer that could measure the rotation speed of a disk without making any physical contact (that's why it is contact less) with the rotating object. The range of this tachometer is 0 - 9999 RPM and displays the RPM on a multiplexed 4-digit seven-segment display. Of course, we are going to do this project on our usual PIC16F628A development board. Infrared sensor Contact-less measurement of RPM will be achieved through an IR sensor. An IR diode will send a beam of infrared towards the rotating disc, and any reflected pulse will be received by a photo diode. The resistance of a photo diode drops drastically when exposed to infrared. An infrared is reflected by a white surface and absorbed by the dark ones. The test disc for this project is shown below. You can see

Experiment No. 2 : Push Button and Seven Segment Display Interface

In this experiment, we will program the PIC16F628A as an UP/DOWN Decade Counter. The count value will be displayed on a Seven-Segment Display and will be incremented/decremented by two push buttons on the board. Experimental Setup: The board has built in interface for a multiplexed 4-digit seven segment display (HS-5461AS2 from www.futurlec.com ).We will select only one digit by connecting a Digit Select pin to Vcc, as shown in figure below. A black jumper wire is used for this purpose. The seven segments will be driven through PORTB (already wired on the board). Connect Push Buttons (PB3 and PB4) to RA1 and RA0 female headers using jumper wires.

PIC16F628A Development Board

The development board we are going to make for our experimental microcontroller PIC16F628A will look like this. Here are the features it is going to have: Access to all I/O pins through female header pins 4 Push Buttons for Input 4 LEDs for Output An LCD Interface Port A 4-digit Seven-Segment Display Interface LCD Backlight Switch and Contrast Adjustment ICSP Programming (Very Important)