PIN Change Interrupt Code klappt nicht

OP #4672491
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)
    {


    }
}
Gast
Huber M. schrieb:
> GIFR|= (1<<PCIF0);

GIFR ist ein Flag-Register, da gibt es nichts zum Einstellen,
nur die IRQ Flags werden hier gelöscht und/oder abgefragt.

Was du einstellen willst/sollst ist das GIMSK (INT0) und das
MCUCR (Interrupt Sense Control Bits).
OP
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)
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
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
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)
    {


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

Eine eigene Frage? Dieser Thread ist über 10 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.