NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Support Forum » Interrupt troubles

June 12, 2010
by keithka
keithka's Avatar

I'm just trying to get a simple pushbutton to work, and my ISR isn't getting called. I'm having trouble following the datasheet, since it seems to refer to the same pin by different names - one moment it's PCINT1, then it's PB1. Or is there some other register where I need to make it explicit how I'm using that pin? I tried understanding the PC keyboard example, but I think it really is using multiple pins.

I'm trying to use pin15 (in the bottom right, row 24 on the breadboard). My code includes:

PCMSK0 |= (1<<PCINT1);

PCICR |= (1<<PCIE0);

PORTB |= (1<<PB1); // I've tried with and without this line


And my ISR is declared as:

ISR(PCINT1_vect) {

    // tiny bit of code with obvious effect

    // it modifies a volatile global variable


My project is a metronome - so I'm using a timer to blink two LEDs (code lifted from the realtime clock sample) and I wonder if maybe the timer is trying to use the same pin I'm using. But nothing I do to pin 15 has any effect on the metronome's ability to blink lights.

Electrically, I've tried letting the wire from pin 15 float, plugged it into ground and into +5v. None of them seem to fire my interrupt.

Is there another bit I need to fiddle with to enable the PCINT1? Thanks in advance.

June 12, 2010
by keithka
keithka's Avatar

I think I get it now. Page 67 of the ATmega168 datasheet says that PCINT0 through 7 all fire the same software interrupt, which seems to be the one we call ISR(PCINT0_vect) in software. In other words, there's an interrupt line called PCINT1, and a software interrupt vector called PCINT1, but they don't actually correspond to each other.

Can any of the experts confirm that I'm understanding this correctly now?

June 13, 2010
by BobaMosfet
BobaMosfet's Avatar

When I look at page 67, I see information on external interrupts-- these may be different that what you want. External interrupts are about external events (pin change) triggering interrupts. I couldn't get my eye on the "all fire the same software interrupt" part you were mentioning.

Look at page 62 (table 11-4). Here you will see a listing of your interrupts, counters, and vector(s).

I would also look at page 16 (Section 6.8 - "Reset and Interrupt Handling") for an overview.

Essentially, set up your clock, set up the prescaler, set up the registers. Then set the condition to fire off the interrupts. These things must be calculated based on the frequency of interrupt you want.


June 13, 2010
by keithka
keithka's Avatar

The part I'm looking at is "The pin change interrupt PCI0 will trigger if any enabled PCINT7..0 pin toggles." So since I've got my start/stop button wired to PCINT1, I put the code to handle the start/stop button in the PCINT0_vect ISR. Good news is it works now, I just want to make sure I didn't just get lucky, and I'm actually reading the datasheet correctly now.

June 13, 2010
by keithka
keithka's Avatar

Also it looks like I do prefer having the pullup resistor enabled with the line:

PORTB |= (1<<PB1);

I have the switch wired to connect pin 15 to ground, and I read the value (to tell if the button is pressed) with PINB & (1<<PB1). Fun stuff.

June 13, 2010
by mrobbins
(NerdKits Staff)

mrobbins's Avatar

Hi keithka,

From reading your earlier posts, I do think that using PCINT1_vect instead of PCINT0_vect was your original problem. Glad to hear that you got it working. Until reading your post, I don't think that I realized until now that these new-style interrupt names were so confusingly done! The older notation (SIG_PIN_CHANGE0) would have at least not made the individual pin names (PCINT1) overlap with the three groups of masked pin change interrupts...


Post a Reply

Please log in to post a reply.

Did you know that two resistors can be used to make a voltage divider? Learn more...