Measure low frequency signal in MikroC and PIC

Status
Not open for further replies.

Rtk89

Newbie level 6
Joined
Nov 15, 2013
Messages
12
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
85
Dear everybody,

I am trying to write an easy code to PIC12F615, but it is not working.
I would like low level in GP0 pin when the frequency is under 5Hz or no signal in GP2 pin, but the output (GP0) has unstable state.
The PIC is working with 4MHz quartz.

Code:
unsigned int t=0;
int cnt=0;

void interrupt() {
        if(CCP1IF_bit == 1) {    // Rising edge
        CCP1IF_bit = 0; //reset capture interrupt flag
        cnt++;
        if(cnt == 1) // first rising edge is detected
           {
            TMR1ON_bit = 1; //timer1 start counting
           }
        if(cnt == 2) //second rising edge is detected
        {
               TMR1ON_bit = 0;  //stop timer1
               t = (CCPR1H<<8) + CCPR1L;         // Store the current value of Timer1
               CCPR1L=0;                        //Reset timer
               CCPR1H=0;
               PIE1.CCP1IE = 0;
               PIR1.CCP1IF = 0;   //reset capture interrupt flag
               PIE1.CCP1IE = 1;
               cnt=0; //reset rising edge counter
        }



     }
     if(TMR1IF_bit == 1){ // TMR1 Overflow
        TMR1ON_bit = 0;  //stop timer1
        CCPR1L=0;                        //Reset timer
        CCPR1H=0;
        TMR1IF_bit = 0;   //Reset TMR1 Overflow bit
        cnt=0;            //Reset riding edge counter
        t = 0;
     }
}

void Configure_Capture(){
 //1:8 Prescaler, External CLK
  T1CKPS1_bit = 1;
  T1CKPS0_bit = 1;
  //Capture every rising edge
  CCP1M3_bit = 0;
  CCP1M2_bit = 1;
  CCP1M1_bit = 0;
  CCP1M0_bit = 1;

CCP1IE_bit = 1;       // Enable CCP1 interrupt
 //enable all interrupts
PEIE_bit = 1;
GIE_bit = 1;
TRISIO = 001100;      //GP0, GP1 ,GP4 ,GP5 are outputs , GP2, GP3 are inputs

 //reset high & low bytes of timer1 & capture registers
  TMR1H = 0; TMR1L = 0;
  CCPR1H = 0; CCPR1L = 0;
  TMR1ON_bit = 0;
}



void main() {
GPIO = 0;
ANSEL = 0;         // All pin digital
ADCON0 = 0x00; // Disable ADC
CMCON0=0;
CMCON1=0; // Disable comparators

Configure_Capture();

do{
       if(t <= 50000 && t > 0){
         GPIO = 000001;
      }   else GPIO = 000000;

} while(1);

}

Thank you very much for help.
 

I had some changes.

TMR1CS_bit = 0; // TMR1 use the internal clock (Fosc/4)

If I don't mistaken in this case I can measure up to 524 msec with the 16bit TMR1, because I set up 1:8 prescaler to TMR1.

Until some changes the code still not work. I simulated in Proteus, and the GP0 has unstable state with 10Hz input to GP2.

Code:
unsigned int t=0;
int cnt=0;

void interrupt() {
        if(CCP1IF_bit == 1) {    // Rising edge
        CCP1IF_bit = 0; //reset capture interrupt flag
        TMR1ON_bit = 0;
        cnt++;
        if(cnt == 1) // first rising edge is detected
           {
            TMR1ON_bit = 1; //timer1 start counting
           }
        if(cnt == 2) //second rising edge is detected
        {
               TMR1ON_bit = 0;  //stop timer1
               t = (CCPR1H<<8) + CCPR1L;         // Store the current value of Timer1
               CCPR1L=0;                        //Reset timer
               CCPR1H=0;
               TMR1H=0;
               TMR1L=0;
               PIE1.CCP1IE = 0;
               PIR1.CCP1IF = 0;   //reset capture interrupt flag
               PIE1.CCP1IE = 1;
               cnt=0; //reset rising edge counter
        }



     }
     if(TMR1IF_bit == 1){ // TMR1 Overflow
        TMR1ON_bit = 0;  //stop timer1
        CCPR1L=0;       //Reset timer
        CCPR1H=0;
        TMR1H=0;
        TMR1L=0;
        TMR1IF_bit = 0;   //Reset TMR1 Overflow bit
        cnt=0;            //Reset rising edge counter
        t = 0;
     }
}

void Configure_Capture(){
  //1:8 Prescaler (1MHz / 8 = 125kHz [8uS]
  T1CKPS1_bit = 1;
  T1CKPS0_bit = 1;
  //Capture every rising edge
  CCP1M3_bit = 0;
  CCP1M2_bit = 1;
  CCP1M1_bit = 0;
  CCP1M0_bit = 1;

  CCP1IE_bit = 1;       // Enable CCP1 interrupt
  //enable all interrupts
  PEIE_bit = 1;
  GIE_bit = 1;
  TRISIO = 001100;      //GP0, GP1 ,GP4 ,GP5 are outputs , GP2, GP3 are inputs

  //reset high & low bytes of timer1 & capture registers
  TMR1H = 0; TMR1L = 0;
  CCPR1H = 0; CCPR1L = 0;
  TMR1ON_bit = 0;
  TMR1CS_bit = 0; // TMR1 from internal clock (FOSC/4 => 4MHz/4= 1MHz [1uS])
}



void main() {
GPIO = 0;
ANSEL = 0;     // All pin digital
ADCON0 = 0x00; // Disable ADC
CMCON0=0;
CMCON1=0;      // Disable comparators

Configure_Capture();

do{
       if(t <= 25000 && t > 0){    // 25000 the value of the TMR1 at 200mS
         GP0_bit = 1;
      }   else GP0_bit = 0;

} while(1);

}

Please help me somebody. :wink:
 

hello


your code seems ok, even i did'nt test it.
but try reversed order to read CCP1

Code:
    t = CCPR1L+ (CCPR1H<<8) ;


maybe a similar probleme whit Timer16 bits order
when WRITE or READ it
 

Thank you for your reply. Unfortunately, It didn't fixed the problem, but I successfully solve the problem.
The following code is work

Code:
unsigned int t=0;
int cnt=0;
bit flag;

void interrupt() {
        if(CCP1IF_bit == 1) {    // Rising edge
        CCP1IF_bit = 0; //reset capture interrupt flag
        TMR1ON_bit = 0;
        cnt++;
        if(cnt == 1) // first rising edge is detected
           {
            TMR1ON_bit = 1; //timer1 start counting
           }
        if(cnt == 2) //second rising edge is detected
        {
               TMR1ON_bit = 0;  //stop timer1
               t = (CCPR1H<<8) + CCPR1L;         // Store the current value of Timer1
               CCPR1L=0;                        //Reset timer
               CCPR1H=0;
               TMR1H=0;
               TMR1L=0;
               PIE1.CCP1IE = 0;
               PIR1.CCP1IF = 0;   //reset capture interrupt flag
               PIE1.CCP1IE = 1;
               cnt=0; //reset rising edge counter
               flag=1;
        }



     }
     if(TMR1IF_bit == 1){ // TMR1 Overflow
        TMR1ON_bit = 0;  //stop timer1
        CCPR1L=0;       //Reset timer
        CCPR1H=0;
        TMR1H=0;
        TMR1L=0;
        TMR1IF_bit = 0;   //Reset TMR1 Overflow bit
        PIE1.CCP1IE = 0;
        PIR1.CCP1IF = 0;   //reset capture interrupt flag
        PIE1.CCP1IE = 1;
        cnt=0;            //Reset rising edge counter
        t = 0;
        flag=1;
     }
}

void Configure_Capture(){
  //1:8 Prescaler (1MHz / 8 = 125kHz [8uS]
  T1CKPS1_bit = 1;
  T1CKPS0_bit = 1;
  //Capture every rising edge
  CCP1M3_bit = 0;
  CCP1M2_bit = 1;
  CCP1M1_bit = 0;
  CCP1M0_bit = 1;

  CCP1IE_bit = 1;       // Enable CCP1 interrupt
  //enable all interrupts
  PEIE_bit = 1;
  GIE_bit = 1;
  TRISIO = 001100;      //GP0, GP1 ,GP4 ,GP5 are outputs , GP2, GP3 are inputs

  //reset high & low bytes of timer1 & capture registers
  TMR1H = 0; TMR1L = 0;
  CCPR1H = 0; CCPR1L = 0;
  TMR1ON_bit = 0;
  TMR1CS_bit = 0; // TMR1 from internal clock (FOSC/4 => 4MHz/4= 1MHz [1uS])
}



void main() {
ANSEL = 0;     // All pin digital
ADCON0 = 0x00; // Disable ADC
CMCON0=0;
CMCON1=0;      // Disable comparators

Configure_Capture();

do{
       if(flag == 1){
       if(t <= 25000 && t > 0){              // 25000 the value of the TMR1 at 200mS
         GP0_bit = 1;
         flag=0;
      }   else GP0_bit = 0;
          flag=0;
                     }
} while(1);

}
 

Not solved...

The GP0 pin don't go to low level when there is 0Hz signal in output pin.
How can I reach that?
 

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…