Search code examples
cmicrocontrolleravratmegaatmega32

ATmega32 analog comparator code with interrupts not working


I wrote a code for my ATmega32 to light an LED using the analog comparator's interrupts but the ISR won't execute. I'm testing on Proteus.

#define F_CPU 8000000UL

#include <avr/io.h>
#include <avr/interrupt.h>

#define LED_DDR     DDRA                ///< DDR of indicator LED.
#define LED_PORT    PORTA               ///< Port of indicator LED.
#define LED_PIN     PA0                 ///< Pin of indicator LED.

void PORT_INIT(void);
void COMPARATOR_INIT(void);

/*!
 *  @brief ISR for Analog Comparator Interrupt; turn on LED if an interrupt occurs.
 */

ISR(ANA_COMP_vect){
    LED_PORT |= (1<<LED_PIN);
}

int main(void){
    PORT_INIT();
    COMPARATOR_INIT();
    
    sei();                              ///< Enable global interrupts.
    
    while(1);
}

/*!
 *  @brief Initialize ports.
 */

void PORT_INIT(void){
    LED_DDR |= (1<<LED_PIN);
}

/*!
 *  @brief Initialize Analog Comparator.
 */

void COMPARATOR_INIT(void){
    ACSR = 0x00;                    ///< Enable Analog Comparator by setting ACD to 0.
    ACSR |= (ACIE)|(ACIS1);         ///< Enable Analog Comparator Interrupt and set Interrupt Mode to Falling Output Edge.
}

I added a line of code to toggle another pin between the while loop to see if any interrupts at all occur but the pin inside the while loop keeps toggling. Am I missing something here?


Solution

  • Edit:

    The ATMega32 bit macros are the actual bit numbers (0, 1) and need to be leftshifted when used in bitwise expressions with the registers.

    ACSR |= (ACIE)|(ACIS1);
    should be
    ACSR |= (1 << ACIE)|(1 << ACIS1);


    There's lots of things that could go wrong here. and I don't see anything obviously wrong (other than the above).

    I added a line of code to toggle another pin between the while loop to see if any interrupts at all occur but the pin inside the while loop keeps toggling

    I don't understand what this means - could you add a code snippet for this test?

    Here's a couple of troubleshooting steps I'd take.

    1. Can you verify that this code can light up the LED?

    This could isolate a problem with the LED code / circuit.
    Try some main function like this:

    #include <util/delay.h>
    //...
    int main(void){
        PORT_INIT();
        //COMPARATOR_INIT();
            
        //sei();                              ///< Enable global interrupts.
            
        while(1)
        {
            LED_PORT |= (1<<LED_PIN);
            _delay_ms(1000);
            LED_PORT = 0;
            _delay_ms(1000);
        }
    }
    
    }
    
    1. If that works, there's more to check on with the Comparator.

    How are you stimulating the comparator input? Do you have a voltmeter to verify the comparator should be triggered? What pins are you applying the voltage to?