//----------------------------------------------------------------------------------------------------------------------
//
// Author: Kees van Nieuwburg
// Version 1.0
//
//-----------------------------------------------------------------------------------------------------------------------
asm __CONFIG _CP_OFF & _WDT_OFF & _XT_OSC & _PWRTE_ON
char Frequency[8] = {128,128,128,128,128,128,128,128};
char Frequency_old[8] = {128,128,128,128,128,128,128,128};
char Counter[4] = { 0,0,0,0 };
char Digit;
void Display();
void Correct();
char Count_Prescaler();
char Count_12bit();
void Count_delay();
void main(void)
{
char x,y;
disable_interrupt( GIE );
set_bit( STATUS, RP0 );
OPTION_REG = 52; // Set pescaler to 1:32 and enable the free-run timer
// to increment its value via external impulses on RA4/T0CKI pin.
set_tris_a( 240 ); // Set RA3 and lower to output
set_tris_b( 0 );
clear_bit (STATUS, RP0 );
delay_ms(250);
Count_12bit(); // Reset the 12-bit counter ( The counter wil stop at the point it has to begin its next cycle ).
while (1==1)
{
TMR0 = 0; // Reset timer 0
clear_wdt(); // clear prescaler
output_port_a( 15 ); // enable counting
Count_delay(); // count for 1 second
output_port_a( 12 ); // disable counting
if( Count_12bit() == 1 ) // The function Count_12bit() wil set the variable Counter. The counter value
{ // is the amount of pulses that were needed to complete the counters cycle.
// If counting isn't succesful Count_12bit() wil return 0.
Frequency[0] = Frequency[0] - Counter[0] + 5;
Frequency[1] = Frequency[1] - Counter[1] + 9;
Frequency[2] = Frequency[2] - Counter[2];
Frequency[3] = Frequency[3] - Counter[3] + 4;
Correct();
for( x = 0; x < TMR0; x++ )
{
Frequency[0] = Frequency[0] + 2;
Frequency[1] = Frequency[1] + 7;
Frequency[2] = Frequency[2] + 0;
Frequency[3] = Frequency[3] + 1;
Frequency[4] = Frequency[4] + 3;
Frequency[5] = Frequency[5] + 1;
Correct();
}
y = Count_Prescaler();
for( x = 0; x < y; x++)
{
Frequency[0] = Frequency[0] + 6;
Frequency[1] = Frequency[1] + 9;
Frequency[2] = Frequency[2] + 0;
Frequency[3] = Frequency[3] + 4;
Correct();
}
for(x = 0; x <= 7; x++)
{
Frequency_old[x] = Frequency[x] & 15;
Frequency[x] = 128;
}
}else
{
for(x = 0; x <= 7; x++)
{
Frequency_old[x] = 1;
Frequency[x] = 128;
}
}
}
}
char Count_Prescaler()
{
char i, TMR0_old;
TMR0_old = TMR0; // Save the value of timer 0
for(i = 1; i <= 32; i++)
{
output_port_a( 0 ); // give a puls
output_port_a( 8 );
if(TMR0 != TMR0_old) // check if timer value has changed
{
return 32 - i; // return the number of pulses the prescaler counted.
}
}
return 0;
}
char Count_12bit()
{
char y, x = 0;
for(Counter[3] = 0; Counter[3] <= 9; Counter[3] = Counter[3] + 1)
{
for(Counter[2] = 0; Counter[2] <= 9; Counter[2] = Counter[2] + 1)
{
for(Counter[1] = 0; Counter[1] <= 9; Counter[1] = Counter[1] + 1)
{
Display(); // Display a digit
for(Counter[0] = 0; Counter[0] <= 9; Counter[0] = Counter[0] + 1)
{
output_port_a( 12 ); // give a pulse
output_port_a( 14 );
y = ( input_port_a() & 16 );
if( y == 16 ) // test if RA4 is high
{
x = 1;
}
else if( x == 1 ) // If RA4 has been high before
{
Counter[0] = Counter[0] + 1; // correct the the counter ( from 0 to ... / 1 to ... )
return 1; // return that the count has been succesful
}
}
}
}
}
return 0;
}
void Correct()
{
/* The function correct works like the primary school method of counting
i believe it's callt "Ten pace ring" in englisch. If a number higher than
9(137) or lower than zero(128) the function wil correct the nurber. */
char i;
for (i = 0; i <= 6; i++)
{
if( Frequency[i] < 128 )
{
Frequency[i] = Frequency[i] + 10;
Frequency[i + 1] = Frequency[i + 1] - 1;
}
if(Frequency[i] > 137)
{
Frequency[i] = Frequency[i] - 10;
Frequency[i + 1] = Frequency[i + 1] + 1;
}
}
}
void Count_delay()
{
/* The function Count_delay() should take exactly one second during this
time pulses are counted and the frequency is displayed
I callibrated mij counter with a fuction generator and the following
delay worked best for me. */
char i;
int x;
for(i = 0; i < 250 ; i++)
{
Display();
delay_ms(1);
Display();
delay_ms(1);
Display();
delay_ms(1);
Display();
delay_us(250);
delay_us(250);
delay_us(250);
delay_us(139);
nop();
}
delay_us(113);
}
void Display()
{
/* Every time the display function is called the next karakter wil be displayed. */
Digit = Digit & 7;
output_port_b( Frequency_old[Digit] | ( Digit << 4 ) );
Digit++;
}
Copyright © 2002-2006 SourceBoost Technologies