/***************************************************************************/
/* */
/* Nordik.c */
/* Dual timer for F5J-Nordik competition flying */
/* */
/* Version : 0.13 */
/* */
/* */
/* By: J. Vehmaa */
/* */
/* Date: 11.01.2004 */
/* */
/* */
/* Version Comments */
/* 0.07 PortAConfig 0x08 --> 0x00, PortBConfig 0x0F --> 0x03 */
/* 0.08 Buzzer and LCD's back light control taken in use */
/* Note: Summeri toimii käänteisellä logiikalla */
/* 0.09 Pre scaler 1:16 --> 1:256, comments added to PIC init part */
/* timer tibles to save results for later use */
/* 0.10 countdown functionality taken in use */
/* 0.11 List mode */
/* 0.12 LCD's back light control removed, buzzer control moved to */
/* main loop */
/* 0.13 buzzer control moved for a while... */
/***************************************************************************/
#pragma CLOCK_FREQ 4000000 // Timing settings for delay functions
#define MAIN
#include "lcd.h"
/* General definitions */
#define TRISA 5
#define TRISB 6
#define PORTA 5
#define PORTB 6
#define RBPU 7
#define BUZZER 4 // Buzzer in RA4
#define LCD_BACK_LIGHT_C 3 // LCD's led back light control in RA3
#define MOTOR_KEY 1 // Motor key in RB0
#define START_KEY 2 // Fly key in RB1
#define INTS_IN_SEC_C 15 // 4000000/(4*256*256)
#define BUZZER_TICS_C 2 // ~ 0.1 x INTS_IN_SEC_C
/* PIC PORT SETUP */
#define PortAConfig 0x00 // Configuration of port A ( 1 = in, O = output )
// RA543210
// 000000
#define PortBConfig 0x0F // Configuration of port B
// RB76543210
// 00001111
#define STATE_IDLE 0 // the both timers are stopped, display resetted
#define STATE_MOTOR_ON 1 // motor and fly timers are running
#define STATE_MOTOR_OFF 2 // motor timer is stopped and fly timer is running
#define STATE_STOP 3 // the both timers are stopped, not resetted
#define STATE_LIST 4 // list saved filght timers
#define F_HRS_POS_C 0x87 // pos 08..09 in line 1
#define F_MIN_POS_C 0x8A // pos 11..12 in line 1
#define F_SEC_POS_C 0x8D // pos 14..15 in line 1
#define M_MIN_POS_C 0xCA // pos 11..12 in line 2
#define M_SEC_POS_C 0xCD // pos 14..15 in line 2
#define MAX_MIN_SEC_C 59
#define FULL_MIN_HRS_C 60
#define SAVED_RESULTS_C 5
#define FOREVER 1
char fly_hrs_t[SAVED_RESULTS_C]; // table for saved timers
char fly_min_t[SAVED_RESULTS_C];
char fly_sec_t[SAVED_RESULTS_C];
char mot_min_t[SAVED_RESULTS_C];
char mot_sec_t[SAVED_RESULTS_C];
char mot_min; // variable for motor timer
char mot_sec;
char fly_hrs; // variable for fly timer
char fly_min;
char fly_sec;
char buzzer_time; // variable for different buzzer sounds
char lcd_bck_time; // time out counter for LCD's back light
char state; // state machine variable
char timer; // interrupt multiplier counter
char fly_index; // index to save timers into table
char disp_index;
//////////////////////////////////////////////////////////////////////
void update_fly_timer( void )
{
fly_sec++; // sec increment
if( fly_sec == 60 ){ // 60 sec has gone -> 1 MINUTES
fly_sec = 0; // prepare for another count
fly_min++; // min increment
buzzer_time = 5; // summeri päälle XX ms ajaksi
if( fly_min == 60 ){ // 60 min has gone -> 1 HOURS
fly_hrs++; // hrs increment
fly_min = 0; // prepare for another count
if( fly_hrs == 24 ){ // 24 hrs has gone -> reset all
fly_hrs = 0;
fly_min = 0;
fly_sec = 0;
state = STATE_IDLE;
}
LCD_WriteIntPos( fly_hrs, F_HRS_POS_C );
}
LCD_WriteIntPos( fly_min, F_MIN_POS_C );
}
LCD_WriteIntPos( fly_sec, F_SEC_POS_C );
}
//////////////////////////////////////////////////////////////////////
void update_mot_timer( void )
{
mot_sec++; // sec increment
if( ( mot_min == 59 ) && ( mot_sec == 59 ) ){
mot_sec = 0;
mot_min = 0;
state = STATE_MOTOR_OFF;
}
else if( mot_sec == 60 ){ // 60 s has gone -> 1 MINUTES
mot_sec = 0; // prepare for another count
mot_min++; // min increment
}
LCD_WriteIntPos( mot_min, M_MIN_POS_C );
LCD_WriteIntPos( mot_sec, M_SEC_POS_C );
}
//////////////////////////////////////////////////////////////////////
void print_counters(void)
{
printf( " Lento:00:00\'00\"Moottori: 00\'00\"");
}
//////////////////////////////////////////////////////////////////////
void print_timers(void)
{
char j;
print_counters();
LCD_Command(RETURN_HOME_C);
LCD_Write_4_Bit('0' + disp_index);
j = fly_hrs_t[disp_index];
LCD_WriteIntPos( j, F_HRS_POS_C );
j = fly_min_t[disp_index];
LCD_WriteIntPos( j, F_MIN_POS_C );
j = fly_sec_t[disp_index];
LCD_WriteIntPos( j, F_SEC_POS_C );
j = mot_min_t[disp_index];
LCD_WriteIntPos( j, M_MIN_POS_C );
j = mot_sec_t[disp_index];
LCD_WriteIntPos( j, M_SEC_POS_C );
}
//////////////////////////////////////////////////////////////////////
void timer_reset( void )
{
fly_hrs_t[fly_index] = fly_hrs;
fly_min_t[fly_index] = fly_min;
fly_sec_t[fly_index] = fly_sec;
mot_min_t[fly_index] = mot_min;
mot_sec_t[fly_index] = mot_sec;
timer = 0;
mot_min = 0;
mot_sec = 0;
fly_hrs = 0;
fly_min = 0;
fly_sec = 0;
buzzer_time = 0;
print_counters();
}
//////////////////////////////////////////////////////////////////////
void interrupt( void ) // every 66ms
{
// Interrupt processing: TMR0 Overflow processing
if( INTCON & 4 ){
timer++;
if ( timer == INTS_IN_SEC_C ){
timer=0; // prepare for another count
if ( ( state == STATE_MOTOR_ON ) || ( state == STATE_MOTOR_OFF ) ){
update_fly_timer();
if( state == STATE_MOTOR_ON ){
update_mot_timer();
}
}
}
clear_bit( INTCON, T0IF ); // flag from RTCC overflow = 0
// must be resetted before exiting ISR
}
}
//////////////////////////////////////////////////////////////////////
void ready_steady_go( void )
{
int i;
LCD_Clear();
printf( "Lahtolaskenta: ");
for( i = 9 ; i > 0 ; i--){
LCD_WriteIntPos( i, 0x8E );
delay_s(1);
// beep after every 2 sec
if(( i == 2 ) || ( i == 4) || ( i == 6 )){
output_low_port_a( BUZZER );
delay_ms( 20 );
output_high_port_a( BUZZER );
}
}
print_counters();
}
//////////////////////////////////////////////////////////////////////
void main(void)
{
char keys1, keys2;
//*** First setup PIC ports and interrupts
disable_interrupt( GIE ); // Enable Global Interrupts
/*
* Select Bank 1 to acess port config registers
*/
set_bit( STATUS, RP0 );
/*
* !RBPU = 1, PS2=1, PS1=1, PS0=1, pre scaler 1:256
*/
OPTION_REG = 0x07; //0x87;
/*
* Configuration of port A ( 1 = in, O = output )
* RA543210
* 000000 = 0x00
*/
set_tris_a( PortAConfig); // Setup port A
/* Configuration of port B ( 1 = in, O = output )
* RB76543210
* 00001111 = 0x0F
*/
set_tris_b( PortBConfig ); // Setup port B
clear_bit( STATUS, RP0 ); // Select Bank 0, INTCON in BANK 1
INTCON = 160; // Configure the INTCON register 7.9.-03lisatty
output_low_port_a( LCD_SEL ); // Disable LCD
enable_interrupt( T0IF ); // enable only TMR0 interrupt
//*** End of PIC Setup
LCD_Setup(); // Initialize the LCD device
output_low_port_a( BUZZER ); // boot procedures.....
printf( "* Nordik timer * ver 0.13 " );
//kikkaile tasta eteenpain buzz_timella.....
// buzzer_time = 2;
delay_ms( 20 );
output_high_port_a( BUZZER );
delay_s( 3 ); // ... here
timer_reset(); // reset timer variables and displays
output_high_port_a( LCD_BACK_LIGHT_C );
state = STATE_IDLE;
fly_index = 0;
//*** End of application setup
while( FOREVER ) // main LOOP
{
keys1 = input_port_b();
delay_ms( 20 );
keys2 = input_port_b();
if( keys1 == keys2 ){
if( ! ( keys1 & 0x01 ) ){ // korjaa vakiot
keys1 = START_KEY;
}
else if( ! ( keys1 & 0x02 ) ){ // korjaa vakiot
keys1 = MOTOR_KEY;
}
// output_low_port_a( BUZZER );
delay_ms( 250 );
// output_high_port_a( BUZZER );
}
switch ( state ){
case STATE_IDLE:
if( keys1 == START_KEY ){ // start the both timers
state = STATE_MOTOR_ON;
}
else if( keys1 == MOTOR_KEY ){ // start final countdown
ready_steady_go();
state = STATE_MOTOR_ON;
}
break;
case STATE_MOTOR_ON:
if( keys1 == MOTOR_KEY ){ // stop motor timer
state = STATE_MOTOR_OFF;
}
else if( keys1 == START_KEY ){ // stop the both timers
state = STATE_STOP;
}
break;
case STATE_MOTOR_OFF:
if( keys1 == MOTOR_KEY ){ // re-start motor timer
state = STATE_MOTOR_ON;
}
else if( keys1 == START_KEY ){ // stop the both timers
state = STATE_STOP;
}
break;
case STATE_STOP: // reset timer displays
if( keys1 == START_KEY ){ // and variables
state = STATE_IDLE;
timer_reset();
}
else if( keys1 == MOTOR_KEY ){ // go to list mode
state = STATE_LIST;
disp_index = 0;
print_timers();
}
break;
case STATE_LIST:
if( keys1 == MOTOR_KEY ){
state = STATE_IDLE;
timer_reset();
}
else if( keys1 == START_KEY ){
if(++disp_index >= SAVED_RESULTS_C){
disp_index = 0;
}
print_timers();
}
break;
}
// if( buzzer_time-- ){ // if buzzer timer has been set
//
// output_low_port_a( BUZZER );
// }
// else { // if timer has expired
// output_high_port_a( BUZZER ); // set buzzer off
// }
}
}
syntax highlighted by
Code2HTML, v. 0.9.1