PIN Change Interrupt Code klappt nicht

OP #4672491
Lesenswert?
• ▲
▼
Hallo,

ich würde gerne einen Pinchange Interrupt auslösen ( eine led soll 
leuchten und wieder aus) um besser zu verstehen was das genau ist. Habe 
folgenden Code dazu geschrieben, aber irgendwie bringe ich ihn nicht zum 
laufen. Was mache ich den hier falsch?

grüsse huber

ich benütze;

Attiny24a
Atmelstudio6.0 mit original Avr isp mk2

/*
 * Attiny24A_test.c
 *
 * Created: 05.08.2016 11:23:30
 *  Author: Huber
 */

#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>

ISR(PCINT1_vect)
{
  PORTA|= (1<<PA0);
  _delay_ms(1000);
  PORTA &= ~(1<<PA0);


}

int main(void)
{   //Ausgänge festlegen
  DDRA|= (1<<PA0);
  //Eingänge festlegen pullups
  PORTA|= (1<<PA1);

  //Interrupt Service Routine PCINT eintellen
  GIFR|= (1<<PCIF0);
  PCMSK0|= (1<<PCINT1);
  sei();

  while(1)
    {


    }
}
OP #4675426
Lesenswert?
• ▲
▼
Mahlzeit,

nein, ich wollte schon gezielt die PCINT nutzen. Um zu verstehen was ich 
mit denen anfangen kann. Oder für was man diese benützt. Denn vom lesen 
alleine verstehe ich es einfach nicht. Ich bräuchte irgend ein beispiel. 
Denn int0 das kann ich, das sind ja externe interrups. Wie gesagt die 
PCINT verstehe ich nicht.

danke huber
(Firma: Vescomp) #4675450
Lesenswert?
• ▲
▼
Huber M. schrieb:
> nein, ich wollte schon gezielt die PCINT nutzen.

 Dann must du die auch erlauben, dass versuchte dir Mitlesa in seinem
 Beitrag zu erklären.
1
  //Interrupt Service Routine PCINT einstellen
2
  PCMSK0 |= (1<<PCINT1);        //* PCINT auf PA.1 erlaubt
3
  GIMSK |= (1<<PCIE0);          //* PA.0 - PA.7 PCINT erlaubt
4
  sei();
 Und du darfst natürlich nicht mehr am PA.1 wackeln, denn selbst als
 Ausgang wird PA.1 einen Interrupt auslösen.
Gast #4675467
Lesenswert?
• ▲
▼
Nun, da hat mitlesa leider einen Fehler gemacht. Es handelt sich nicht 
um das Bit namens "INT0" sondern das Bit namens "PCIEO".

Das GIFR brauchst Du nicht zu setzen. Das dient dazu das Interrupt-Flag 
zurückzusetzen, falls der Interrupt mal aufgetreten ist. Das braucht man 
aber bis auf Ausnahmefälle nicht selbst zu tun, da es, wie im Datenblatt 
steht, selbsttätig zurückgesetzt wird, sobald die Interrupt-Routine 
angesprungen wird.

Aber das steht alles im Datenblatt.

Selbst wenn Du daraus nicht entnehmen kannst, wozu es gut ist, solltest 
Du aber die Funktionsweise erkennen können. In einer Bedienungsanleitung 
eines Autos steht ja auch nur, wie es zu bedienen ist, nicht was man 
damit machen kann oder soll.

Du solltest Du auch angewöhnen, genau zu beschreiben, was nicht 
funktioniert. Was geschieht und was stattdessen geschehen soll. Das 
hilft bei der Fehlersuche ungemein.

Und noch eins: Auch wenn es in Deinem Fall nur eine Rolle spielt, wenn 
Interrupts in kürzeren Abständen als 1s auftreten, solltest Du delays in 
Interrupt-Routinen vermeiden. In diesem Fall nur zu Übungszwecken, aber 
Du kannst ja mal die Interrupts in kurzen Abständen auslösen, dann 
siehst Du, das Du Probleme bekommst.
OP #4677662
Lesenswert?
• ▲
▼
Moing,

so sieht der abgeänderte Code jetzt aus. Und, wenn jetzt irgend eine 
Veränderung an PCINT1 mittels Taster auftritt, soll PA0, 1sec. lang 
leuchten, und danach wieder ausgehen. Es tut sich aber gar nichts. Und 
wenn ich das richtig übersetzt habe, dann löst jede Veränderung an PCINT 
7-0 ein interrupt aus oder?

-die LED ist Ordnungsgemäß an PA0 angeschlossen
-der Taster an PA1(schaltet PA1 gegen GND). Und war testweise auch an 
andere pins. Es müsste doch eigentlich funktionieren?







/*
 * Attiny24A_test.c
 *
 * Created: 05.08.2016 11:23:30
 *  Author: Huber
 */

#define F_CPU 1000000UL
#include <util/delay.h>
#include <avr/io.h>
#include <avr/interrupt.h>

ISR(PCINT1_vect)
{
  PORTA|= (1<<PA0);
  _delay_ms(1000);
  PORTA &= ~(1<<PA0);


}

int main(void)
{   //Ausgänge festlegen
  DDRA|= (1<<PA0);
  //Eingänge festlegen pullups
  PORTA|= (1<<PA1);

   //Interrupt Service Routine PCINT einstellen
  PCMSK0 |= (1<<PCINT1);        //* PCINT auf PA.1 erlaubt
  GIMSK |= (1<<PCIE0);          //* PA.0 - PA.7 PCINT erlaubt
  sei();

  while(1)
    {


    }
}
#4677724
Lesenswert?
• ▲
▼
Huber M. schrieb:
> Moing,
>
> so sieht der abgeänderte Code jetzt aus. Und, wenn jetzt irgend eine
> Veränderung an PCINT1 mittels Taster auftritt, soll PA0, 1sec. lang
> leuchten, und danach wieder ausgehen. Es tut sich aber gar nichts. Und
> wenn ich das richtig übersetzt habe, dann löst jede Veränderung an PCINT
> 7-0 ein interrupt aus oder?
nein,
Im PCMSKx Register legst du fest welche der zugeordneten 8 Pins einen 
INT auslösen kann. Im GIMSK wiederum musst du festlegen welche Gruppe 
von PCINTs einen INT auslösen dürfen. Die ISR gibts immer nur für jede 
Gruppe, deshalb muss die auch die Nummer aus dem entspechenden PCMSK 
haben.
Solange du aus einer 8'er Gruppe genau einen Pin freigibst verhält sich 
die ISR genau wie bei INT0 o. INT1. Gibst du mehrere frei musst du in 
der ISR erst noch herausfinden welcher Pin den INT ausgelöst hat.

Wenn du für PA1 also  PCINT1 in PCMSK*0* setzt, und PCIE*0* im GISMK 
setzt und dann den richtigen INT PCINT0_vect nimmst, dann sollte es 
auch funktionieren.

Sascha

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren