Forum: Mikrocontroller und Digitale Elektronik External Interrupt an Atmega328P


von Felix (Gast)


Lesenswert?

Hallo liebe Mikrocontroller Gemeinde,

ich verzweifle grade bei dem Versuch, einen externen Interrupt am 
Atmega328p zu nutzen und brauche eure Hilfe. Im Ganzen geht es um eine 
Drehzahlerfassung.

1. Am Atmega328p an PC5 (PCINT13) habe ich das Ausgangssignal eines 
Hallsensors. Dieses liefert stets 5 V und fällt ab und zu mal auf 0 V. 
Dies sehe ich mit dem Oszilloskop.

2. Im C-Programm habe ich die
1
<avr/interrupt.h>
 eingebunden.

3. Als erstes setzte ich Pin 5 an Port C auf Eingang. (
1
DDRC = 0x0F;
)

4. Dann rufe ich die Funktion sei() auf um Interrupts zu zulassen.

5. Mit
1
EICRA = EICRA | 0b00001000;
 wähle ich die fallende Flanke als Auslöser für INT1.

6. Mit
1
EIMSK = EIMSK | 0b00000010;
 aktiviere ich INT1.

7. Mit
1
PCICR = PCICR | 0b00000010;
 erlaube ich Pin Change Interrupt 1.

8. Mit
1
PCMSK1 = PCMSK1 | 0b00100000;
 wähle ich PCINT13 als Signalquelle.

9. Über der Mainfunktion habe ich die ISR implementiert:
1
ISR(INT1_vect)      
2
{
3
  [...]
4
}



Mein Problem ist nun, dass, wenn ich die Flanke an PCINT13 fallen lasse, 
die ISR nicht ausgeführt wird.

Kann mir jemand helfen? Vielleicht habe ich etwas wichtiges übersehen? 
In den Tutorials wird immer von den Registern MCUCR und GICR 
geschrieben. Diese kommen in meinem Datenblatt unter "external 
Interrupts" aber nicht vor. Stattdessen werden die o.g. erwähnt, die ich 
nun entsprechend gesetzt habe.

Ich freue mich auf eure Rückmeldungen und bedanke mich schonmal 
herzlich.

Felix

: Verschoben durch Moderator
von Felix (Gast)


Lesenswert?

Ups, falsches Forum... kann das jemand bitte nach µC & Elektronik 
verschieben? Danke ;)

von m.n. (Gast)


Lesenswert?

Felix schrieb:
> aktiviere ich INT1.

> 8. MitPCMSK1 = PCMSK1 | 0b00100000; wähle ich PCINT13 als Signalquelle.

Du solltest Dich schon für einen Interrupt entscheiden.

von Felix (Gast)


Lesenswert?

Hallo :)

m.n. schrieb:
> Du solltest Dich schon für einen Interrupt entscheiden.

Soweit ich das Datenblatt verstehe, gibt es nur INT0, 1 und 2. Wobei 
PCINT14 bis PCINT 8 dem INT1 zugeordnet werden. PCINT13 dient somit als 
Auslöser für INT1.

von Felix (Gast)


Lesenswert?

Hi Leute,

habe den Fehler gefunden. Der Interruptvector ist nicht INT1_vect sonder 
PCINT1_vect.

Die ISR wird nun ausgeführt. Allerdings nicht nur bei fallender sondern 
auch bei steigender Flanke...?

von m.n. (Gast)


Lesenswert?

Felix schrieb:
> Die ISR wird nun ausgeführt. Allerdings nicht nur bei fallender sondern
> auch bei steigender Flanke...?

Das ist ja auch typisch für PCINT0 - PCINT23.
Einstellbare Flanken gibt es nur bei INT0 und INT1. Die dazugehörigen 
Eingänge sind PD2 und PD3.

von Bernd B. (bbrand)


Lesenswert?

Gibt es eigentlich einen besonderen Grund, dass dafür ein externer 
Interrupt verwendet und auf eine bestimmte Flanke getriggert werden 
muss?

Für eine einfache Drehzahlmessung würde mir ansonsten die Verwendung 
einer der Timer/Counter des 328P und Zuführung des Signals über Eingang 
T0 oder T1 geeigneter erscheinen.

Gruß,
Bernd

von Felix (Gast)


Lesenswert?

m.n. schrieb:
> Das ist ja auch typisch für PCINT0 - PCINT23.

Ok, das wusste ich nicht. Hatte da nicht zwischen INT1 und PCINT1 
unterschieden... Dann kann ich mir wohl die Konfiguration von EICRA 
sparen.


Bernd B. schrieb:
> Gibt es eigentlich einen besonderen Grund, dass dafür ein externer
> Interrupt verwendet und auf eine bestimmte Flanke getriggert werden
> muss?

Habe da noch keine Erfahrung. Ich wollte einfach mal einen externen 
Interrupt nutzen und die verstrichene Zeit über den Timer messen. Das 
Signal direkt an den Timer zu führen wäre sicher eleganter. Da hast du 
recht. Beim nächsten mal ;)

von m.n. (Gast)


Lesenswert?

Bernd B. schrieb:
> Für eine einfache Drehzahlmessung würde mir ansonsten die Verwendung
> einer der Timer/Counter des 328P und Zuführung des Signals über Eingang
> T0 oder T1 geeigneter erscheinen.

Egal wie, aber so bitte nicht!

Die beste Lösung ist die Verwendung des Input-Capture von Timer 1 bei 
ATmegaxxx: beste Auflösung und höchste Meßrate.

Ext. INT0/INT1 oder PCINTxx wäre der nächste Ansatz und auch für hohe 
Drehzahlen noch gut geeignet.

Zuletzt gibt es noch die Möglichkeit, einen beliebigen Eingang im 0,1 - 
1 ms Raster abzufragen (polling) und die aktive Flanke per Software 
auszufiltern. Kann man machen, wenn man sich vor Interrupts scheut 
und/oder nicht in der Lage ist, Eingangssignale hinreichend 
aufzubereiten (prellende Kontakte).

von Thomas E. (thomase)


Lesenswert?

Felix schrieb:
> Dann kann ich mir wohl die Konfiguration von EICRA
> sparen.

Nein, du kannst dir grundsätzlich die Konfiguration des Pinchange 
sparen. Denn beim Intx kannst du genau die Flanke einstellen, die du 
haben möchtest.

Felix schrieb:
> Habe da noch keine Erfahrung. Ich wollte einfach mal einen externen
> Interrupt nutzen und die verstrichene Zeit über den Timer messen. Das
> Signal direkt an den Timer zu führen wäre sicher eleganter. Da hast du
> recht. Beim nächsten mal ;)

Dann mache es nicht beim nächsten Mal, sondern gleich. Schließe deinen 
Drehzahlgeber am ICP des Timer1 an. Die Auswertung ist einfacher und 
genauer als das Gehampel mit dem Interrupt.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.