Forum: Mikrocontroller und Digitale Elektronik Problem mit INT0 am ATmega16


von Rush (Gast)


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 ;-)
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <avr/interrupt.h>
4
5
void init(void)
6
{
7
  DDRB |= (1<<PB4);
8
  PORTB |= (1<<PB4);
9
  MCUCR |= (1<<ISC01) | (1<<ISC00);
10
  GICR |= (1<<INT0);
11
  sei();
12
}
13
14
ISR(INT0_vect)
15
{
16
  cli();
17
  PORTB &= ~(1<<PB4);  //LED an
18
  _delay_ms(3000);
19
  sei();
20
}
21
22
23
void main(void)
24
{
25
init();
26
27
28
  while (1)
29
    {
30
    PORTB |= (1<<PB4);  //LED aus
31
    }
32
}

Hab ich noch irgendwas vergessen ?

von Rush (Gast)


Lesenswert?

Sorry... hatte den falschen code gepostet, hier ist der richtige
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <avr/interrupt.h>
4
5
6
ISR(INT0_vect)
7
{
8
  cli();
9
  PORTD &= ~(1<<PD4);
10
  _delay_ms(3000);
11
  sei();
12
}
13
14
15
void init(void)
16
{
17
  DDRD |= (1<<PD4);
18
  PORTD |= (1<<PD4);
19
  PORTD &=~ (1<<PD2);
20
  MCUCR |= (1<<ISC01) | (1<<ISC00);
21
  GICR |= (1<<INT0);
22
  sei();
23
}
24
25
26
27
28
void main(void)
29
{
30
init();
31
32
33
  while (1)
34
    {
35
    PORTD |= (1<<PD4);
36
    }
37
}
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?

von hans (Gast)


Lesenswert?

Wo wird F_CPU gesetzt? Hat Delay eine Kristallkugel?

von Ralf (Gast)


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.

von Johannes M. (johnny-m)


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.

von Tom (Gast)


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

von Ralf (Gast)


Lesenswert?

...welcher Taster?

von Rush (Gast)


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?

von Johannes M. (johnny-m)


Lesenswert?

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

von Johannes M. (johnny-m)


Lesenswert?

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

von Rush (Gast)


Lesenswert?

Jo Fuses habe ich auch gesetzt

von Hannes Lux (Gast)


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.

...

von Rush (Gast)


Lesenswert?

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

von Johannes M. (johnny-m)


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

von Rush (Gast)


Lesenswert?

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

von Stefan E. (sternst)


Lesenswert?

ADC != Analog-Komparator
Das sind zwei völlig unterschiedliche Dinge.

von Stefan B. (stefan) Benutzerseite


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.
1
// MCU ist Atmega16
2
// F_CPU ist im Projekt/Makefile auf 16000000L definiert
3
#include <avr/io.h>
4
#include <util/delay.h>
5
#include <avr/interrupt.h>
6
7
8
ISR(INT0_vect)
9
{
10
  PORTD &= ~(1<<PD4); // active-low LED AN
11
}
12
13
14
void init(void)
15
{
16
  DDRD |= (1<<PD4);
17
  PORTD |= (1<<PD4); // active-low LED AUS
18
  PORTD &= ~(1<<PD2);
19
/*
20
Table 35. Interrupt 0 Sense Control
21
ISC01 ISC00 Description
22
  0     0   The low level of INT0 generates an interrupt request.
23
  0     1   Any logical change on INT0 generates an interrupt request.
24
  1     0   The falling edge of INT0 generates an interrupt request.
25
  1     1   The rising edge of INT0 generates an interrupt request.
26
*/
27
  MCUCR |= (1<<ISC01) | (1<<ISC00); // rising edge of INT0
28
  GICR |= (1<<INT0);
29
  sei();
30
}
31
32
33
void main(void)
34
{
35
  init();
36
37
  while (1)
38
  {
39
    if ( !(PORTD & (1<<PD4)) ) // Ist active-low LED AN?
40
    {
41
      // hier Code für Auslöser einfügen
42
      // ...
43
      _delay_ms(3000);   // 3s Leuchten LED
44
      PORTD |= (1<<PD4); // active-low LED AUS
45
    }
46
  }
47
}

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.