Forum: Mikrocontroller und Digitale Elektronik Interrupt mit ATmega328P an PCINT0


von A. S. (21addo12)


Lesenswert?

Hallo Leute,

Eigentlich Programmiere ich PIC. Nun aber liegt ein ATmega328P vor mir, 
auf diesen möchte ich den PCINT0 Interrupt laufen lassen. Er soll 
ausgelöst werden wenn der PIN auf HIGH steht. Ich habe nun viele 
möglichkleiten ausprobiert, aber er springt mir nur beim Initialisieren 
in den Interrupt! Nun wollte ich fragen ob jemand erkennen kann was ich 
da falsch gemacht habe.

Den Port habe ich folgendermaßen Initialisiert dazu dann auch noch 
Interrupt enabled
1
 DDRB |= 0x00;
2
3
 PCICR |= (1 << PCIE0);
4
 PCMSK0 |= (1 << PCINT0);

Damit rufe ich den Interrupt auf:
1
 ISR(PCINT0_vect)
2
 {
3
  PORTD |= (1 << PD4);
4
 }
5
6
7
void main (void)
8
{
9
 sei();
10
11
 while(1)
12
 {
13
  PORTD &= ~(1 << PD4);
14
 }
15
}

Bei diesem Beispiel soll eine LED so lang leuchten wie der Interrupt 
anliegt.

Habe ich da was falsch gemacht?

Ich danke für Hilfe!

Grüße, Arthur

von Qwertz (Gast)


Lesenswert?

>Habe ich da was falsch gemacht?

>Bei diesem Beispiel soll eine LED so lang leuchten wie der Interrupt
>anliegt.

Da liegt ein Verständnisproblem vor. Ein Interrupt ist kein "Zustand" 
sondern ein "Ereignis". Man kann demzufolge keine Bedingung 
programmieren die lautet: "solange der Interrupt anliegt".

Letztlich ist es sinnvoll in Ereignissen zu denken also z.B. 
"Pegelwechsel".

Schau Dir die Beschreibung im Datenblatt an. Da steht genau beschrieben, 
was der uC an Ereignissen erkennen kann und wie er darauf reagiert.

von Qwertz (Gast)


Lesenswert?

Noch was: Ein Interrupt wird nicht "aufgerufen" sondern durch ein 
äusseres Ereignis ausgelöst. Du kannst kontrollieren durch welche 
Ereignisse ein Interrupt ausgelöst wird. Aber Du löst ihn nie durch Dein 
Programm aus.

von Helfer (Gast)


Lesenswert?

> Er soll ausgelöst werden wenn der PIN auf HIGH steht.
> DDRB |= 0x00;

Also du hast PortB als Eingang, korrekt für PCINT. Aber damit ist der 
LOW Ruhepegel nicht sichergestellt, denn die Eingänge sind Tristate! Du 
brauchst ein angeschlossenes Gerät mit sauberen TTL Pegeln oder einen 
externe Pull down Widerstände an deinen PCINT Eingängen.

Anm.: Bei DDRB |= 0x00; die VerODERung kontrollieren, die ist sinnlos.

von A. S. (21addo12)


Lesenswert?

Ok! Sorry! Im eifer des schreibens/tippens und mit der tatsache das 
Freitag war g habe ich mich doch etwas unglücklich ausgedrückt!

Mir ist klar das ein Interrupt ein Ereignis ist und das man den nicht 
per Software auslösen kann.


Ich habe einen 2ten Controller der einen Port auf High zieht wenn er 
etwas empfängt!

@Qwertz:

Ich habe mich an das Datenblatt gehalten bin aber verwirrt da mein 
Controller  mehrere PCINTx Pins besitzt, ich aber in den Interrupt 
Vectoren nur PCINT0 - PCINT2 habe.

Daher meine Frage ob die Initialisierung passt oder ob ich da was 
übersehen habe!

@Helfer:
Danke für den Tipp! Werde das mal ändern und ausprobieren!

von MWS (Gast)


Lesenswert?

Arthur Samol schrieb:
> Er soll
> ausgelöst werden wenn der PIN auf HIGH steht.

Es gibt beim ATM328 noch Int0 und Int1, diese können als "level 
triggered" konfiguriert werden und lösen solange aus, wie Low Level 
anliegt (level triggered geht nur Low Level)

Arthur Samol schrieb:
> Ich habe mich an das Datenblatt gehalten bin aber verwirrt da mein
> Controller  mehrere PCINTx Pins besitzt, ich aber in den Interrupt
> Vectoren nur PCINT0 - PCINT2 habe.

Für eine Gruppe PCINT-Pins ist jeweils eine ISR zuständig, darin muss 
man dann selbst rausfinden, welcher Pin getriggert hat.

Arthur Samol schrieb:
> Mir ist klar das ein Interrupt ein Ereignis ist und das man den nicht
> per Software auslösen kann.

Könnte man. Es ist erlaubt einen ext. Int zu definieren, auf diesen 
Portpin zu schreiben und damit den Int auszulösen.

Die Initialisierung lt. obigen Code ist ok, aber dennoch wird da nix 
leuchten, im Falle eines Flankenwechsels wird PD4 gesetzt und in der 
main sofort wieder gelöscht.

Um das gewünschte Verhalten über PCINT zu erreichen, müsste in der ISR 
PD4 bei steigender Flanke gesetzt und bei fallender Flanke gelöscht 
werden. Ob die Flanke steigend oder fallend war, lässt sich am Zustand 
von PB0 ablesen.

von A. S. (21addo12)


Lesenswert?

Hallo,

Um den Thread sauber abzuschliessen.

Ich habe den Fehler gefunden lag nicht an obiger Initilisierung, diese 
hat gestimmt!

Der andere Controller hat gesponnen!

Danke an alle die mir geantwortet haben!

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.