PIC 16f877a frequency counter

Status
Not open for further replies.

dmta

Member level 2
Joined
Mar 25, 2013
Messages
52
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Location
Earth
Visit site
Activity points
1,650
Hi all,

I am trying to make a frequency counter and wrote some code. I wanted to use a frequency averaging part to make things more accurate. But when I run the code with the averaging part it acts funny (at frequencies close to 10kHz).

Also please give me some pointers to the variable declaration (eg int, float etc) as I am pretty sure me using "int" is wrong. Furthermore the way I am doing the calculations, is there a better/faster way of doing them.

I'm using a PIC16F877A with 4MHz crystal.

Regards

Code:
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;

int kk  = 0;
int fr  = 0;
int cnt = 0;
int rit = 0;
int acc = 0;
int i   = 0;
int fra[10];

char CN[10];

void interrupt() {

     if(INTCON.TMR0IF == 1){
          fr = (cnt + kk*256)*(1000000)/(256*256); //4MHz crystal, 256 Timer0 increment rate
         /*if(acc<10){         ///
               fra[acc] = fr; ///Counted frequencies are put into an array
               acc++;         ///
          }
          else if(acc >= 10){
               acc = 0;
               for(i=0;i<10;++i){       ///
                   rit = rit + fra[i];  ///Average frequency is calculated
               }                        ///
          rit = rit/10;                 ///
          }*/
     cnt = 0;
     kk  = 0;
     INTCON.TMR0IF=0;
     }

    if(INTCON.INTF == 1){
         cnt++;
         if(cnt>=256){
              cnt = 0;
              kk++;
         }
    INTCON.INTF = 0;
    }
}

void main() {

     Lcd_Init();
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Cmd(_LCD_CURSOR_OFF);
     
     PWM1_Init(1000);
     PWM1_Set_Duty(100);
     PWM1_Start();

     INTCON.GIE        = 1; //Enable Global Interrupt
     INTCON.INTE       = 1; //Enable RB0/INT external Interrupt
     INTCON.TMR0IE     = 1; //Enable TMR0 Overflow Interrupt
     
     OPTION_REG.T0CS   = 0; //Timer0 increments with Internal instruction cycle clock
     OPTION_REG.PSA    = 0; //Prescaler is assigned to the Timer0 module
     OPTION_REG.PS2    = 1; ////
     OPTION_REG.PS1    = 1; ////Timer0 increments every 256 instruction cycles
     OPTION_REG.PS0    = 1; ////
     OPTION_REG.INTEDG = 1; //Interrupt on rising edge
     
     while(1){
     
           IntToStr(fr,CN);
           Lcd_Out(1,1,CN); //Display the average frequency
     
     }

}
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…