Pinchangeinterrupt on PB6 / PB7

Hi all

I have a standalone 328P set to internal clock and i changed pins_arduino.h to have xtal pins (PB6 and PB7) as regular i/O ports (D20 and D21). I tested those pins with digitalRead and digitalWrite and they work fine.

Now i need to set PB6 (or PB7) to Pinchangeinterrupt, i saw this example

https://baremetalmicro.com/tutorial_avr_digital_io/06-Pin-Change-Interrupts.html

that uses pinchangeinterrupt on pin D2 ,but i don't know what to change to work with PB6 (or PB7).

Any help?

And your code is? Post something which you've tested.

PCMSK0 and PCINT0_vect is for PCINT6-7 (on PB6-7) in contrast with example from the link you've posted.

this is from pins_arduino.h:

const uint8_t PROGMEM digital_pin_to_port_PGM[] = {
	PD, /* 0 */
	PD,
	PD,
	PD,
	PD,
	PD,
	PD,
	PD,
	PB, /* 8 */
	PB,
	PB,
	PB,
	PB,
	PB,
	PC, /* 14 */
	PC,
	PC,
	PC,
	PC,
	PC,
	PB, /* add - 20  - PB6*/
    PB, /* add - 21  - PB7*/
};

const uint8_t PROGMEM digital_pin_to_bit_mask_PGM[] = {
	_BV(0), /* 0, port D */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(6),
	_BV(7),
	_BV(0), /* 8, port B */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(0), /* 14, port C */
	_BV(1),
	_BV(2),
	_BV(3),
	_BV(4),
	_BV(5),
	_BV(6), /* add - 20 - PB6 */
	_BV(7), /* add - 21 - PB7 */
};

and this is my code ( where i changed i commented the original code:

#include <avr/io.h>
#include <avr/interrupt.h>


ISR(PCINT0_vect) // original: ISR(PCINT2_vect)
{
    // Read PD2 using the Port D Pin Input Register (PIND)
    if (PINC & _BV(PINC6)) // original: if (PIND & _BV(PIND2))
    {
        // PD2 is high, so button is released

        // Set PB5 low using the Port B Data Register (PORTB)
        PORTB &= ~_BV(PORTB5);
    }
    else
    {
        // PD2 is low, so button is pressed

        // Set PB5 high using the Port B Data Register (PORTB)
        PORTB |= _BV(PORTB5);
    }
}

int main(void)
{
    // Configure PD2 as an input using the Data Direction Register D (DDRD)
    
    DDRC &= ~_BV(DDD6);   // original: DDRD &= ~_BV(DDD2);

    // Enable the pull-up resistor on PD2 using the Port D Data Register (PORTD)
    
    PORTC |= _BV(PORTC6);   // original: PORTD |= _BV(PORTD2);

    // Enable pin change interrupt on the PCINT18 pin using Pin Change Mask Register 2 (PCMSK2)
    
    PCMSK0 |= _BV(PCINT6);    // original: PCMSK2 |= _BV(PCINT18);

    // Enable pin change interrupt 2 using the Pin Change Interrrupt Control Register (PCICR)
    
    PCICR |= _BV(PCIE0);    // original: PCICR |= _BV(PCIE2);

    // Configure PB5 as an output using the Port B Data Direction Register (DDRB)
    DDRB |= _BV(DDB5);

    // Enable interrupts
    sei();

    // Loop forever
    while (1)
    {
        // Nothing to do here
        // All work is done in the ISR
    }
}

Led attached to D13 is always on

Firstly, PB6 should be configured as input pull-up.

DDRB &= ~_BV(DDB6);
PORTB |= _BV(PORTB6);

Hurray, it worked.

I assumed that PB6 was PORTC, but it is PORTB.
Inside ISR i also changed PINC & _BV(PINC6) to PINB & _BV(PINB6)

Thanks budvar10, i learn alot today!

Great!
Heh, the names are always according port names (A, B, C...). The rule is valid for all pins, registers, bits etc. You can find more in the datasheet.