Billiard Shot Timer
I have created open project as a billiards shot clock/timer. This is a 45 second countdown timer to limit the player’s time on each shot. This uses Tiny Threads as its multitasking engine for the display and button debouncing.
This is posted at a Filipino Electronics forum here.
Download the compile .hex file here Billiard Shot Timer Source Code and Hex File
/*
* 2 Digit Billiard Timer
* Copyright (c) 2008, Regulus Berdin
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL REGULUS BERDIN BE LIABLE FOR
* ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* History:
* 1.0 10/27/2008 Created file.
*
*/
#include
__CONFIG(PROTECT & CPD & LVPDIS & BOREN & MCLREN & PWRTEN & WDTDIS & XT);
#include “tthread.h”
#define BTN_RESET RB0
#define BTN_START_STOP RB1
#define BTN_EXTEND RB2
#define TICKS_SECONDS 225
#define DEBOUNCE_DELAY 12
unsigned char tmr_count, start_count, seconds;
unsigned char debounce1, debounce2, debounce3;
unsigned char disp1, disp2;
void interrupt isr(void)
{
T0IF = 0;
if (start_count)
{
if (tmr_count)
{
–tmr_count;
}
else
{
tmr_count = TICKS_SECONDS;
++seconds;
}
}
if (debounce1) –debounce1;
if (debounce2) –debounce2;
if (debounce3) –debounce3;
}
void init(void)
{
/* disable comparators */
CMCON=0×07;
/* setup PIOs*/
TRISA=0;
TRISB=0b00000111;
PORTA=0;
PORTB=0;
RBPU = 0;
/* Timer0 on Fosc */
T0CS = 0;
/* Prescaler on Timer0 */
PSA = 0;
/* Divided by 16
Timer0 = 225 ticks/seconds */
PS0 = 1;
PS1 = 1;
PS2 = 0;
T0IF = 0;
T0IE = 1;
GIE = 1;
}
void update_dispay(void)
{
PORTA = disp1 & 0×0F;
PORTB = (disp2 << 4) & 0xF0;
}
void reset_display(unsigned char a, unsigned char b)
{
disp1 = a;
disp2 = b;
T0IF = 0;
TMR0 = 0;
update_dispay();
}
TT_DEF(display)
{
TT_BEGIN(display);
reset_display(4,5);
seconds = 0;
while (1)
{
TT_WAIT_UNTIL(display, seconds);
--seconds;
TT_SWITCH(display);
if (disp2)
--disp2;
else
if (disp1)
{
disp2 = 9;
--disp1;
}
else
{
start_count = 0;
}
TT_SWITCH(display);
update_dispay();
}
TT_END(display);
}
TT_DEF(reset)
{
TT_BEGIN(reset);
while(1) {
do {
TT_WAIT_WHILE(reset, BTN_RESET);
debounce1 = DEBOUNCE_DELAY;
TT_WAIT_WHILE(reset, debounce1);
} while (BTN_RESET);
start_count = 0;
reset_display(4,5);
do {
TT_WAIT_WHILE(reset, BTN_RESET == 0);
debounce1 = DEBOUNCE_DELAY;
TT_WAIT_WHILE(reset, debounce1);
} while(BTN_RESET == 0);
}
TT_END(reset);
}
TT_DEF(start_stop)
{
TT_BEGIN(start_stop);
while(1)
{
do {
TT_WAIT_WHILE(start_stop, BTN_START_STOP);
debounce1 = DEBOUNCE_DELAY;
TT_WAIT_WHILE(start_stop, debounce1);
} while (BTN_START_STOP);
start_count = start_count?0:1;
do {
TT_WAIT_WHILE(start_stop, BTN_START_STOP == 0);
debounce2 = DEBOUNCE_DELAY;
TT_WAIT_WHILE(start_stop, debounce2);
} while(BTN_START_STOP == 0);
}
TT_END(start_stop);
}
TT_DEF(extend)
{
TT_BEGIN(extend);
while(1)
{
do {
TT_WAIT_WHILE(extend, BTN_EXTEND);
debounce3 = DEBOUNCE_DELAY;
TT_WAIT_WHILE(extend, debounce3);
} while (BTN_EXTEND);
disp1 += 3;
update_dispay();
/* reset_display(3,0); */
start_count = 1;
do {
TT_WAIT_WHILE(extend, BTN_EXTEND == 0);
debounce3 = DEBOUNCE_DELAY;
TT_WAIT_WHILE(extend, debounce3);
} while(BTN_EXTEND == 0);
}
TT_END(extend);
}
void main(void)
{
init();
start_count = 0;
TT_INIT(display);
TT_INIT(reset);
TT_INIT(start_stop);
TT_INIT(extend);
while (1)
{
TT_SCHED(display);
TT_SCHED(reset);
TT_SCHED(start_stop);
TT_SCHED(extend);
}
}


