Externí přerušení
Seznámení s možností externího přerušení
Řešené příklady:
• Vytvořte funkci tzv. Cykloblikače, po stisku tlačítka změnit blikající sekvenci.
Zadání:
Při stisku tlačítka 0 změňte sekvenci blikání 8 LED. Využijte externí přerušeni 0 (EXT0) .
Nápověda:
Přerušení obecně
Přerušení je nástroj , který nám
přeruší běh programu a skočí do části
zvané obsluha přerušení (ISR - Interrupt Service
Routine). Po vykonání
části programu v obsluze přerušení se opět běh
programu vrátí na místo,
kde byl program přerušen. Existuje několik druhů
přerušení, které
závisí na událostech, které jej vyvolali,
jsou to:
- přerušení vyvolané vnitřními obvody procesoru (Timer - viz další hodina)
- přerušení vyvolané periferními obvody procesoru - UART, AD převodník, SPI, atd.
- přerušení vyvolané vnějším prostředím - externí přerušení - změna napěťové úrovně na speciálních pinech procesoru
Přerušení se využívají k efektivním reakcím na danou situaci.
Inicializace externiho přerušení pro EXT0
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
EICRA=0x02;
EICRB=0x00;
EIMSK=0x01;
EIFR=0x01;
Obsluha přerušení a vektor přerušení pro EXT0
ISR(INT0_vect) // obsluha preruseni
{
prerus1=1;
}
povolení přerušení
// Global enable interrupts
sei();
Definice proměné pro použití v "obsluze přerušení"
volatile unsigned char prerus1;
//Pokud je nějaká proměnná označena slovem volatile,
//nebude kompilátor žádným způsobem optimalizovat její užití.
Řešení :
#define F_CPU 16000000UL
#include <avr/io.h>
#include <string.h>
#include <util/delay.h>
#include <avr/interrupt.h>
//*******************************************************************************************
// MOJE UPRAVY
//-------------------------------------------------------------------------------------------
//
#define setb(port,pin) port |= 1<<pin //nastav bit
#define clrb(port,pin) port &= ~(1<<pin) //nuluj bit
#define negb(port,pin) port ^= 1<<pin //neguj bit
//***********************************************************************************
int i;
int x;
int y;
int stav;
volatile unsigned char prerus1=0; //Pokud je nějaká proměnná označena slovem volatile,
// nebude kompilátor žádným způsobem optimalizovat
její užití.
ISR(INT0_vect) // obsluha preruseni
{
prerus1=1;
}
int main(void)
{
DDRB=0xFF; // vystupní - Ledky
DDRD=0x00; // vstupní - Tlacitka
// External Interrupt(s) initialization
// INT0: On
// INT0 Mode: Falling Edge
EICRA=0x02;
EICRB=0x00;
EIMSK=0x01;
EIFR=0x01;
// Global enable interrupts
sei();
PORTB=0;
_delay_ms(1000);
PORTB=255;
_delay_ms(1000);
PORTB=0;
_delay_ms(1000);
PORTB=255;
_delay_ms(1000);
stav=0;
while (1)
{
if (prerus1==1)
{
stav=stav+1;
if (stav>5) stav=1;
prerus1=0;
}
if (stav==0)
{
negb(PORTB,0);
_delay_ms(100);
}
if (stav==1)
{
PORTB=0;
}
if (stav==2)
{
PORTB=255;
for (i=0;i<=7;i++)
{
negb(PORTB,i);
_delay_ms(100);
negb(PORTB,i);
}
}
if (stav==3)
{
PORTB=255;
for (i=7;i>=0;i--)
{
negb(PORTB,i);
_delay_ms(100);
negb(PORTB,i);
}
}
if (stav==4)
{
PORTB=255;
_delay_ms(200);
PORTB=0;
_delay_ms(200);
}
if (stav==5)
{
PORTB=255;
x=3;
y=4;
for (i=0;i<=3;i++)
{
negb(PORTB,x);
negb(PORTB,y);
_delay_ms(100);
negb(PORTB,x);
negb(PORTB,y);
y++;
x--;
}
x=0;
y=7;
for (i=0;i<=3;i++)
{
negb(PORTB,x);
negb(PORTB,y);
_delay_ms(100);
negb(PORTB,x);
negb(PORTB,y);
x++;
y--;
}
}
};
}