first.c

Beginner project for PIC16F84, 7-segment indicator with common anode, 2 buttons and IC sn74ls139. This project counts from 0000 to 9999 forward and backward depending on which button is pressed (by Tzvetelin Velkov).



// This is written by Tzvetelin Velkov ,Technical University - Sofia ,Bulgaria
// e-mail dark__flame@hotmail.com ,please do not spam me !
// This code work very stable ,it's tested couple of days
// feel free to use this project in way you wish :))


#include <p16f84a.h>

// optional ,if you use function delay then you need this
#pragma CLOCK_FREQ 4000000

// variables
char num ,
     sec_1 ,
     sec_2 ,
     buttons ,
     inp;

// BCD codings :      0    1  2   3   4    5    6    7  8    9
const char bcd[] = {191, 6, 91, 79, 102, 109, 253, 7, 255, 239};

// buffers for Dinamic LED ,8 digit 7 segment  
// this buffer contains a number ,which we display in 7 segment BCD format
char buf[] = {0,0,0,0,0,0,0,0};
//this buffer contains a number in normal format
char sim[] = {0,0,0,0,0,0,0,0};

// this function increment 4 digit array 
void up(void)
{
 if (sim[0] >= 9)
  {
   buf[0] = bcd[0];
   sim[0] = 0;
   if (sim[1] >= 9)
    {
     buf[1] = bcd[0];
     sim[1] = 0;
     if (sim[2] >= 9)
      {
       buf[2] = bcd[0];
       sim[2] = 0;
       if (sim[3] >= 9)
        {
         buf[3] = bcd[0];
         sim[3] = 0;
        }
       else
        {
         sim[3] = sim[3] + 1;
         buf[3] = bcd[sim[3]];
        }
      }
     else
      {
       sim[2] = sim[2] + 1;
       buf[2] = bcd[sim[2]];
      }
    }
   else
    {
     sim[1] = sim[1] + 1;
     buf[1] = bcd[sim[1]];
    }
  }
 else
  {
   sim[0] = sim[0] + 1;
   buf[0] = bcd[sim[0]];
  }
}

//this function decremet a 4 digit array
void down(void)
{
 if ((sim[0] == 0) || (sim[0] > 9))
  {
   buf[0] = bcd[9];
   sim[0] = 9;
   if ((sim[1] == 0) || (sim[1] > 9))
    {
     buf[1] = bcd[9];
     sim[1] = 9;
     if ((sim[2] == 0) || (sim[2] > 9))
      {
       buf[2] = bcd[9];
       sim[2] = 9;
       if ((sim[3] == 0) || (sim[3] > 9))
        {
         buf[3] = bcd[9];
         sim[3] = 9;
        }
       else
        {
         sim[3] = sim[3] - 1;
         buf[3] = bcd[sim[3]];
        }
      }
     else
      {
       sim[2] = sim[2] - 1;
       buf[2] = bcd[sim[2]];
      }
    }
   else
    {
     sim[1] = sim[1] - 1;
     buf[1] = bcd[sim[1]];
    }
  }
 else
  {
   sim[0] = sim[0] - 1;
   buf[0] = bcd[sim[0]];
  }
}

//this is interrupt handle
void interrupt(void)
{
//display 1 digit
 if ((num == 0))
  {
   output_port_a(0);
   output_port_b(buf[0]);
  }
//dispaly 2 digit
 if ((num == 1))
  {
   output_port_a(1);
   output_port_b(buf[1]);
  }
//display 3 digit
 if ((num == 2))
  {
   output_port_a(2);
   output_port_b(buf[2]);
  }
//display 4 digit
 if ((num == 3))
  {
   output_port_a(3);
   output_port_b(buf[3]);
  }
//reverse variable num
 if (num == 3) num = 0;
          else num ++;
//variable for time measurment          
 sec_1 ++;
//clear interrupt   
 clear_bit( INTCON, T0IF );  //clear TMR0 overflow flag
}

void main(void)
{
//disable all interrupts
    disable_interrupt(GIE);

//porta 2:0 are inputs and 4:3 are outputs  
    trisa = 28;

//portb 7:0 are outputs
    trisb = 0;

//set prescaler to 1:128
    option_reg = 2;

//initial value for portb
    output_port_b(0);

//enable interrupts
    enable_interrupt( GIE );

//enable timer0 overflow interrupt
    enable_interrupt( T0IE );

    buf[0] = bcd[0];
    buf[1] = bcd[0];
    buf[2] = bcd[0];
    buf[3] = bcd[0];

    sec_1 = 0;
    sec_2 = 0;

//optional delay ,it's used for more stability    
    while (sec_2 <= 8)
     {
      if (sec_1 >= 98)
       {
        sec_1 = 0;
        sec_2 ++;
       }
     }

    buf[0] = bcd[0];
    buf[1] = bcd[0];
    buf[2] = bcd[0];
    buf[3] = bcd[0];

    sec_1 = 0;
    sec_2 = 0;
    buttons = 0;

    num = 0;

    while( 1 ) //endless loop
     {
//reads porta
      inp = input_port_a();
//button 1 pressed ,then wait for release
      if ((inp & 4) == 4)
       {
        set_bit(buttons,0);
       }
//button 2 pressed ,then wait for release 
      if ((inp & 8) == 8)
       {
        set_bit(buttons,1);
       }
//button 1 released ,then button 1 is pressed
      if (((inp & 4) != 4)&&(buttons & 1))
       {
        clear_bit(buttons,0);
        set_bit(buttons,7);
        up();
       }
//button 2 released ,then button 2 is pressed
      if (((inp & 8) != 8)&&(buttons & 2))
       {
        clear_bit(buttons,1);
        clear_bit(buttons,7);
        down();
       }
//measure 1 seccond
// 1 sec = sec_1 * sec_2 = (((osc / 4) /prescaller) /255)

      if (sec_1 >= 98)
       {
        sec_1 = 0;
        if (sec_2 >= 6)
         {
          sec_2 = 0;
          if ((buttons & 128) == 128) up();
          else down();
         }
        sec_2 ++;
       }
     }
}



http://www.sourceboost.com/home.html

Copyright © 2002-2006 SourceBoost Technologies