2
\$\begingroup\$

I'm trying to use the input capture module on a PIC32MX250F128B to measure the frequency of a square wave. The results I'm getting are both inconsistent and incorrect. All I'm trying to do here is measure the frequency of the input square wave by reading the capture value at every falling edge interrupt. Then I reset Timer2 and read the capture value again at the next interrupt.

Here's my ISR:

void __ISR(_INPUT_CAPTURE_4_VECTOR, ipl1) Capture4(void) {
 mPORTBToggleBits(BIT_10);
 capture_value = IC4BUF; 
 mIC4ClearIntFlag();
 TMR2 = 0;
}

Here's my module configurations:

IC4Rbits.IC4R = 0; // Assign peripheral pin RPA0 to IC4
mPORTASetPinsDigitalIn(BIT_0);
IC4CONbits.C32 = 0; // 16-bit source timer
IC4CONbits.ICTMR = 1; // Use Timer2
IC4CONbits.ICI = 0; // Interrupt every capture event
IC4CONbits.ICM = 2; // Simple Capture Event mode - every falling edge
IFS0bits.IC4IF = 0; // Clear interrupt flag
IFS0bits.IC4IE = 1 // Enable IC interrupt
IFS0bits..IC4IP = 1; // Set interrupt priority to 1
IC4CONbits.ON = 1; // Enable IC module
T2CONbits.ON = 0; // Disable while config
TCONbits.SIDLE = 0; // Continue in idle mode
TCONbits.TCS = 0; // Use internal clock
TCONbits.TCKPS = 0; // Set 1:1 prescale
TCONbits.TGATE = 0; // Disable gated time accumulation
PR2 = 0xFFFF; // set period register
TMR2 = 0; // start counting at zero
T2CONbits.ON = 1; // enable module

You'll notice the first line of the ISR toggles a digital output pin; I added this so I could monitor the activity to see if the interrupt was ever called. The interrupt does get called and I've viewed it on an oscilloscope. I would expect the ISR to be called consistently in line with the falling edges of the input square wave but this is not the case. Instead, the ISR is called inconsistently at seemingly random intervals. Also, the values being read from IC4BUF don't correlate at all with any adjustments to the input signal's frequency.

Clearly I'm missing something here. If you have any suggestions or can point out any obvious errors that I've made, that would be greatly appreciated. Also, I'm open to alternative methods for accomplishing the task of measuring the input frequency. I chose this route with the Input Capture because it seemed to make the most sense. Thanks!

asked Mar 30, 2015 at 17:31
\$\endgroup\$
4
  • \$\begingroup\$ What range of frequencies are you aiming to measure, and what is the clock speed of your PIC? \$\endgroup\$ Commented Mar 30, 2015 at 18:29
  • \$\begingroup\$ Is capture_value declared as volatile? \$\endgroup\$ Commented Mar 30, 2015 at 18:55
  • \$\begingroup\$ The PIC is clocking at 48 MHz. I'm anticipating inputs ranging from 0.1 - 100 KHz \$\endgroup\$ Commented Mar 30, 2015 at 19:05
  • \$\begingroup\$ @RogerRowland, yes I've tried with capture_value declared as volatile, no change \$\endgroup\$ Commented Mar 30, 2015 at 23:23

1 Answer 1

1
\$\begingroup\$

Check this command: IFS0bits.IC4IE = 1. Here IEC0 register should be used IFS0 is used to check the flag bits which get SET when any interrupt occurs. So, modify your command as follows:

IEC0bits.IC4IE = 1

(If it still does not work then check your datasheet for the location of IC4IE bit.)

IFS0bits..IC4IP = 1 : this command is also wrong , you have to use IPC0 register for setting the priority of the Input Capture.

Dmitry Grigoryev
26.2k6 gold badges49 silver badges111 bronze badges
answered Jul 28, 2017 at 11:19
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.