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.

Microcontroller Programming » Using PCINT4

April 22, 2010
by fcowles
fcowles's Avatar

I am trying to hook up a pushbotton on PCINT4 of an ATMEGA 168. What interupt vector is used in the ISR? The data sheet has PCINT0-3, but no PCINT4.

Also, is there a good way to debounce a button to use with an ISR. I am getting multiple calls of the routine for a single push since the PCINTs fire on any change of the pin.

Fred

April 22, 2010
by bretm
bretm's Avatar

It's a little confusing because the datasheet uses PCINTx to name the individual pins, but also uses PCINT0 through PCINT2 to name the three supported interrupt vectors, each of which correspond to a set of 7 or 8 pins.

Section 12 spells it out:

The pin change interrupt PCI2 will trigger if any enabled PCINT23..16 pin toggles. The pin change interrupt PCI1 will trigger if any enabled PCINT14..8 pin toggles. The pin change interrupt PCI0 will trigger if any enabled PCINT7..0 pin toggles. The PCMSK2, PCMSK1 and PCMSK0 Registers control which pins contribute to the pin change interrupts.

April 22, 2010
by fcowles
fcowles's Avatar

So for PCINT4 (the PIN), I would use PCINT0_vect ?

April 22, 2010
by bretm
bretm's Avatar

You can debounce using either hardware or software.

If you already know you want to handle debouncing through software, and specifically by watching pin changes, you can trigger a timer that fires 15ms after the most recent change. If another change comes in within that time, restart the timer. Only if the timer successfully reaches 15ms without any other pin change do you pay attention to the change. This technique requires a timer interrupt.

You can do it with a timer interrupt alone, without a pin change interrupt. Just poll the pin every 2ms and if the state changed the 8th time ago but not on the previous 7 times, count it as a real change, e.g.

uint8_t pinState;

every 2ms do this:
   pinState = (pinState << 1) | ((PINB >> PB4) & 1);
   if (pinState == 0x80)
      pinWentLowAndStayed();
   else if (pinState = 0x7F)
      pinWentHighAndStayed();

This will miss any round-trip pin transitions that don't cross a 2ms polling boundary, but that might be OK.

April 22, 2010
by bretm
bretm's Avatar

Yes, PCINT0_vect for PCINT4 (pin PB4).

Post a Reply

Please log in to post a reply.

Did you know that SPDT stands for "Single Pole, Double Throw"? Learn more...