dsPIC33EP512MU810 analogue comparator not working

511 views Asked by At

I'm having trouble getting the analogue comparator working on a dsPIC33EP512MU810. I want to compare two external voltages. Connected to C1IN1+ is my reference voltage (1.5V) and C1IN1- is my variable voltage (1.1 - 1.9V). I've set the Event trigger to be generated on both rising edge and falling edge but I only get an interrupt when the program starts and nothing after that.

// Macro to provide an indicator of when the ISR is running on a digital output pin (G6).
#define MONIT_1 (LATGbits.LATG6)

// Configuration registers.
_FGS(GSSK_OFF);
_FOSCSEL(FNOSC_PRIPLL & IESO_ON);
_FOSC(FCKSM_CSDCMD & OSCIOFNC_OFF & POSCMD_XT & IOL1WAY_OFF);
_FWDT(FWDTEN_OFF);
_FPOR(BOREN_ON);
_FICD(ICS_PGD2);
_FAS(APLK_OFF);

// The SYS_OSCSEL bits are written to the OSCCON.NOSC bits to select a new
// oscillator and read from the OSCCON.COSC bits to determine the current
// oscillator.
#define SYS_OSCSEL      0b011       // 011 = Primary Oscillator with PLL (XTPLL, HSPLL, ECPLL)

#define SYS_FIN         8000000LL   // clock-frequecy in Hz with suffix LL (64-bit-long)
#define SYS_PLLPRE      0
#define SYS_PLLPOST     1
#define SYS_PLLDIV      38
#define SYS_FVCO        ((SYS_FIN * (SYS_PLLDIV + 2)) / (SYS_PLLPRE + 2))
#define SYS_FOSC        (SYS_FVCO / (2 * (SYS_PLLPOST + 1)))
#define SYS_FCY         (SYS_FOSC/2)

// bit 0 OSWEN: Oscillator Switch Enable bit
#define OSCCON_OSWEN    (0x0001)  
// bit 5 LOCK: PLL Lock Status bit (read-only)
#define OSCCON_LOCK     (0x0020)    
// bit 6 IOLOCK: Peripheral Pin Select (PPS) Lock bit
#define OSCON_IOLOCK    (0x0040)   

static volatile int _cout; // To capture the comparator output during the ISR.

int main(int argc, char** argv) 
{
     // Set up PLL to give Fosc = 40MHz from an 8MHz Crystal.
    CLKDIVbits.PLLPRE = SYS_PLLPRE;
    CLKDIVbits.PLLPOST = SYS_PLLPOST;
    PLLFBDbits.PLLDIV = SYS_PLLDIV;

    CLKDIVbits.DOZEN = 0;       // No Doze
    CLKDIVbits.ROI = 0;         // not setting recover on interrupt

    // Switch to PLL mode from XT.
    __builtin_write_OSCCONH(SYS_OSCSEL);
    __builtin_write_OSCCONL(OSCCON | 0x01);
    // Wait for Clock switch to occur
    while (OSCCON_OSWEN & OSCCON);                  
    // Wait for PLL to lock
    while (OSCCONbits.LOCK != 1);                   
    // Wait for Oscillator to match
    while (OSCCONbits.COSC != OSCCONbits.NOSC);     

    // PIN20, C1IN1+ as analogue reference pin, VBUS -> PL1.PIN20
    ANSELBbits.ANSB5 = 1;
    TRISBbits.TRISB5 = 1;
    // PIN11, C1IN1- as analogue voltage pin for VM1 -> PL1.PIN11
    ANSELGbits.ANSG7 = 1;
    TRISGbits.TRISG7 = 1;

    // PIN10: digital MONIT_1 
    ANSELGbits.ANSG6 = 0;
    TRISGbits.TRISG6 = 0;
    MONIT_1 = 0;

    // Disable comparator
    CM1CONbits.CON = 0;

    // Continue operation in idle mode.
    CMSTATbits.CMSIDL = 0;
    // Comparator output is internal only
    CM1CONbits.COE = 0;
    // Comparator input is not inverted
    CM1CONbits.CPOL = 0;
    // Trigger/event/interrupt is generated on any change of the comparator output (while CEVT = 0)
    CM1CONbits.EVPOL = 0b11;
    // Comparator reference input selection. VIN+ input connects to external C1IN1+ pin
    CM1CONbits.CREF = 0;
    // Comparator channel selection. VIN- input connects to external C1IN1- pin
    CM1CONbits.CCH = 0b00;

    // Enable comparators
    CM1CONbits.CON = 1;
    // Enable comparator interrupts
    IEC1bits.CMIE = 1;
    // Enable the global interrupt
    INTCON2bits.GIE = 1;
    // Clear comparator interrupt flag
    IFS1bits.CMIF = 0;

    // Clear this value to enable future triggers and interrupts.
    CM1CONbits.CEVT = 0;

    while(1)
    {
        Nop();
    }

    return (EXIT_SUCCESS);
}

void __attribute__ ((__interrupt__,no_auto_psv)) _CM1Interrupt(void)
{
    MONIT_1 = 1;        // Turn the G6 IO on.

    // Clear comparator interrupt flag
    IFS1bits.CMIF = 0;

    // Check if comparator event 1 occurred.
    if (CM1CONbits.CEVT > 0)
    {
        _cout = CM1CONbits.COUT;
        // Clear comparator events to trigger the next event.
        CM1CONbits.CEVT = 0;

    }
    MONIT_1 = 0;        // Turn the G6 IO off.
}
0

There are 0 answers