Tuesday, March 15, 2016

Interfacing PIC16F84A with multiplexed 7-Segment display with shift register


7-Segment with multiplexing and shift register
A serial-in parallel-out shift register (74HC164, 74HC595, CD4094.....) can be added to a 7-segment display. The adding of the shift register minimizes the number of pins used by the 7-segment display. This topic shows how to make a 4-digit digital counter with multiplexing and 74HC164 shift register using PIC16F84A and CCS PIC C compiler.
Interfacing PIC16F84A with multiplexed 7-Segment display with shift register circuit:
Example circuit schematic is shown below where a common anode 7-segment display and 74HC164N shift register are used.
Other shift registers such as 74HC595 and CD4094 can be used in this project.
The button connected to RB2 used to increment the displayed number.
seveb segment display shift register pic16f84a projects ccs pic c
Interfacing PIC16F84A with multiplexed 7-Segment display with shift register CCS C code:

// 4-Digit digital counter using PIC16F84A
// Common cathode 7-segment display with shift register
// http://ccspicc.blogspot.com/
// electronnote@gmail.com

#include <16F84A.h>
#fuses HS,NOWDT,PUT,NOPROTECT
#use delay(crystal=8000000)

short s;   // Used to know button position
unsigned int j, digit, digit1, digit10, digit100,digit1000;
unsigned long i;
unsigned int seg(unsigned int 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 0x82;
    case 7 : return 0xF8;
    case 8 : return 0x80;
    case 9 : return 0x90;
   }
}
void main() {
  while(TRUE) {
   if(input(PIN_B2) == 1)
     s = 1;
   if(s == 1) {
     if(input(PIN_B2) == 0) {
       s = 0;
       i++;
       if(i > 9999)
         i = 0;
     }
   }
   digit = i % 10;
   digit1 = seg(digit);
   output_a(0x0F);                     // Turn off all displays
   for(j = 0x40; j > 0; j = j >> 1) {
     if(digit1 & j)
       output_high(PIN_B0);
     else
       output_low(PIN_B0);
     delay_us(10);
     output_high(PIN_B1);
     delay_us(10);
     output_low(PIN_B1);}
   output_a(0x07);                     // Turn on display for ones
   delay_ms(1);
   digit = (i / 10) % 10;
   digit10 = seg(digit);
   output_a(0x0F);                     // Turn off all displays
   for(j = 0x40; j > 0; j = j >> 1) {
     if((digit10 & j) != 0)
       output_high(PIN_B0);
     else
       output_low(PIN_B0);
     delay_us(10);
     output_high(PIN_B1);
     delay_us(10);
     output_low(PIN_B1);}
   output_a(0x0B);                     // Turn on display for tens
   delay_ms(1);
   digit = (i / 100) % 10;
   digit100 = seg(digit);
   output_a(0x0F);                     // Turn off all displays
   for(j = 0x40; j > 0; j = j >> 1) {
     if((digit100 & j) != 0)
       output_high(PIN_B0);
     else
       output_low(PIN_B0);
     delay_us(10);
     output_high(PIN_B1);
     delay_us(10);
     output_low(PIN_B1);}
   output_a(0x0D);                     // Turn on display for hundreds
   delay_ms(1);
   digit = (i / 1000) % 10;
   digit1000 = seg(digit);
   output_a(0x0F);                     // Turn off all displays
   for(j = 0x40; j > 0; j = j >> 1) {
     if((digit1000 & j) != 0)
       output_high(PIN_B0);
     else
       output_low(PIN_B0);
     delay_us(10);
     output_high(PIN_B1);
     delay_us(10);
     output_low(PIN_B1);}
   output_a(0x0E);                     // Turn on display for thousands
   delay_ms(1);
   }
}

Digital counter using PIC16F84A microcontroller and CCS C compiler video:
The following video shows this project in hardware circuit.