/*
* SIMPLE SERIAL FREQUENCY METER
*
* this program writes one time per second to the RS232 communication line,
* the frequency of the input signal on the RB0 pin
*
* PIC16F877A
* 4 Mhz crystal, XT clock
*
* PORTB.0, in : counter input
* PORTc.6, out : RS232 tx
* PORTc.7, in : RS232 rx
*/
sbit BUZZER at RC1_bit; // Buzzer connections
sbit BUZZER_Direction at TRISC1_bit;
/*
* RAM variables
*/
unsigned long cntr ; // number of RB0 transition
unsigned int ovrflw ; // number of timer0 overflows
unsigned char str[10] ; // display result string
/*
* constant strings
*/
const unsigned char welcome[] = "\r\rRS232 Frequency Meter Ready" ;
const unsigned char unit[] = " Hz\r" ;
/*
* write the s ram string to RS232
*/
void Comm_Write(unsigned char *s)
{
while(*s)
{
Soft_Uart_Write(*s) ;
s++ ;
}
}
/*
* write the s constant string to RS232
*/
void Comm_WriteConst(const unsigned char *s)
{
while(*s)
{
Soft_Uart_Write(*s) ;
s++ ;
}
}
/*
* convert the cnrt long value to string
*/
void Long2str(void)
{
unsigned char i, j ;
if(cntr == 0)
{
str[0] = '0' ;
str[1] = 0 ;
}
else
{
str[0] = 0 ;
i = 0 ;
while(cntr > 0)
{
for(j = i + 1 ; j > 0 ; j--)
{
str[j] = str[j - 1] ;
}
str[0] = cntr % 10 ;
str[0] += '0' ;
i++ ;
cntr /= 10 ;
}
}
}
/*
* interrupt routine called 4000000/256 times by seconds :
* the timer TMR0 is increased each 4 clock cycles (quartz frequency is 16 Mhz),
* and overflows when reseting from 255 to 0,
* calling the interrupt procedure with bit T0IF set
*
* also called on each RBO transition, with bit INTF set
*/
void interrupt(void)
{
if(INTCON.INTF)
{
/*
* RB0 interrupt
*/
cntr++ ; // inc. transition counter
INTCON.INTF = 0 ; // clear interrupt flag to enable next call
}
else if(INTCON.T0IF)
{
/*
* TIMER 0 overflow
*/
ovrflw++ ; // inc. overflow counter
INTCON.T0IF = 0 ; // clear interrupt flag to enable next call on overflow
}
}
/*
* entry point
*/
main()
{
Sound_Init(&PORTC,1);
Sound_Play(1000,100);
Soft_Uart_Init(PORTC, 7, 6, 9600, 0) ; // RS232 on PORTC, bits 7 & 6, 38400 bauds
Comm_WriteConst(welcome) ; // write welcome message
TRISB0_bit = 1 ; // RB0 interrupt pin as input
// T0CON = 0b11001000;
OPTION_REG = 0b01001000 ; // no prescaler
/*
* main loop
*/
for(;;)
{
cntr = 0 ; // clear counters
ovrflw = 0 ;
INTCON = 0b10000110; // T0IF, INTF and GIE enabled
while(ovrflw < 3906) ; // wait 1 second : 15626 = 16 000 000 / 4 / 256, rounded up
INTCON.GIE = 0 ; // stop all interrupts
Long2Str() ; // convert counter to string
Comm_Write(str) ; // write string
Comm_WriteConst(unit) ; // write unit
}
}
//