//
// Rev counter
//
#include <P16f84.h>
#include <displays.h>
//
// Define software version strings
const unsigned char VersionString1[]="V1.02";
const unsigned char VersionString2[]="19/02/2006";
#include "RevCount-vars.h"
// FUNCTION PROFORMAS
void clearLCD(); //Clear LCD display
void LCDNum(); //Output 5-digit revCount number to LCD
void Interrupt(); //Interrupt handler
//Time delay
void waitTime(unsigned int time);
//MAIN
//
void main ()
{
//Initialise Port A
TRISA=0x17; //Set all bits of Port A to input
// Initialize the LCD with startup message
waitTime(1000); //Wait a bit
LCD(-2); //2-line display, 8-bit, 5x7 format
clearLCD(); //Initialize & clear screen
LCDPrintAt(0,0); //2nd message
LCDString("RevMaster"); //Hello to the world
LCDPrintAt(0,1); //2nd line
LCDString (VersionString1); //Display software version
waitTime(32767); //Wait some more
LCDPrintAt(0,1); //2nd line
LCDString (VersionString2); //Display software date
waitTime(32767); //Wait some more
LCDPrintAt(0,1); //2nd line
zeros=5; //assume 1ppr and therefore 1 trailing zero
scale=6; //...and scale result by 6
if (PA.B0==0)
{
LCDString("06"); //6 marks per rev
zeros=5; //...therefore 1 trailing zero
scale=1; //...and scale by 1
}
else if (PA.B1==0)
{
LCDString("60"); //60 marks per rev
zeros=6; //...therefore 0 trailing zeros
scale=1; //...and scale by 1
}
else LCDString("00"); //60 marks per rev
LCDString(" PPR "); //
waitTime(32767); //Wait a bit
LCDPrintAt(0,1); //2nd message
LCDString(" 0 RPM"); //assume 1 mark per rev
LCD(0x104); //Force reverse cursor for number printing
//Initialise Port B and Interrupt settings
TRISB=0x01; //Set bits 1 to 7 of Port B to output,
//bit 0 to input
OPTION_REG=0x85; //Pull ups on B, TMR0 internal, 64 prescale
INTCON|=(1<<T0IE)|(1<<GIE)|(1<<INTE);
//Enable interrupts for TMR0 & INTE
// MAIN CONTROL LOOP - Select major mode & execute that mode's behaviour
while(1) //Loop forever
{
if (timeInt) //If there has been a 1/10th second interrupt
{
timeInt=0; //Clear the int flag
actual=countHi;
actual=(actual<<8)+countLo;
//Get the count value
countLo=0; //Clear the count value
countHi=0;
actual=actual*scale; //Scale the value by 1 or 6
LCDNum(); //Print the value
LCDPrintAt(16,1); //Lose the cursor
}
}
};
//
// Waittime function - waits for a specified delay period.
//
void waitTime(unsigned int time)
{
while(time--) ; //Repeat loop time times
};
//
// LCD Clear function
//
void clearLCD()
{
LCD(0x108); //Display off
LCD(0x101); //Clear display, cursor home
LCD(0x10f); //Display on, cursor on, flash cursor
LCD(0x180); //Print position 0,0
};
//
// LCDNum function - prints 4 digit revCount to LCD display (backwards)
// Includes decimal point if the point parameter is within range of digits
//
void LCDNum()
{
char digits;
LCD((int)zeros-1+0x180+0x40); //Print position zeros,0
for(digits=5; digits; digits--)
{
LCD((actual%10)+'0'); //Print Nth digit
actual/=10; //lose Nth digit
}
};
//
//Interrupt handler
//Interrupt generated every 1/50 secs by timer 0
//and every time a pulse is detected on Port B bit 0
//
const int QuickInt=1; // Flag use of quick interrupts
void Interrupt()
{
#asm
btfss INTCON,INTF ; If tacho interrupt...
goto noTach
incfsz countLo ; Increment low count
goto clearTach
incf countHi ; Increment high count if necessary
clearTach:
bcf INTCON,INTF ; Clear tacho interrupt...
noTach:
btfss INTCON,T0IF ; If timer interrupt...
goto noTimer
decfsz sec ; Decrement seconds count
goto clearTimer
movlw 1
movwf timeInt ; Signal a timer interrupt
movlw 50
movwf sec ; Re-prime the timer
clearTimer:
bcf INTCON,T0IF ; Clear timer interrupt...
noTimer:
#asmend
}