中断不工作的 ATmega32 模拟比较器代码

问题描述

我为我的 ATmega32 编写了一个代码,使用模拟比较器的中断点亮 LED,但 ISR 不会执行。我正在 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.
}

添加了一行代码来切换 while 循环之间的一个引脚,以查看是否发生了任何中断,但 while 循环内的引脚一直在切换。我在这里遗漏了什么吗?

解决方法

编辑:

ATMega32 位宏是实际的位数 (0,1),当用于寄存器的位表达式时需要左移。

ACSR |= (ACIE)|(ACIS1);
应该
ACSR |= (1 << ACIE)|(1 << ACIS1);


这里有很多事情可能会出错。而且我没有看到任何明显的错误(除了上述内容)。

我添加了一行代码来在 while 循环之间切换另一个引脚,以查看是否有任何中断发生,但 while 循环内的引脚一直在切换

我不明白这是什么意思 - 你能为这个测试添加一个代码片段吗?

这是我要采取的一些故障排除步骤。

  1. 您能否验证此代码是否可以点亮 LED?

这可以隔离 LED 代码/电路的问题。
尝试一些像这样的主要功能:

#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. 如果可行,还有更多内容需要使用 Comparator 进行检查。

你是如何刺激比较器输入的?你有电压表来验证比较器应该被触发吗?您将电压施加到哪些引脚?