Multiplexed Seven Segment Display using PIC16F877A and HI-TECH C


#include <htc.h>

#define _XTAL_FREQ 20000000UL

typedef unsigned char UINT8;
typedef signed char INT8;
typedef unsigned int UINT16;
typedef signed int INT16;

//Connection of Seven segment display

#define SEVEN_SEGMENT_LAT PORTD
#define SEVEN_SEGMENT_TRIS TRISD

//MUX Control
#define MUX_PORT PORTB
#define MUX_START_POS 1 //From which bit on port the select lines start

//MUX settings
#define MUX_DISP_COUNT 4   //Number of displays

//Global Varriable
UINT8 DisplayArray[MUX_DISP_COUNT];//Holds 'data' for each disp

void SevenSegmentWrite(UINT16 n)
{
/* 
   n=data to dislay
   example:

   n=1234 will display 1234 in a 4 segment display

   Working:
      This function breaks apart a given integer into separete digits
      and writes them to the display array i.e. digits[]
*/

   UINT8 i=0;
   UINT8 j;

   while(n)
   {
      DisplayArray[i]=n%10;
      i++;

      if(i==MUX_DISP_COUNT)
         break;   //We don't have room for more digits

      n=n/10;
   }

   //Fill Unused area with 0
   for(j=i;j<MUX_DISP_COUNT;j++) DisplayArray[j]=0;
}

void WriteSegment(UINT8 num)
{
   switch (num)
   {
      case 0:
                        //-GFEDCBA

         SEVEN_SEGMENT_LAT = 0B01000000;
         break;

      case 1:
                        //-GFEDCBA
         SEVEN_SEGMENT_LAT = 0B01111001;
         break;

      case 2:
                        //-GFEDCBA

         SEVEN_SEGMENT_LAT = 0B00100100;
         break;

      case 3:
                        //-GFEDCBA
         SEVEN_SEGMENT_LAT = 0B00110000;
         break;

      case 4:
                        //-GFEDCBA

         SEVEN_SEGMENT_LAT = 0B00011001;
         break;

      case 5:
                        //-GFEDCBA
         SEVEN_SEGMENT_LAT = 0B00010010;
         break;

      case 6:
                        //-GFEDCBA

         SEVEN_SEGMENT_LAT = 0B00000010;
         break;

      case 7:
                        //-GFEDCBA
         SEVEN_SEGMENT_LAT = 0B01111000;
         break;

      case 8:
                        //-GFEDCBA

         SEVEN_SEGMENT_LAT = 0B00000000;
         break;

      case 9:
                        //-GFEDCBA
         SEVEN_SEGMENT_LAT = 0B00010000;
         break;

   }

}


void Wait()
{
   UINT8 i;
   for(i=0;i<1;i++)
      __delay_ms(10);
}
void main()
{
   //Set Up I/O Ports

      TRISB0=0;
      SEVEN_SEGMENT_TRIS = 0B10000000;//Disp is connect from 0-6 last bit 7 is unused

      //MUX select lines
      TRISB = 0B11100001;

   //Init TIMER0

      T0CS=0;     //Timer Clock source is intruction clock that is 5MHz
      PSA=0;      //Prescaler is assigned to TIMER0
      PS2=1;
      PS1=1;
      PS0=0;      //Prescaler = FCPU/128

      TMR0IE=1;   //Enable Timer0 Interrupt
      PEIE=1;     //Enable Peripheral Interrup

   //Enable Interrupts Globally
   ei();

   while(1)
   {
      for (UINT16 i=0;i<10000;i++)
      {
         SevenSegmentWrite(i);
         Wait();
      }
   }



}




//Our Interrupt Service Routine
void interrupt ISR()
{
   if(TMR0IE && TMR0IF)
   {
      //TIMER0 Overflow Interrupt
      //First Clear the INT flag
      TMR0IF=0;

      // Current display selected

      //Value of "static varriable" is retained between calls
      static int i;

      //Switch On Display Pointed by 'i'
      MUX_PORT = (~(1<<(i+MUX_START_POS)));

      //Latch digit on it

      WriteSegment(DisplayArray[i]);

      //On each time out select next display
      i++;

      //If on last display then goto first
      if(i==MUX_DISP_COUNT)
            i=0;
   }
}

Facing problem with your embedded, electronics or robotics project? We are here to help!
Post a help request.

Avinash

Avinash Gupta is solely focused on free and high quality tutorial to make learning embedded system fun !

More Posts - Website

Follow Me:
FacebookLinkedInGoogle Plus

4 thoughts on “Multiplexed Seven Segment Display using PIC16F877A and HI-TECH C

  • By Henry Jenkins - Reply

    I have just written some very similar code but for a Atmel sam7 device (AT91SAM7S256) to control the same display. The code can be found at http://github.com/steakunderscore/AVRJukebox in the display.h and display.c files.

  • By summer - Reply

    i am interested on the seven-segment display. But more specifically on 7-segment display body bathroom scale that is non LCD. Because i am working on a project that requires me to display the output from a weighing machine to the computer. Unfortunately i do not know how to disassemble and find the output port(s) of the current digital LCD bathroom scales found in the market. Is there any way I can execute my project? thanks.

  • By vigneshwaran - Reply

    can i get a detailed description of port connections with 7seg. thanks.

  • By vahid - Reply

    please present schematic for your code

Leave a Reply

Your email address will not be published. Required fields are marked *


9 − = eight

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>