0
\$\begingroup\$

so I am working on learning some AVR programming with the ATmega328p. I am trying to set up a pin change interrupt and this is the code I am running. However, the interrupt never seems to trigger. Is there anything I am doing wrong?

Is there some way I can test this outside of using a board, like in simulation? I am using Atmel Studio.

Thanks!

#include <avr/io.h>

#define F_CPU 16000000UL
#include <util/delay.h>
#include <avr/interrupt.h>

#define ON_B0 PORTB |= (1 << PORTB0)
#define OFF_B0 PORTB &= ~(1 << PORTB0)
#define TOGGLE_B0 PINB |= (1 << PINB0)

ISR(PCINT1_vect)
{
    // Check if pin B1 is low)
    if ( !( PINB & (1 << PINB1) ) )
    {
        ON_B0;
    }
    else
    {
        OFF_B0;
    }   
}

int main(void)
{
    DDRB |= ( 1 << DDB0 );
    DDRB &= ~( 1 << DDB1 );

    PCMSK0 |= ( 1 << PCINT1);
    PCICR |= ( 1 << PCIE0);

    sei();


    while (1) 
    {
        PORTB |= ( 1 << PORTB1);
    }
}
\$\endgroup\$
  • 1
    \$\begingroup\$ I didnt get that the code inside the infinite while loop. Are you setting a port pin that you've config'd as input? Did you try without that line (i.e. with only the infinite while loop)? One more thing (just to check that the ISR is triggered): Toggle the pin (by XORing with 1) instead of checking whether it is 0 or 1. \$\endgroup\$ – Rohat Kılıç Aug 7 '17 at 21:27
3
\$\begingroup\$

The problem is you have an ISR on the PCINT1 vector, but the vector for PORTB pin changes is PCINT0. Uninitialized vectors jump to address 0, so the MCU resets when a pin change interrupt occurs on PORTB.

This is an easy mistake to make because PCINT1 is the designation of pin PB1 for pin change, and also the name of the vector for pin change interrupts on PORTC (thanks Atmel!).

You need to change ISR(PCINT1_vect) to ISR(PCINT0_vect).

Is there some way I can test this outside of using a board, like in simulation?

Yes (this is how I found the error in your code). In AVR simulator you can simulate a pin change by clicking on the pin to toggle it, then follow the resulting code execution with 'step into' (F11). View disassembler to step through the machine code one instruction at a time.

enter image description here

\$\endgroup\$
0
\$\begingroup\$

the interrupt never seems to trigger.

You probably want to assure yourself that the ist isn't firing. Otherwise you are solving A non existent problem.

Secondly read the datasheet to see how you clear the point flag.

Having simpler code helps too.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.