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í 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--;
            }   
   
    }

     };
}