I'm currently trying to create a simple program for an ATMega48 emulator that has a PCINT2 external interruptor listening on PORTD input and changing the output based on its value.
Here's the code of the interruptor:
unsigned int d; // a variable that has to change based on the input
ISR(PCINT2_vect) {
if (PORTD % 2 == 0) {
if (d <= 8000) {
d += 500;
}
} else {
if (d >= 1000) {
d -= 500;
}
}
}
the main() function:
int main(void)
{
DDRD = 0x00; // set PORTC for input
DDRB = 0xFF; // set PORTB for output
PORTB = 0x00; // Initial value is 0
PCMSK0 = 0b00000100;
d = 4000;
sei();
while (1) {
// Enable\Disable the LED with an initial delay
if (PIND == 0b00000000) {
PORTB = 0b00100000;
} else {
PORTB = 0b00000000;
}
// Delay for N seconds (determined by interrupt)
delay_stuff(d);
}
return 1;
}
Currently it's not calling the interruptor no matter what happens to any port, my assumption is that I'm not registering some magical ATMega listeners to call the interruptor. How to register the interruptor then, what am I missing here?
According to datasheet page 75-76, you must enable Pin Change Interrupt in PCICR
register and select which pin will be enabled on the corresponding IO in PCMSK2
for PCINT2
(PCMSK0
is for PCINT0
, i.e PINB
).
int main(void)
{
DDRD = 0x00; // set PORTC for input
DDRB = 0xFF; // set PORTB for output
PORTB = 0x00; // Initial value is 0
PCICR |= _BV(PCIE2); //or, PCICR |= 0x04;
PCMSK2 |= 0xFF; //any changes in PIND will trigger interrupt
d = 4000;
sei();
//other codes...
}