gpt4 book ai didi

c - ATmega88 中断服务程序执行两次

转载 作者:行者123 更新时间:2023-11-30 19:22:05 26 4
gpt4 key购买 nike

我一直在寻找这个问题的答案,但一无所获。当我的 ISR 被触发时,它会执行并完成所有应该完美完成的事情,然后在退出并返回主循环之前 ISR 再次执行。一旦第二次完成,它就会返回到主循环。仅当我使用 115V 继电器来操作中断时才会发生这种情况。

我正在尝试检测何时断电或何时恢复供电。我正在使用引脚更改中断来感测继电器是否闭合或打开。当电源关闭时,继电器将打开并触发 ISR。如果我将此设置连接到普通按钮或开关,一切都会根据需要工作并且没有问题,只有当它连接到继电器时才会出现问题。

这是我的代码:(我知道我不需要 cli,我只是在尝试一切)

ISR(PCINT2_vect){

cli();

sbi(PORTC,5);
_delay_ms(6000);
cbi(PORTC,5);
for(delay_counter=0;delay_counter<2;delay_counter++)
{
_delay_ms(6000);
}
sbi(PORTC,5);
_delay_ms(6000);
if(bit_is_set(PIND,2))
{
lcd_clrscr();
lcd_puts("Sending SMS");
usart_print("at");
USART_Transmit('\r');
_delay_ms(6000);
for(i=0;i<=1;i++)
{
usart_print("at*smsm2m=");
USART_Transmit('"');
for(j=0;j<11;j++)
{
USART_Transmit(Alert_Numbers[i][j]);
}
usart_print(" Power has been lost");
USART_Transmit('"');
USART_Transmit('\r');
_delay_ms(6000);
}

lcd_clrscr();
lcd_puts("SMS Sent");
_delay_ms(6000);
lcd_clrscr();
lcd_puts("Status:NO POWER");
cbi(PORTC,5);
}

else if(bit_is_clear(PIND,2))
{
lcd_clrscr();
lcd_puts("System Reset");
_delay_ms(6000);
_delay_ms(6000);
usart_print("at");
USART_Transmit('\r');
_delay_ms(6000);
for(i=0;i<=1;i++)
{
usart_print("at*smsm2m=");
USART_Transmit('"');
for(j=0;j<11;j++)
{
USART_Transmit(Alert_Numbers[i][j]);
}
usart_print(" Pump regained power");
USART_Transmit('"');
USART_Transmit('\r');
_delay_ms(6000);
}

lcd_clrscr();
lcd_puts("POWER ON");
_delay_ms(6000);
lcd_clrscr();
lcd_puts("Status: Good");

}
else
{

}


}

int main(void)
{ /*Initializations*/
DDRC = 0x20; // PORTC,5 is now output
sbi(PORTC,5);
USART_Init(51);
lcd_init(LCD_DISP_ON);
lcd_clrscr();

/*Set interrupts*/
DDRD = 0b11111011; // set PD2 to input
PORTD = 0b00000100; // set PD2 to high
PCICR |= (1 << PCIE0);
PCMSK0 |= (1 << PCINT0);
PCICR |= (1<<PCIE2);
PCMSK2 |= (1<<PCINT18);
sei();


lcd_clrscr();
lcd_puts("Status: Good");

/*Main Program Loop: NOP*/
while(1)
{
lcd_clrscr();
lcd_puts("MAIN LOOP");
for(delay_counter=0;delay_counter<3;delay_counter++)
{
_delay_ms(6000);
}
}
}

最佳答案

I am using a Pin change interrupt to sense if the relay is closed or open.

不要那样做。严重地。不要尝试将机械开关连接到中断引脚来触发 ISR。

如果您坚持这样做,至少要确保开关信号在到达 µC 的输入引脚之前在硬件中得到适当的去抖 .

此外,任何类型的等待 (_delay_ms(6000);) 都不是人们希望在 ISR 中出现的情况。

关于c - ATmega88 中断服务程序执行两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18343058/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com