# pic 16f877a code problem (frequency counter)

#### sayf alawneh

Joined Aug 4, 2014
20
this code is for frequency meter project
crystal oscillator is 12 Mhz
the external pulse is a square one with 300 Khz frequency
the code is designed to measure 524 Khz with prescalar value 1:8
but it only measure up to 63Khz only do u know the reason guys ?
her is the code
C:
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;// End LCD module connections
char i;
unsigned short cnt;
unsigned int freq_result;
// Define Messages

char message1[ ] = "Freq          Hz";

char *freq = "00000";

void Display_Freq(unsigned int freq2write) {

freq[0] = (freq2write/10000)%10 + 48;   // extrct hundred thousnads digit
freq[1] = (freq2write/1000)%10 + 48;    //extract thousands digit
freq[2] = (freq2write/100)%10 + 48;    //extract hundreds digit
freq[3] = (freq2write/10)%10 + 48;    // Extract tens digit
freq[4] =  freq2write%10     + 48;    // Extract ones digit
Lcd_Out(1, 6, freq);                   // Display Frequency on LCD

}
void main()
{
TRISB = 0;
PORTB = 0xFF;
TMR1H = 0x00;                         // Initialize Timer1 register
TMR1L = 0x00;                         // Initialize Timer1 register
T1CON = 0B00110011;                            // Timer1 on, external input RC0 and 1:8 scalling
TMR1IF_bit = 0;                       // clear TMR1IF

TRISC = 0xff;                         // all input
//////////////////////#LCD INITIALIZATION#////////////////////
Lcd_Init();                        // Initialize LCD
Lcd_Cmd(_LCD_CLEAR);                // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF);           // Cursor off
/////////////////////////////////////////////////////////////
Lcd_Out(1,1,message1);                // Write message1 in 1st row
do {

TMR1H = 0;                               // reset high byte of timer 1 (takes effect when low byte written)
TMR1L = 0;                               // reset low byte of timer 1 (also loads in high byte now)

Delay_ms(1000);  // Delay 0.1 Sec

freq_result = TMR1L;                      // get low byte of timer 1 count (and read high byte to buffer)
freq_result += TMR1H*256;                 // add in the high byte from buffer
freq_result*=8;
Display_Freq(freq_result);                // show the result on LCD

} while(1);  // Infinite loop

#### ericgibbs

Joined Jan 29, 2010
18,611
hi,
I dont use C, but this line is suspect... Delay_ms(1000); // Delay 0.1 Sec

If your gate is open for 1 second, and the freq input is 524KHz, and Timer1 is only 16bit.? thats 65535

#### sayf alawneh

Joined Aug 4, 2014
20
hi,
I dont use C, but this line is suspect... Delay_ms(1000); // Delay 0.1 Sec

If your gate is open for 1 second, and the freq input is 524KHz, and Timer1 is only 16bit.? thats 65535
its just a mistake its a delay of 1 second i used a prescaler of 1:8 so every 8 pulses r counted as one so i can get 65535*8 frequency thats 522k frequency but i cant read more than 63k hz thats my problem :/

#### FroceMaster

Joined Jan 28, 2012
688
Could this be the problem "unsigned int freq_result;"
Unsigned int is from 0 to 65535, even if u multiply by 8.

#### jjw

Joined Dec 24, 2013
819
The variable freq_result should be 32bit long integer.

#### djsfantasi

Joined Apr 11, 2010
9,151
…and intermediate variables should also be 32 bit integers to avoid conversion errors. Or cast intermediate values to the target variable type.