Tuesday, 29 November 2011

So now it's a stopwatch.

After watching the numbers flash by, produced by the code in my previous article, i now tweaked the program to do something useful for a change. The display will now count to 59.9 seconds, and resets when a button is pressed. It still isn't very sophisticated, and a $2.00 wristwatch will actually do a much better job, but that wasn't the point :-)

//Includes & references
#include <htc.h>

//Processor configuration (look in processor header file for definitions)
__CONFIG(FOSC_INTRCIO & WDTE_OFF & PWRTE_OFF & BOREN_OFF &
    MCLRE_OFF & CPD_OFF & CP_OFF);

#define _XTAL_FREQ    4000000
#define DIGIT0        RA0
#define DIGIT1        RA1
#define    DIGIT2        RA2
#define    BUTTON1        RA5

//Global variables
//int counter = 0;

//Put initialization code here
void init (void)
{
    //Disable interrupts
    INTCON        = 0b00000000;
    PIE1        = 0b00000000;
    //Set options
    OPTION_REG    = 0b10000111;
    //Switch off comparator to enable digital I/0
    CMCON        = 0b00000111;
    //Set port directions
    TRISA        = 0b00101000;
    TRISC        = 0b00000000;
}

/**** Function prototypes ****/
void SelectDigit (int Digit);
void ShowNumber (int Number);

/**** Main function block ****/
void main (void)
{
    init();
    int loopCounter = 0;
    int countDigit0 = 0;
    int countDigit1 = 0;
    int countDigit2 = 0;
    int i = 0;
    //This loop executes approx. 1000x / sec. for display multiplexing
    for (;;)
    {
        //Blank display before digit switch
        ShowNumber(11);
       
        SelectDigit (i);
       
        //Show next number
        switch (i)
        {
            case (0):
            ShowNumber(countDigit0);
            break;
            case (1):
            ShowNumber(countDigit1);
            break;
            case (2):
            ShowNumber(countDigit2);
            break;
            default:
            ShowNumber(4);
            break;
        }
        __delay_ms(1);
        i++;
        if (i > 2)
            i = 0;
        loopCounter++;
        //Reset loopCounter (adjust for max accuracy)
        if (loopCounter > 98)
        {
            loopCounter = 0;
            countDigit0++;
            if (countDigit0 > 9)
            {
                countDigit0 = 0;
                countDigit1++;
                if (countDigit1 > 9)
                {
                    countDigit1 = 0;
                    countDigit2++;
                    if (countDigit2 > 5)
                    {
                        countDigit0 = countDigit1 = countDigit2 = 0;
                    }
                }
            }
        }   
           
        //Reset counters when sw1 is pressed
        if (!BUTTON1)
        {
            countDigit0 = countDigit1 = countDigit2 = 0;
        }
    }
}

/**** Functions ****/

//Call with 0 - 2 to select digit. All other values blank the display.
void SelectDigit (int Digit)
{
    switch (Digit)
        {
            case (0):
            //Digit 0
            DIGIT0 = 0;
            DIGIT1 = 1;
            DIGIT2 = 1;
            break;
            case (1):
            //Digit 1
            DIGIT0 = 1;
            DIGIT1 = 0;
            DIGIT2 = 1;           
            break;
            case (2):
            //Digit 2 (MSB)
            DIGIT0 = 1;
            DIGIT1 = 1;
            DIGIT2 = 0;
            break;
            default:
            //Defaults to blank
            DIGIT0 = 1;
            DIGIT1 = 1;
            DIGIT2 = 1;
            ;
        }
}

//Call with 0 - 9 to show number. All other values blank the display.
void ShowNumber (int Number)
{
    switch (Number)
    {
        case (0):
        PORTC = 0b000000;
        RA4 = 1;
        break;
        case (1):
        PORTC = 0b111001;
        RA4 = 1;
        break;
        case (2):
        PORTC = 0b100100;
        RA4 = 0;
        break;
        case (3):
        PORTC = 0b110000;
        RA4 = 0;
        break;
        case (4):
        PORTC = 0b011001;
        RA4 = 0;
        break;
        case (5):
        PORTC = 0b010010;
        RA4 = 0;
        break;
        case (6):
        PORTC = 0b000010;
        RA4 = 0;
        break;
        case (7):
        PORTC = 0b111000;
        RA4 = 1;
        break;
        case (8):
        PORTC = 0b000000;
        RA4 = 0;
        break;
        case (9):
        PORTC = 0b010000;
        RA4 = 0;
        break;
        default:
        //Defaults to blank
        PORTC = 0b111111;
        RA4 = 1;   
    }
}

1 comment:

  1. Definitely something useful to change the program in the article much better display the results
    Online Stopwatches

    ReplyDelete