mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Problem mit INT0 am ATmega16


Autor: Rush (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich will über einen Fototransistor einen Blitz detektieren. Zum Testen 
halte ich das gute stück einfach zu oder leuchte mit einer 
Tisch-Halogenleuchte drauf.
Wenn ich den Transistor zuhalte liegen an INT0 0,8 Volt an, bei 
beleuchtetem Zustand 4,8 Volt.
Interrupt ist aktiviert und auf steigende Flanke gestellt, laut 
Datenblatt.
Aber anscheinend fehtl was weil kein Interrupt ausgelöst wird

Ich habe zwar schon im Forum gesucht, auch was gefunden, aber das war 
nicht unbedingt anders als das was ich bis jetzt geproggt habe, mit dem 
Unterschied dass es bei den anderen läuft ;-)
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>

void init(void)
{
  DDRB |= (1<<PB4);
  PORTB |= (1<<PB4);
  MCUCR |= (1<<ISC01) | (1<<ISC00);
  GICR |= (1<<INT0);
  sei();
}

ISR(INT0_vect)
{
  cli();
  PORTB &= ~(1<<PB4);  //LED an
  _delay_ms(3000);
  sei();
}


void main(void)
{
init();


  while (1)
    {
    PORTB |= (1<<PB4);  //LED aus
    }
}
  

Hab ich noch irgendwas vergessen ?

Autor: Rush (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry... hatte den falschen code gepostet, hier ist der richtige
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>


ISR(INT0_vect)
{
  cli();
  PORTD &= ~(1<<PD4);
  _delay_ms(3000);
  sei();
}


void init(void)
{
  DDRD |= (1<<PD4);
  PORTD |= (1<<PD4);
  PORTD &=~ (1<<PD2);
  MCUCR |= (1<<ISC01) | (1<<ISC00);
  GICR |= (1<<INT0);
  sei();
}




void main(void)
{
init();


  while (1)
    {
    PORTD |= (1<<PD4);
    }
}
  
wenn ich den Fototransistor jetzt kurzzeitig  beleuchte und gleich 
wieder abdunkle geht die LED zwar an, bleibt aber anstatt von 3 sekunden 
ca 7 sekunden an, wieso?

Autor: hans (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wo wird F_CPU gesetzt? Hat Delay eine Kristallkugel?

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

delay.h braucht noch den Systemtakt (#define F_CPU 8000000)
In einer ISR brauchst du den Interrupt nicht zusätzlich disablen...das 
macht der compiler für dich.

Deswegen ist auch das Delay in der ISR noch schlimmer als es ohnehin 
schon ist. Andere ISR werden in diesen 3Sekunden einfach nicht 
aufgerufen.
Setz doch lieber in der ISR nur ein flag was  du ausserhalb der ISR 
auswertest.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralf wrote:
> delay.h braucht noch den Systemtakt (#define F_CPU 8000000)
> In einer ISR brauchst du den Interrupt nicht zusätzlich disablen...das
> macht der compiler für dich.
Falsch, das macht die Hardware. Der Compiler hat damit nichts zu tun. 
Ein sei() in einem Interrupt-Handler (auch am Ende) kann sogar Probleme 
verursachen. Schließlich ist die unscheinbare schließende Klammer am 
Ende der ISR in Wirklichkeit viel mehr als nur eine einfache Klammer...

> Deswegen ist auch das Delay in der ISR noch schlimmer als es ohnehin
> schon ist.
Ohne das sei() am Ende wäre es gar nicht so tragisch, da in diesem 
Falle nur ein einziger Interrupt aktiv ist. Durch das Prellen des 
Tasters wird aber vermutlich das Interrupt-Flag während des Delays schon 
wieder gesetzt und noch bevor der Controller am Ende der ISR die 
Register zurückschreiben und aus dem Handler rausspringen kann, wird der 
Interrupt erneut auseglöst (eben durch das sei()). Das kann durchaus 
knallen...

> Andere ISR werden in diesen 3Sekunden einfach nicht
> aufgerufen.
Andere gibt es in diesem Falle auch nicht.

> Setz doch lieber in der ISR nur ein flag was  du ausserhalb der ISR
> auswertest.
Das sollte man generell machen, auch wenn es in diesem Fall sogar so 
gehen müsste.

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

beachte auch dass eine Spannung von 0,8V im Dunkelzustand ziemlich hoch 
ist, da die Input Low Voltage vom ATMega16 maximal 0.2 x VCC beträgt.

D.h. bei 5V VCC ist die Input Low Voltage 1V.

Grüße

Autor: Ralf (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...welcher Taster?

Autor: Rush (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, Frequenz von 16 Mhz ist im Compiler definiert.
Und Taster habe ich nicht.
Meine ISR funzt mittlerweile.
Habe an den Ausgang jetzt ein externes Blitzgerät drangehängt und mit 
der digikam einfach mal ein foto gemacht. Blöd ist nur dass das ganze 
nicht zuverlässig funzt da mal der Tochterblitz rechtzeitig gezündet 
wird und mal zu spät.

Habt ihr nen Plan wie  ich die Abarbeitung etwas beschleunigen kann?

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ralf wrote:
> ...welcher Taster?
Sorry, kommt davon, wenn man an mehreren Problemstellungen gleichzeitig 
arbeitet...

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weiß der AVR auch, dass er mit 16 MHz laufen soll? Thema [[AVR 
Fuses]]...

Autor: Rush (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jo Fuses habe ich auch gesetzt

Autor: Hannes Lux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Habt ihr nen Plan wie  ich die Abarbeitung etwas beschleunigen kann?

Analog... ;-)

Ich habe sowas vor 35 Jahren mit Gasentladungsröhren 
(Kaltkathoden-Thyratron Z5823) realisiert. War extrem einfach und 
zuverlässig. Ich nutzte das Überkopf-Zünden bei starker 
Lichteinstrahlung vom Init-Blitz und entlud per Thyratron 47nF (310V) 
über die Zündspule...

Mit Fotodiode, OPV und Kleinthyristor sollte das auch schnell genug 
funktionieren.

...

Autor: Rush (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hätte es eben gerne digital ;-) Analog hab ich auch schon dran 
gedacht aber mag ich nicht.

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rush wrote:
> Ich hätte es eben gerne digital ;-) Analog hab ich auch schon dran
> gedacht aber mag ich nicht.
Schon mal an den Mittelweg gedacht? Der ATMega16 hat auch einen 
eingebauten Analog-Komparator. Da bist Du selbst Herr der 
Schaltschwellen und die Wahrscheinlichkeit, dass es zuverlässig klappt, 
ist größer...

Autor: Rush (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe ich auch schon dran gedacht, nur ist der ADC meines wissen nach an 
sich, also bei der convertierung des Signals auch langsam.

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ADC != Analog-Komparator
Das sind zwei völlig unterschiedliche Dinge.

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Rush

> wenn ich den Fototransistor jetzt kurzzeitig  beleuchte und gleich
> wieder abdunkle geht die LED zwar an, bleibt aber anstatt von 3 sekunden
> ca 7 sekunden an, wieso?

Zwei INT0 hintereinander?

@ Ralf

> Deswegen ist auch das Delay in der ISR noch schlimmer als es ohnehin
> schon ist. Andere ISR werden in diesen 3Sekunden einfach nicht
> aufgerufen. Setz doch lieber in der ISR nur ein flag was du ausserhalb
> der ISR auswertest.

Sehe ich genauso. Als Flag kann man die LED selbst nehmen.

// MCU ist Atmega16
// F_CPU ist im Projekt/Makefile auf 16000000L definiert
#include <avr/io.h>
#include <util/delay.h>
#include <avr/interrupt.h>


ISR(INT0_vect)
{
  PORTD &= ~(1<<PD4); // active-low LED AN
}


void init(void)
{
  DDRD |= (1<<PD4);
  PORTD |= (1<<PD4); // active-low LED AUS
  PORTD &= ~(1<<PD2);
/*
Table 35. Interrupt 0 Sense Control
ISC01 ISC00 Description
  0     0   The low level of INT0 generates an interrupt request.
  0     1   Any logical change on INT0 generates an interrupt request.
  1     0   The falling edge of INT0 generates an interrupt request.
  1     1   The rising edge of INT0 generates an interrupt request.
*/
  MCUCR |= (1<<ISC01) | (1<<ISC00); // rising edge of INT0
  GICR |= (1<<INT0);
  sei();
}


void main(void)
{
  init();

  while (1)
  {
    if ( !(PORTD & (1<<PD4)) ) // Ist active-low LED AN?
    {
      // hier Code für Auslöser einfügen
      // ...
      _delay_ms(3000);   // 3s Leuchten LED
      PORTD |= (1<<PD4); // active-low LED AUS
    }
  }
}


Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.