📜 ⬆️ ⬇️

External interrupts for 8-bit avr, using buttons

Hello, the other day I decided to experiment with external interruptions on attiny2313A . I think those who are engaged in programming microcontrollers know that the MC does not always quickly respond to pressing a button, since PIN verification is standardly carried out in an infinite loop, and if the program is large enough, it can slow down the pin polling.
The code below is written for WinAVR.

image

Standard poll:




')
In the second method , the usual polling in the loop will look like:
if (!(PINB & (1<<PINB6))){ // PORTB6, :
;
}
if (PINB & (1<<PINB7)){ // PORTB7, :
;
}

if you invert, it will turn out for the first method, but I don’t think it is necessary for someone.

So, External interrupts themselves.


In datashit on MK attiny2313A
there are interrupts INT0 (foot PD2), INT1 (foot PD3), and PCINT0..7 (the entire port B and although it has 8 legs, but the interruption is one for all, which personally does not please me)
Interrupts INT0 and INT1 their priority is higher than other interrupts.

In total, we can configure only three buttons without using a standard poll .
I had the idea that I will use external interrupts, then the DDR and PORT registers will not change anything in the behavior of the MC, but this is not so ... the output must also be configured as in standard processing.
Immediately make a reservation that I am writing about the legs, tuned to the pull-up resistors ie DDRxy & = ~ (1 << y); PORTxy | = (1 << y). otherwise it makes no sense, triggering from the touch of a finger, as it seems to me, does not interest anyone.

Control registers


So datasheet page 58 External Interrupts

MCU Control Register– MCUCR:
image

image
image

If it defaults , the low level of INT0 generates an interrupt request, then by pressing the button we will receive a vector response, if not released, the program will again and again go to the interrupt.

If any logical change on INT1 generates an interrupt request , then pressing the button and not releasing it, the interrupt function will work once and then the program will go according to the standard scheme, but when we wait for the button to go, it will again change the logic, then the vector will start again .

The falling edge of INT1 generates an interrupt request - the same as the default, in any case on experiments, only works less stable, while pressing the button can work.

The rising edge of INT1 generates an interrupt request - the button only works when you press it.

General Interrupt Mask Register - GIMSK:
Globally resolves the interruptions we need.
image

External Interrupt Flag Register - EIFR:
The registration is responsible for the execution of the interruption, if the logic on the leg has changed, then a record appears in the register, and the interruption vector begins to be processed.
image

Pin Change Mask Register - PCMSK:
Enables interruption on a particular leg of Port B
image

separately about PCINT

This is a non-configurable external interrupt, unlike others, and always works on the principle of Any logical change, which makes it difficult to use it, although it will also be used in reasonable hands.
And there is one more misfortune - there is a false alarm when the MK is powered up, it takes one time to interrupt and no longer fails, working in normal mode.

Supplement from Ocelot (in comments):
There is no big problem in that the interrupt is triggered by any level change (any logical change). In the interrupt handler, you can always check the port status and determine the event we need. The same goes for PCINT interrupt, which is one for all 8 legs. You can always easily find out exactly which input caused the interruption.

Interrupt vectors affecting our subject


image

void preriv() //
{
GIMSK=(1<<PCIE)|(1<<INT0);
PCMSK=(1<<PCINT0);
MCUCR=(0<<ISC00)|(0<<ISC01);
}
preriv();//

ISR(INT0_vect){ // INT0
PORTD|=(1<<PORTD4);
_delay_ms(1000);
}

ISR(PCINT_vect){ // PCINT
PORTD|=(1<<PORTD4);
_delay_ms(1000);
}


The project for Win AVR , attiny2313 PORTD4 - the LED stands on the anode (plus) and blinks when the button on the POTRD2 closes to ground.

To use another MK, see the corresponding datasheet.

The article Dmitry helped me myself.

Source: https://habr.com/ru/post/131908/


All Articles