# pic 16f877a code problem (frequency counter)

Discussion in 'Embedded Systems and Microcontrollers' started by sayf alawneh, Oct 3, 2014.

1. ### sayf alawneh Thread Starter New Member

Aug 4, 2014
20
0
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
// 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

2. ### ericgibbs AAC Fanatic!

Jan 29, 2010
2,595
393
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

3. ### sayf alawneh Thread Starter New Member

Aug 4, 2014
20
0
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 :/

4. ### FroceMaster Member

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

djsfantasi likes this.
5. ### jjw Member

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

6. ### djsfantasi AAC Fanatic!

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