Микроконтроллер ATmega88v
Схема: к выводу PD3 подтянут плюс питания через резистор 10к, подключена кнопка на землю.
К выводу PB0 подключен светодиод.
Тактируется от внутреннего генератора.
Код проверяю на железке.
Вот кодок.
Код
#include<ioavr.h>
#include<intrinsics.h>
volatile unsigned char x = 0;
int main(void)
{
DDRD = (1 <<DDD0)|(1 <<DDD1)|(1 <<DDD2)|(0 <<DDD3)|(1 <<DDD4)|(1 <<DDD5)|(1 <<DDD6)|(1 <<DDD7);
DDRB = 255;
PORTD = (0 << PD0)|(0 << PD1)|(0 << PD2)|(1 << PD3)|(0 << PD4)|(0 << PD5)|(0 << PD6)|(0 << PD7);
PORTB = 0;
EICRA = (0<<ISC11) | (0<<ISC10); // Select low lewel on INT1
EIMSK = (1<<INT1) | (0<<INT0); // Enable INT1 interrupts
SMCR = (0 << SM2)|(1 << SM1)|(0 << SM0)|(0 << SE);// power down
__enable_interrupt();
while(1)
{
if(x)
{
PORTB = 1;
__delay_cycles(800000);
__delay_cycles(800000);
__delay_cycles(800000);
PORTB = 0;
}
EIMSK = (1<<INT1)|(0<<INT0);
DDRD = 0;
PORTD = (0 << PIND0)|(0 << PIND1)|(0 << PIND2)|(1 << PIND3)|(0 << PIND4)|(0 << PIND5)|(0 << PIND6)|(0 << PIND7);
DDRB = 0;
PORTB = 0;
x = 0;
SMCR |= (1<<SE);
__sleep();
SMCR |= (0<<SE);
DDRD = (1 <<DDD0)|(1 <<DDD1)|(1 <<DDD2)|(0 <<DDD3)|(1 <<DDD4)|(1 <<DDD5)|(1 <<DDD6)|(1 <<DDD7);
DDRB = 255;
PORTD = (0 << PD0)|(0 << PD1)|(0 << PD2)|(1 << PD3)|(0 << PD4)|(0 << PD5)|(0 << PD6)|(0 << PD7);
PORTB = 0;
}
}
#pragma vector = INT1_vect
__interrupt void INT1_vect_INT(void)
{
EIMSK = (0<<INT1)|(0<<INT0);
x = 1;
}
#include<intrinsics.h>
volatile unsigned char x = 0;
int main(void)
{
DDRD = (1 <<DDD0)|(1 <<DDD1)|(1 <<DDD2)|(0 <<DDD3)|(1 <<DDD4)|(1 <<DDD5)|(1 <<DDD6)|(1 <<DDD7);
DDRB = 255;
PORTD = (0 << PD0)|(0 << PD1)|(0 << PD2)|(1 << PD3)|(0 << PD4)|(0 << PD5)|(0 << PD6)|(0 << PD7);
PORTB = 0;
EICRA = (0<<ISC11) | (0<<ISC10); // Select low lewel on INT1
EIMSK = (1<<INT1) | (0<<INT0); // Enable INT1 interrupts
SMCR = (0 << SM2)|(1 << SM1)|(0 << SM0)|(0 << SE);// power down
__enable_interrupt();
while(1)
{
if(x)
{
PORTB = 1;
__delay_cycles(800000);
__delay_cycles(800000);
__delay_cycles(800000);
PORTB = 0;
}
EIMSK = (1<<INT1)|(0<<INT0);
DDRD = 0;
PORTD = (0 << PIND0)|(0 << PIND1)|(0 << PIND2)|(1 << PIND3)|(0 << PIND4)|(0 << PIND5)|(0 << PIND6)|(0 << PIND7);
DDRB = 0;
PORTB = 0;
x = 0;
SMCR |= (1<<SE);
__sleep();
SMCR |= (0<<SE);
DDRD = (1 <<DDD0)|(1 <<DDD1)|(1 <<DDD2)|(0 <<DDD3)|(1 <<DDD4)|(1 <<DDD5)|(1 <<DDD6)|(1 <<DDD7);
DDRB = 255;
PORTD = (0 << PD0)|(0 << PD1)|(0 << PD2)|(1 << PD3)|(0 << PD4)|(0 << PD5)|(0 << PD6)|(0 << PD7);
PORTB = 0;
}
}
#pragma vector = INT1_vect
__interrupt void INT1_vect_INT(void)
{
EIMSK = (0<<INT1)|(0<<INT0);
x = 1;
}
Прерывание отрабатывается как надо, засыпает просыпается, все супер, НО если в то время когда светодиод горит нажать повторно кнопку,
и дождаться когда микроконтроллер уснет, отпустить кнопку, все , не реагирует ,только reset помогает.