1
\$\begingroup\$

My goal is to measure PWM pulses. But to achive that I'm making baby steps, so my first goal is to set a pin when an edge of the PWM signal is detected. The PWM signal enters the microcontroller (pic18f25k80, Datasheet) on the INT1 pin (RB1). I wrote the code to initialize the external interrupt:

#include <stdio.h>
#include <stdlib.h>
#include <pic18f25k80.h>
#include "config.h"


void main() {
        TRISB1 = 1;                 // INT1 as input
        LATB1 = 0;                  // Clear INT1
        TRISC6 = 0;                 // RC6 as output
        LATC6 = 0;                  // Clear RC6

        //Setup of INT1
        RCONbits.IPEN = 0;          //Disable priorities
        INTCONbits.GIE_GIEH = 1;    //Enable Global interrupt
        INTCONbits.PEIE_GIEL = 1;   //Enable peripheral interrupts
        INTCON2bits.INTEDG1 = 1;    // Edge select for INT1
        INTCON3bits.INT1IE = 1;     // Enable the INT1 external interrupt
        //INTCON3bits.INT1IP = 0;     // Low priority
        INTCON3bits.INT1IF = 0;        //Clear external interrupt flag bit

        while(1) {
        }
    }
    //Interrupt Service Routine

    #pragma code isr=0x08
    #pragma interrupt isr

    void isr(void)
    {
        if(INTCON3bits.INT1IF){
            LATC6 = 1;
        }
    }

    #pragma code

It seems that the interrupt flag doesn't go high, because the RC6 pin is low. I've measured that with an oscilloscope. What am I doing wrong?

BTW is that the correct way to call a ISR?

\$\endgroup\$
  • 2
    \$\begingroup\$ What compiler are you using? \$\endgroup\$ – David Nov 5 '14 at 8:28
  • 1
    \$\begingroup\$ Also this processor has a CCP module that might be suitable for what you are trying to do. \$\endgroup\$ – David Nov 5 '14 at 8:30
3
\$\begingroup\$

This is probably because there are other functions on pin B1 that need to be disabled before you can use it as a digital input.

In the datasheet we find table 11-4, shown below:

enter image description here

A quick look at that register in the datasheet shows that it is 1 by default, which means analogue input mode:

enter image description here

You will need to clear this bit before you can use it as a digital input.

You will also need to reset INTCON3bits.INT1IF to 0 in your interrupt service routine or the handler will keep firing and you will never escape it.

If you are trying to measure PWM you might like to read section 20.2 "Capture Mode" in the datasheet. This uses the Enhanced Capture and Compare Peripheral. It acts like your edge selection interrupt but will also store the value of TMR1 or TMR3, allowing you to make measurements of the period or duty cycle (or both).

| improve this answer | |
\$\endgroup\$
  • 1
    \$\begingroup\$ The highlighting of your table 11-4 is misleading. The column "Bit 1" doesn't refer to pin B1 except for the first three rows. All the other rows are nothing to do with B1 in that column. For instance, B1 is INT1, which is controlled by bits under columns 0, 3 and 6. It's AN8, not AN9, so the ANSEL8 bit in column Bit 0 needs clearing, not ANSEL9. It would be better to highlight the individual cells, not the one column. \$\endgroup\$ – Majenko Nov 5 '14 at 10:34
  • \$\begingroup\$ Hopefully fixed @Majenko-notGoogle. \$\endgroup\$ – David Nov 5 '14 at 13:32
  • \$\begingroup\$ You might want to update the Register 23-9 image too... \$\endgroup\$ – Majenko Nov 5 '14 at 13:33
  • \$\begingroup\$ Done this also @Majenko-notGoogle - thanks! \$\endgroup\$ – David Nov 5 '14 at 13:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.