Thursday 12 July 2012

Episode 3

7-Segment LED Display

This is an introduction to the 7-segment LED display module and how to make basic counters from 1 digit up to 6 digits. Also I have included three examples, the first one is for a counter from 0 to 9, the second example is a counter from 00 to 59 and the final example is about a 24 hours counter.


 



Useful Links
http://www.gooligum.com.au/tutorials/baseline/PIC_Base_C_4.pdf



Board Settings

First you have to switch on all the bits of S5 .


 

 

A counter from 0 to 9

For this example connect with a jumper wire the pin RC0 to the rightmost digit of the 7-segment display and copy the following code.




//Include the header for 16F877A. 
#include <16F877A.h> 

//We use an xtal crystal, no watchdog, 
//no low-voltage protection and no code protection. 
#fuses XT, NOWDT, NOLVP, NOPROTECT 

//The crystal is at 4,000,000 Hz. 
#use delay (clock=4M) 

//The enable pin of the digit one. 
#define digit_on PIN_C0 

//The numbers 0-9 in hexadecimal form.
const char display_number[10] ={0xC0,0xF9,0xA4,0xB0,0x99, 0x92,0x82,0xD8,0x80,0x90}; 

//The variable for the current digit.
int digit; 

//This is the starting point of the program.
void main() 
{ 
   //Set the Port D to 0.
   set_tris_D(0x00); 

   //Infinite loop.
   while(1) 
   { 
     //Display one digit at a time with 1 second delay.
     for(digit=0;digit<10;digit++) 
     { 
       output_low(digit_on); 
       output_D(display_number[digit]); 
       delay_ms(1000); 
     } 

   } 
} 



A counter from 00 to 59

Now connect with an other jumper wire, the pin A1 to the second digit of the 7-segment display and copy the code below.


//Include the header for 16F877.A 
#include <16F877A.h> 

//We use an xtal crystal, no watchdog, 
//no low-voltage protection and no code protection. 
#fuses XT, NOWDT, NOLVP, NOPROTECT 

//The crystal is at 4,000,000 Hz. 
#use delay (clock=4M) 

//Table of digits from 0 to 9. 
int tab[10] = {0xC0,0xF9,0xA4,0xB0,0x99, 0x92,0x82,0xD8,0x80,0x90}; 

//We set as a byte variable the units and the tens of each second.
byte sec_unit , sec_ten ; 

//Set the variable of time.
int time = 0; 

//0-59 seconds counter
int i ; 

//This is the starting point of your program.
void main() 

{ 
  //Infinite loop.
  while (1) 
  { 
    //The time variable is set to 0.
    time = 0; 

    //A loop repeat for 1 minute.
    while (time < 60 ) 
    { 
      //Split the seconds in units and tens. 
      sec_unit = time %10; 
      sec_ten = time /10; 
      i = 0 ; 

      //Repeat for a second
      while ( i < 100 ) 
     { 
       //Enable the pin for units.
       OUTPUT_a(0b00000000) ; 
       
       //Display the units.
       OUTPUT_d(tab[sec_unit]) ; 

       //Disable the pin for units.
       OUTPUT_a(0b00000010) ; 

       //Wait for 5 milliseconds.
       delay_ms( 5 ); 

       //Enable the pin for tens.
       OUTPUT_a(0b00000000) ; 

       //Display the tens.
       OUTPUT_d(tab[sec_ten]); 
       
       //Disable the pin for units.
       OUTPUT_a(0b00000001) ; 
 
       //Wait for 5 milliseconds.
       delay_ms( 5 );
       
       //Add one to the seconds counter.
       i++; 
     } 

   //Add one to the time counter.
   time++; 

  } 

} 

}


A 24 hours counter

For this example you will have to connect the pin A2-A5 to the rest of the 7-segment digits to enable all the six digits of the 7-segment module.





//Include the header for 16F877.
#include <16F877A.h>

//We use an xtal crystal, no watchdog, 
//no low-voltage protection and no code protection.
#fuses XT, NOWDT, NOLVP, NOPROTECT
           
//The crystal is at 4,000,000 Hz.
#use delay (clock=4M)   


#define HRS_TENS      PIN_A5
#define HRS_ONES      PIN_A4
#define MIN_TENS      PIN_A3
#define MIN_ONES      PIN_A2
#define SEC_TENS      PIN_A1
#define SEC_ONES      PIN_A0

void set7seg(int8 digit);
void set7seg_dp(int8 digit);

#define TMR0_2 (get_timer0() & 1<<2)
                
void main() 
{

    int mpx_cnt;
    int mins, secs, hrs;
    
    setup_adc_ports(NO_ANALOGS);
    setup_comparator(NC_NC_NC_NC);
    
    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);


    while (TRUE)
    
    
    {   

    for(hrs=0; hrs<24; hrs++)
    {
     for(mins=0; mins<60; mins++)
      {
         for (secs=0; secs<60; secs++)
         {
          for(mpx_cnt=0; mpx_cnt <1000000/2048/6; mpx_cnt++)
          {
            while (!TMR0_2);
            set7seg(secs%10);
            output_low (SEC_ONES);
            while(TMR0_2);
            output_high(SEC_ONES);
                        
            while (!TMR0_2);
            set7seg(secs/10);
            output_low (SEC_TENS);
            while(TMR0_2);
            output_high(SEC_TENS);
            
            while (!TMR0_2);
            set7seg_dp(mins%10);
            output_low (MIN_ONES);
            while(TMR0_2);
            output_high(MIN_ONES);
            
            while (!TMR0_2);
            set7seg(mins/10);
            output_low (MIN_TENS);
            while(TMR0_2);
            output_high(MIN_TENS);
            
            while (!TMR0_2);
            set7seg_dp(hrs%10);
            output_low (HRS_ONES);
            while(TMR0_2);
            output_high(HRS_ONES);
            
            while (!TMR0_2);
            set7seg(hrs/10);
            output_low (HRS_TENS);
            while(TMR0_2);
            output_high(HRS_TENS);
          }
        }
      }
    }
  }
}

void set7seg( int8 digit)
{
   const int8  pat7segment[10] = 
   {0xC0,0xF9,0xA4,0xB0,0x99,
    0x92,0x82,0xD8,0x80,0x90
   };
   
   output_d(pat7segment[digit]);

}

void set7seg_dp( int8 digit)
{
   const int8  pat7segment_dp[10] = 
   {0x40,0x79,0x24,0x30,0x19,
    0x12,0x02,0x58,0x00,0x10
   };
   
   output_d(pat7segment_dp[digit]);

}