/*
 * 7-seg.c 
 * Driving 2-digit 7-segment Common Anode LED & keypad
 * Copyright (C) 1999 Wichit Sirichote
 * compiled with Dunfield Micro-C for 8051 Release 3.2
 * c:\mc\cc51 7-seg -i h=c:\mc m=t
 */

#include c:\mc\8051io.h  /* include i/o header file */
#include c:\mc\8051reg.h

extern register char cputick; // cputick was incremented every 10ms

register unsigned char flag1;
unsigned register char sec,digit,buffer[2];
register char key;

char convert[10] = {0x3F,0x0c,0x76,0x5e,0x4d,0x5b,0x7b,0x0e,0x7f,0x5f};
   // LED pattern for  0    1   2    3    4    5    6    7    8    9

/*  my LED's segment pin designation
	    b	
	   __
	a|__| c
	f |    | d
	   ----
                    e
*/

#define setValue 99

main()
{
          flag1 = 0;
          sec = setValue;
          timeToBuffer();
          serinit(9600); // set timer0 to be 16 bit counter 
          while(1){

               while(cputick < 10)
                scanLED();
            // execute the following functions every 100ms
                cputick = 0;
                timeToBuffer();
                keyexe();
                countdown();
                  }
}


scanLED() /* scan 2-digit LED and 2-key switch, if key pressed key = 0-1
else key = -1 */

{
    int i;
    digit = 0x02;    // scan code 00000010 
    key = -1;
    for( i = 0; i < 2; i++)  /* 2-DIGIT scanning */
    {
        P3 = ~digit;      /* send complement[digit] */
        P1 = ~buffer[i];  /* send complement[segment] */
        delay(1);         /* delay 1ms */
        P1 = 0xff;        /* off LED */
        if ((P3 & 0x10) == 0) /* if key pressed P3.4 became low */
           key = i;       /* save key position to key variable */
        digit>>=1;        /* next digit */
    }
}

timeToBuffer() // converts binary data in sec to 7-segment pattern
{
    buffer[0] = convert[sec%10];
    buffer[1] = convert[sec/10];
}

countdown()   
{
    if ((flag1 & 0x02) != 0)
        sec--;
        if (sec == 0 )
                flag1 &= ~0x02;  // clear run bit 
}

keyexe()
{
    if (key != -1)
    {
      switch(key){
        case (0): /* key position 0 */
        reset();  /* service key 0 */
        break;
        case (1): /* key position 1 */
        run();    /* service key 1 */
                }

    }
}

reset()
{
        sec = setValue;  // reload set value
        timeToBuffer();
        flag1 &= ~0x02;  // stop counting down
}

run()
{
        if (sec != 0)
        flag1 |= 0x02; // start counting down
}

