Sunday, March 13, 2016

4-Digit digital counter using PIC16F877A and CCS C compiler


Interface PIC16F877A with 7-segment display
Using PIC16F877A and 7-segment display we can build a digital counter that counts from 0 to 9999 with a button to increment the number. The same thing as on the following topic where the microcontroller PIC16F84A was used.
4-Digit 7-segmant display counter using PIC16F84A and CCS PIC C compiler
We are going to see circuit and code for both 7-segment display types, common anode and common cathode.
Digital counter using common anode 7-segment display:
Circuit schematic for interfacing PIC16F877A with common anode 7-segment display is shown below:
pic16f877a 7 segment display ccs pic c common anode
The button is used to increment the displayed number.
Digital counter using common anode 7-segment display CCS C code:

// 4-Digit digital counter using PIC16F877A
// Common anode 7-segment display
// http://ccspicc.blogspot.com/
// electronnote@gmail.com

#include <16F877A.h>
#use delay(crystal=8000000)

short s;                       // Used to know button position
unsigned int digit, digit1, digit10, digit100,digit1000;
unsigned long i = 0;
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_D0) == 1)
      s = 1;
    if(s == 1) {
      if(input(PIN_D0) == 0) {
       s = 0;
       i++;
       if(i > 9999)
         i = 0;
      }
    }
    digit = i % 10;
    digit1 = seg(digit);
    output_c(0x0F);           // Turn off all displays
    output_b(digit1);         // Send ones digit
    output_c(0x07);           // Turn on display for ones
    delay_ms(2);
    digit = (i / 10) % 10;
    digit10 = seg(digit);
    output_c(0x0F);           // Turn off all displays
    output_b(digit10);        // Send tens digit
    output_c(0x0B);           // Turn on display for tens
    delay_ms(2);
    digit = (i / 100) % 10;
    digit100 = seg(digit);
    output_c(0x0F);           // Turn off all displays
    output_b(digit100);       // Send hundreds digit
    output_c(0x0D);           // Turn on display for hundreds
    delay_ms(2);
    digit = (i / 1000) % 10;
    digit1000 = seg(digit);
    output_c(0x0F);           // Turn off all displays
    output_b(digit1000);      // Send thousands digit
    output_c(0x0E);           // Turn on display for thousands
    delay_ms(2);
    }
}

Digital counter using common cathode 7-segment display:
Circuit schematic of the common cathode is a little bit different from the common anode one as shown below:
digital counter pic16f877a 7 segment display ccs pic c common cathode
Digital counter using common cathode 7-segment display CCS C code:
The code is also has some differences from the common anode code.

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

#include <16F877A.h>
#use delay(crystal=8000000)

short s;                       // Used to know button position
unsigned int digit, digit1, digit10, digit100,digit1000;
unsigned long i = 0;
unsigned int seg(unsigned int 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;
    }
}
void main(){
  while(TRUE){
    if(input(PIN_D0) == 1)
      s = 1;
    if(s == 1) {
      if(input(PIN_D0) == 0) {
       s = 0;
       i++;
       if(i > 9999)
         i = 0;
      }
    }
    digit = i % 10;
    digit1 = seg(digit);
    output_c(0);           // Turn off all displays
    output_b(digit1);         // Send ones digit
    output_c(8);           // Turn on display for ones
    delay_ms(2);
    digit = (i / 10) % 10;
    digit10 = seg(digit);
    output_c(0);           // Turn off all displays
    output_b(digit10);        // Send tens digit
    output_c(4);           // Turn on display for tens
    delay_ms(2);
    digit = (i / 100) % 10;
    digit100 = seg(digit);
    output_c(0);           // Turn off all displays
    output_b(digit100);       // Send hundreds digit
    output_c(2);           // Turn on display for hundreds
    delay_ms(2);
    digit = (i / 1000) % 10;
    digit1000 = seg(digit);
    output_c(0);           // Turn off all displays
    output_b(digit1000);      // Send thousands digit
    output_c(1);           // Turn on display for thousands
    delay_ms(2);
    }
}

Digital counter using PIC16F877A and 7-segment display video:
The following video shows a hardware circuit for the discussed counter.