Hallo Leute,
ich steh hier leider vor einem Problem.
ISR (INT0_vect)
{
setLedMode(15,true);
}
Ich wollte eigentlich das bei einem Interrupt eine Led immer
eingeschaltet wird.
Mein Problem ist gerade, dass der Interrupt immer ausgelöst wird, sobald
mein µC geflasht worden ist mit meinem neuen Programm.
Es liegt immer 5 V an und bei einem Interrupt fällt die Flanke auf 0 V.
(ich denke daran liegt der fehler).
Hier ist die Doku für die Lichtschranke:
http://www.produktinfo.conrad.com/datenblaetter/125000-149999/140268-da-01-en-IR_SENSOR_APDS_9102_L22.pdf
und es handelt sich um ein ATMEGA88.
Danke im Vorraus!
Tuji de Assis Moreira schrieb:> // Port D auf Ausgang setzen> DDRD = 0xff;> // Lichtschranke PD2 auf Eingang> DDRD = DDRD & ~(1<<PD2);
Diese Initialisierung produziert einen kurzen Low-Impuls auf PD2 und
triggert damit den INT0!
Wieso den Port D nicht gleich richtig initalisieren?
Unabhängig von dem ISR-Problem: Mach mal Deine Schaltung heil!
AVCC muß an VCC angeschlossen werden (und mit 100nF gegen GND
geblockt), auch dann, wenn der A/D-Wandler nicht benutzt wird.
Der Pin versorgt nämlich nicht nur den A/D-Wandler,
sondern auch PORT C (PC0..PC3).
(siehe Datenblatt, Seite 6)
Matthias Sch. schrieb:> Es ist auch eine gute Idee, vor der Freigabe des Interruptes> etwaige> anstehende Anforderungen zu löschen:EIFR = (1<<INTF0);
Habe es versucht und trotzdem, funktioniert es nicht.
Tuji de Assis Moreira schrieb:> Hat niemand eine Ahnung ?> oder überhaupt, an was es liegen könnte, warum der interrupt immer> ausgelöst wird?
Weil die Erkennungslogik nicht riechen kann, ob die Bedingung zur
Registreierung eines Interrupts jetzt deswegen eingetreten ist, weil
sich am Eingang tatsächlich eine Flanke ereignet hat, oder ob diese
Flanke 'pseudo-mässig' dadurch enstanden ist, dass du die
Auswertebedingungen während der Intialisierungsphase des Programms
geändert hast.
Nachdem alles fertig konfiguriert ist, lösche eventuell aufgelaufene
'falsche und unerwünschte' Interrupt Anforderungen ehe du mit sei()
alles für den tatsächlichen Betrieb freigibst und gut ists.
Das ist weder anrüchig noch schlechte Praxis.
Hinweis: derartige Interrupt-Registrierungsflags werden durch
Einschreiben eines 1-Bits an der entsprechenden Bitposition ins
entsprechende Register gelöscht.
Karl Heinz schrieb:> Weil die Erkennungslogik nicht riechen kann, ob die Bedingung zur> Registreierung eines Interrupts jetzt deswegen eingetreten ist, weil> sich am Eingang tatsächlich eine Flanke ereignet hat, oder ob diese> Flanke 'pseudo-mässig' dadurch enstanden ist, dass du die> Auswertebedingungen während der Intialisierungsphase des Programms> geändert hast.
Ich hab versucht es zurückzusetzen.
Iwie funktioniert es aber nicht, vllt habe ich es nur falsch gemacht:
GIFR = (1<<INF1);
EIFR = (1<<INTF0);
Habe ich das was falsches gemacht?
Wie heißt den der Code zum zurück setzen?
Stefan P. schrieb:> Was macht denn setLedMode(15,true); ?
Ich hab auf meiner Platine 16 LED´s.
Wenn diese methode aufgerufen wird, wird die LED eingeschalten.
Das Problem bei der ganzen Sache ist, dass der immer anbleibt(ist ja
auch richtig).
Aber wenn ich in meiner Main dann sage, schalte die LED wieder aus,
leuchtet die LED auf und wieder zu, die ganze zeit.
Darum denke ich, dass diese ISR(INT0_vect) immer wieder aufgerufen wird,
obwohl kein externer Interrupt geschieht.
spess53 schrieb:> Wo hat der ATMEga88 ein GIF-Register?>> MfG Spess
Muss ehrlich zugeben, dass ich noch ein newbie bin.
Ich kenne mich halt nicht perfekt aus, suche mir gerade alles ausm
Internet zusammen.
Versuche aber auf über den µController zu lernen.
Aber es tut sich einfach nicht.
Tuji de Assis Moreira schrieb:> Darum denke ich, dass diese ISR(INT0_vect) immer wieder aufgerufen wird,> obwohl kein externer Interrupt geschieht.
Zeig doch mal dein ganzes Programm.
Immer diese Ratespielchen von wegen: ich denke, das das und das
passiert.
Unabhängig davon: wenn man den Verdacht hat, dass eine bestimmte
Komponente ein Problem verursacht, dann ist es auch kein Beinbruch sich
erst mal ein Testprogramm zu machen, welches nur und ausschliesslich
diese Komponente testet.
In deinem Fall willst du wissen, ob der externe Interrupt korrekt
funktioniert. Dazu braucht es keinen Timer oder sonstiges Zeugs. Einfach
nur dir Lichtschranke und die LED um das Ansprechen der Lichtschranke
anzuzeigen. Mehr braucht es dazu nicht. Dann läuft man auch nicht
Gefahr, dass man sich mit all den anderen Zusatzteilen im Programm
irgendwo einen Bock geschossen hat, den man selbst nicht mehr findet.
Bei der Fehlersuche bzw. wenn man erst mal ratlos ist, ist die
Konzentration aufs Wesentliche der erste wichtige Punkt. Alles was
nichts mit diesem Wesentlichen zu tun hat, fliegt erst mal raus.
Tuji de Assis Moreira schrieb:> Kann es vielleicht sein, dass ich diese Register setzen muss:>> GICR|=0x40;> MCUCR=0x02;>> Ich bin mir halt nicht sicher.
Das weiß ich nicht, weil ich eine Abneigung dagegen habe, einzelne BIts
(die eine Bedeutung haben, die sich in ihrem Namen wiederspiegelt) per
Hex-Zahl zu setzen.
Die Bits haben Namen. Atmel hat dir diese Namen zur Verfügung gestellt.
Benutzte sie auch!
Immer dieses Hex-Zahl mit dem Datenblatt auseinanderpfriemeln. Da
scrollt man sich doch regelmässig einen Tennisarm beim Nachverfolgen im
PDF.
Tuji de Assis Moreira schrieb:> Darum denke ich, dass diese ISR(INT0_vect) immer wieder aufgerufen wird,> obwohl kein externer Interrupt geschieht.
IN deinem Eröffnungsposting klingt das alles aber nocht ganz anders
> Mein Problem ist gerade, dass der Interrupt immer ausgelöst wird,> sobald mein µC geflasht worden ist mit meinem neuen Programm.
da ist vom Einspielen eines neuen Programms die Rede.
Was denn nun?
Tuji de Assis Moreira schrieb:> Am besten wäre es wenn sie das komplette Projekt mit Atmel Studio> öffnen.
Nö. Sorry. Aber das tu ich mir nicht an.
Entweder du reduzierst dein Programm auf einen einfachen Fall
* lichtschranke + 1 LED
oder du musst dir den Fehler selbst suchen
Tuji de Assis Moreira schrieb:> Das ist immer noch das alte Programm. Mit kleinen Veränderungen die mir> hier vorgeschlagen worden ist.
Ja. Aber ich analysiere jetzt nicht 30 Minuten lang, was da im Programm
alles abgeht und welche Querverflechtungen für welchen Effekt
verantwortlich sein könnten, wenn ein simples
1
#include<avr/io.>
2
#include<util/delay.h>
3
4
intmain()
5
{
6
DDRC=0xFF;
7
8
EIMSK|=_BV(INT0);// PD2 = INT0 enablen
9
EICRA|=_BV(ISC01);// Triggern auf fallende Flanke des INT0
10
PORTD|=_BV(PD2);
11
12
while(1){
13
PORTC|=_BV(PC0);
14
_delay_ms(1000);
15
}
16
}
17
18
ISR(INT0_vect)
19
{
20
PORTC&=~_BV(PC0);
21
}
... auch ausreichend ist, um die Funktion des externen Interrupts für
sich alleine zu testen.
Und bei sowas
1
ISR(INT0_vect)
2
{
3
turnOffLeds();
4
_delay_ms(5000);
5
....
fangen bei mir sowieso alle Alarmglocken zu klingeln an.
Karl Heinz schrieb:> Nö. Sorry. Aber das tu ich mir nicht an.>> Entweder du reduzierst dein Programm auf einen einfachen Fall> * lichtschranke + 1 LED> oder du musst dir den Fehler selbst suchen
Hi
>Kann es vielleicht sein, dass ich diese Register setzen muss:>GICR|=0x40;>MCUCR=0x02;>Ich bin mir halt nicht sicher.
Welchen Controller setzt du nun wirklich ein?
MCUCR/GICR/GIFR gehören zum ATMega8. Beim ATMega88 heißen die
richtigen Register EICRA, EIMSK und EIFR.
Könnte es sein, das du dein Programm für einen ATMega8 compilierst?
MfG Spess
schon besser.
Aber da fehlt die obligate Hauptschleife.
Ohne Hauptschleife läuft das Programm aus main() raus zurück in die
C-Runtime. Und die hat als erstes nichts besseres zu tun, als alle
Interrupts mittels eines cli() abzuschalten.
Daher braucht JEDES Programm eine Hauptschleife. Selbst wenn die leer
ist. Du willst das Programm aus main() nie wieder rauslassen.