Forum: Mikrocontroller und Digitale Elektronik ATMega88 und INT0


von Ben H. (holltsb)


Lesenswert?

Hallo
habe folgendes Problem. Benutze einen Atmega 88 und möchte gerne an INT0
einen Taster betreiben.( Soll später für aufwecken benutz werden).

Momentan habe ich nur den Code geschrieben, um den INT 0 Anschluß
zu initialisieren.
Folgendes passiert:
Es wird nach einschalten der Versorgungsspannung bzw. nach einem Reset
direkt ein Int0 ausgelöst.
Was mache ich nur falsch?

Habe schon alles mögliche probiert.
z.B. Setzen von EIFR vor aktivierung von EIMSK. Hat nichts bewirkt.
Taster an PB0, Led an PC4 gegen vcc geschaltet

int main(void)
{     DDRB = 0b11111100;
      PORTB |= (1<<P2) |1<<P1);   // Pullups

      sbi(PORTC,4);
      EIFR = 0b00000011;
      EIMSK = 0b000000001;
      sei();
}
SIGNAL(SIG_INTERRUPT0)
  // signal handler for external interrupt int0
{
  cbi(PORTC,4);
  delay_ms(100);
  sbi(PORTC,4);
}


Bin für jede Hilfe dankbar
Gruß

Ben

von gast (Gast)


Lesenswert?

Hast du eigentlich irgendwo noch eine Endlosschleife eingebaut?

von Johannes M. (johnny-m)


Lesenswert?

Ben Holländer wrote:
> int main(void)
> {     DDRB = 0b11111100;
>       PORTB |= (1<<P2) |1<<P1);   // Pullups
Wer oder was sind P1 und P2?

>       sbi(PORTC,4);
Die sbi- und cbi-Makros sind afair veraltet.

>       EIFR = 0b00000011;
>       EIMSK = 0b000000001;
Zähle bitte mal die Nullen und Einsen...

Und dann gewöhne Dir die Schreibweise mit den Bitnamen an, die im 
Artikel Bitmanipulation beschrieben ist. Dann muss auch nicht jeder 
erst im Datenblatt nachsehen, was Du da alles gesetzt hast.

> SIGNAL(SIG_INTERRUPT0)
SIGNAL ist ebenfalls veraltet. Schau bitte im AVR-GCC-Tutorial nach, 
wie es geht!

von Ben H. (holltsb)


Lesenswert?

Hallo
vielen Dank für die Tips.
Habe das hanze mal überarbeitet:

Funktioniert immer noch nicht. Taster an PB0, Led an PC4 gegen vcc

int main(void)
{
  DDRC |= (1<<PC4);
  DDRB &= ~(1<<PB0);   // Eingang

  PORTB |= (1<<PB0);  // Pull up
  PORTC |= (1<<PC4);
  EICRA &= ~(1<<ISC01);
  EICRA &= ~(1<<ISC00);
  EIMSK |= (1<<INT0);
  sei();
  while(1);
}

ISR(INT0_vect)
  // signal handler for external interrupt int0
{
  PORTC &= ~(1<<PC4);
  delay_ms(100);
  PORTC |= (1<<PC4);

}


Bin für jede Hilfe dankbar

von Juergen (Gast)


Lesenswert?

> ISR(INT0_vect)
> {
>   ...
>   delay_ms(100);
>   ...
> }

100ms im Interrupt zu verwarten ist auch nicht die vornehme Art ...

von Ben H. (holltsb)


Lesenswert?

Hallo
die Zeitverzögerung dient ja nur zum Test dazu
das man ein led blinken war nimmt.
Gruß

Ben

von Stefan E. (sternst)


Lesenswert?

> Taster an PB0, ...

Das ist aber nicht der INT0-Pin. Das ist PD2.

von Peter D. (peda)


Lesenswert?

Ben Holländer wrote:
> habe folgendes Problem. Benutze einen Atmega 88 und möchte gerne an INT0
> einen Taster betreiben.( Soll später für aufwecken benutz werden).

Fürs Aufwecken eignet sich besser der Pin-Change-Interrupt.
Fürs Entprellen eignet sich besser ein Timerinterrupt.
Also macht man Aufwecken und Entprellen besser separat.


Peter

von Michael A. (micha54)


Lesenswert?

Hallo,

steht nichgt bereits alles da ? Die ansteigende Flanke soll eine INT0 
generieren. Schalte den Pullup ein und Du hast eine ansteigende Flanke.

Nachtrag: Schreib ein INTF0 nach EICRA, das löscht das Interruptflag.
EICRA |= (1<<INTF0);

Weiterhin macht der Pullup keine Sinn, wenn Du auf eine ansteigende 
Flanke wartest.


Gruß,
Michael

von Ben H. (holltsb)


Lesenswert?

Hallo
@ Stefan Ernst
Tausend Dank.
Natürlich wars das. INT0 und PCINT0 vertauscht.
So ein Mist. Layout kann ich jetzt erstmal neu zeichnen.

Super Forum hier.

Nochmals Vielen Dank für die Hilfe.

Gruß
Ben

von Johannes M. (johnny-m)


Lesenswert?

Michael Appelt wrote:
> Nachtrag: Schreib ein INTF0 nach EICRA, das löscht das Interruptflag.
> EICRA |= (1<<INTF0);
Nö. In EICRA stehen keine Interrupt-Flags! Das hat er in seiner 
ursprünglichen Version schon richtig gemacht mit EIFR.

> Weiterhin macht der Pullup keine Sinn, wenn Du auf eine ansteigende
> Flanke wartest.
Ein Pull-Up hat nichts damit zu tun, was für eine Flanke man haben will, 
sondern nur damit, wie der Taster angeschlossen ist. Wenn der Taster 
gegen Gnd angeschlossen ist, dann internen Pull-Up aktivieren, wenn er 
gegen VCC angeschlossen ist (was bei AVRs i.d.R. unsinnig und damit 
unüblich ist), dann externen Pull-Down anschließen.

Im ersten Fall gilt Taster gedrückt -> fallende Flanke, Taster 
losgelassen -> steigende Flanke.

Ben Holländer wrote:
>   EICRA &= ~(1<<ISC01);
>   EICRA &= ~(1<<ISC00);
Damit konfigurierst Du den Interrupt auf Low-Level-sensitiv. Das ist 
vermutlich nicht das, was Du willst...

von Peter D. (peda)


Lesenswert?

Ben Holländer wrote:
> Natürlich wars das. INT0 und PCINT0 vertauscht.
> So ein Mist. Layout kann ich jetzt erstmal neu zeichnen.

Ich wüßte nicht warum.
PCINT0 ist doch ideal zum Aufwecken.


Peter

von Michael A. (micha54)


Lesenswert?

Johannes M. wrote:
> Nö. In EICRA stehen keine Interrupt-Flags! Das hat er in seiner
> ursprünglichen Version schon richtig gemacht mit EIFR.

Ja, mein Fehler.

>> Weiterhin macht der Pullup keine Sinn, wenn Du auf eine ansteigende
>> Flanke wartest.
> Ein Pull-Up hat nichts damit zu tun, was für eine Flanke man haben will,
> sondern nur damit, wie der Taster angeschlossen ist. Wenn der Taster

Ein Pullup triggert bereits ohne Taster eine ansteigende Flanke.

> Im ersten Fall gilt Taster gedrückt -> fallende Flanke, Taster
> losgelassen -> steigende Flanke.

Taster gedrückt = 3 fallende und 2 steigende Flanken, Taster losgelassen 
dito insertiert. Taster prellen sowieso, da ist die Richtung der FLanken 
wurst.

Aber das Problem war ja bereits gelöst...

Gruß,
Michael

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.