Archiv verlassen und diese Seite im Standarddesign anzeigen : Ext. Interrupt löst nur unregelmässig aus
Hallo zusammen,
ich habe ein Lichtschranke, die am Int1 Eingang eines Mega16 hängt.
Solange nichts die Lichtschranke durchfährt, liegt eine 0 am Eingang an. Ist was dazwischen, gibts ne 1.
Ich hab den Interrupt so eingestellt, dass er bei einer L==>H Flanke auslösen soll. Also sobald etwas durch die Schranke rauscht. Hier die Initialisierung:
On Int1 Lichtschranke
Mcucr.2 = 1
Mcucr.3 = 1
Enable Interrupts
Enable Int1
Doch... Der Interrupt löst nur sehr unregelmässig aus... Eigentlich fast immer nur jedes zweite Mal, wenn etwas durch die Schranke geht. (Das 1 liegt an, aber es gibt keinen Interrupt)...
Ändere ich die Auslösecharakteristik des Interrupts auf "Change", also dass er triggern soll, sobald die Flanke wechselt, dann löst er jedes mal korrekt aus, einfach zwei mal, was ich vermeiden möchte... Die Hardware scheint mir in Ordnung, nur: wieso löst er nicht immer aus.. ?
Dasselbe Phänomen des "nicht immer auslösens" hab ich, wenn ich ihm sage, er soll von H zu L triggern... Funktioniert auch nicht immer... Komishce Sache.. Sobald er auf einen Flankenwechsel triggern soll, triggert er erfolgreich auf beide Flanken, und zwar immer.
Hab ich was vergessen?
Herzlichen Gruss
Mario
Hmm, vielleicht doch noch die Hardware der Lichtschranke.
Siehe Anhang. Hab halt das Case eines Optokopplers genommen, aber man wird wohl drauskommen...
Die Lichtschranke ist eine KTIR0621DS.
DB: http://www.datasheetcatalog.com/dat.....shtml
linux_80
05.01.2007, 23:42
Hallo,
bei der URL kommt nur "Not Found", weil die Punkte so mit drinstehen !
Kann es evtl. sein, das die Flanke nicht Steil genug ist, weiss jetzt nicht wie das genau zu sein hat, das der AVR das auch als solches erkennt :-k
Evtl. mal einen Schmitt-Trigger dazwischen bauen.
Nunja... bei Triggerung auf beide Flanken erwischt er diese immer..
Hier das Linktier:
http://www.datasheetcatalog.com/datasheets_pdf/K/T/I/R/KTIR0621DS.shtml
Versuchs doch mal nicht mit dem Interrupt, sondern mit dem Analog Komperator.
Sollte es Wirklich an der Flankensteilheit liegen, müsste es damit eigentlich funktionieren.
Es sei denn du brauchst den Komperator anderweitig...
Geht net... Chip schon verlötet (SMD) und auf der Unterseite der Platine, die bereits eingebaut ist...
Kommst Du noch an den Optokoppler ran ?
Eventuell kannst Du dem Teil ja noch einen Komperator oder Transistor nachschalten um die Flankensteilheit zu erhöhen ?
Oh, bei mir ists ne Lichtschranke, hab nur den Optokoppler als Symbol genommen.
Hab nochmals nachgeschauen - auch wenn er auf beide Flanken triggern soll, dann erwischt er die fallende fast nie...
Aber das ist doch doof... Erkennt der AVR nun die Flanke, oder ein Wechsel von 0/1 oder 1/0? Erkennt er am Interrupteingang langsame Zustandswechsel nicht?
Erkennt er am Interrupteingang langsame Zustandswechsel nicht?
Ich fürchte fast das es so ist, auch wenn ich im Datenblatt auf die schnelle keine Angabe darüber gefunden hab.
Da steht nur vom Timing bei Wakeup was drin.
Eventuell kann man ja mal im Datenblatt von nem ATMEGA 8 oder ATMEGA 32 schauen.
Ich denk nicht das die Interruptschaltungen bei den Chips wesentlich anders sind.
Der INT 2 ist anscheinend intern anders aufgebaut, wenn Du da rankommst kannst Du ja mal die beiden Pins brücken und den INT 0 softwaremäßig abschalten und deine Routine im INT 2 ausführen.
Ich denke eher, das der Wurm in der Software liegt.
Viel zu lange Interupt Routinen zeigen beispielsweise exakt diese Symtome. Allerdings kann man da ohne Code nicht allzuviel machen.
Hubert.G
06.01.2007, 11:31
Ich habe einen mega16 am Steckbrett, wenn du mir deinen Quellcode schickst kann ich den mal ausprobieren und auch die Bedingungen der Flanken testen.
Hubert
Erkennt er am Interrupteingang langsame Zustandswechsel nicht?
Ich fürchte fast das es so ist, auch wenn ich im Datenblatt auf die schnelle keine Angabe darüber gefunden hab.
Kann ich mir nicht vorstellen. Der Interrupt wird ja ausgelöst durch den Flankenwechsel 0/1 oder halt 1/0. Ab der Eingang nun 0 oder 1 hat ist von der Spannung abhängig die anliegt. Wenn die langsam sinkt kommt der wechsel halt später aber er kommt. Also auch wenn die Spannung langsam sinkt gibts für den Interrupt ne steile Flanke( halt der wechsel 0/1..).
teslanikola
06.01.2007, 17:00
man könnte ja an den Interrupteingang nen Sägezahn hinhänge (so 1Hz oder so ) dann immer wenn der Interrupt kommt nen Port tooglen, dann kann man schnell fest stellen wie langsam der Flankenwechsel max. sein darf.
Also in der ISR wird genau eine Variable gesetzt und der Timer0 angeworfen. Fertig. Also ne sehr kurze Routine, daran liegt es nicht.
Zuerst werde ich die Hardware der LS ein wenig ändern, kürzere Leitungen, andere Widerstände. Dann kann ich mal ein Rechteck auf den INT Eingang loslassen, um zu sehen, ob das geht. Falls ja, sind es die schlechten Flanken der LS. Es ist anscheinend tatsächlich so, dass der AVR eine steile Flanke braucht, ansonsten ist er zu lange im "verbotenen Bereich"...
Es ist sehr wahrscheinlich, dass es an der LS liegt.
Ich werde berichten.
Herzlichen Gruss und vielen Dank
Mario
Hallo!
Ich bin (leider :) ) ein PIC Benutzer, kann also ein Blödsinn hier schreiben, bitte um Verständniss !
Muss bei AVR's das interrupt flag nicht in der Software gelöscht werden ?
MfG
Nää, wird automatisch gelöscht, sobald der Interrupt durch ist.
Aber es liegt nicht an der Software.. Ich sehe nicht, was da falsch sein sollte ==> LS macht Ärger
Hallo Murus!
Vielleicht sind die Flanken wirklich schlecht. Wenn Du langes geschirmtes Kabel benutzts, wäre es möglich. Versuch den pull-up R2 direkt an AVR pin anzuschliessen. Wenn es nichts bringt, musst Du die Flanken mit einem Schmitt-Trigger (z.B. 74HC14) "schärfen" oder anderes Kabel (mit weniger pF/m) nehmen.
MfG :)
Also in der ISR wird genau eine Variable gesetzt und der Timer0 angeworfen. Fertig. Also ne sehr kurze Routine, daran liegt es nicht.
bei Bascom sind es trotzdem um die 66+ Operationen die durchgeführt werden ... aber das ist ein anderes Thema.
Das Timer0 anwerfen hab ich aber in asm gemacht. (Bei Bascom wäre es "Start Timer0") Ischt trotzdem eine relativ kurze ISR.
SprinterSB
07.01.2007, 13:29
Bist du sicher, daß es nicht an seiner Software liegt?
Etwa, daß eine ISR zu lange braucht?. Du hast bestimmt noch andere IRQs aktiv. Wenn die zu lange dauern und IRQs so lange global deaktiviert sind passieren evtl mehrere INT-IRQs, von denen du nur einen siehst?
Ich habs auch schon runtergestrickt, bei der die ISR nur noch eine LED toggelte ==> dasselbe Resultat, die Software ist es nicht.
Bevor der nächste Int-IRQ kommt, ist der Timerinterrupt schon lange wieder ausgeschaltet.
SprinterSB
07.01.2007, 23:07
Ich meinte nicht die INT-IRQ, sondern andere aktive IRQs (UART, Timer, ADC, AC, etc)
Eben net... Nach dem Ext. Interrupt wird der Timer angeworfen, der lange voro dem nächsten Ext. Interrupt wieder ausgeschaltet wird. Das sind alle Interrupts.
Allerdings kann man da ohne Code nicht allzuviel machen.
Ich zitiere mich hier mal frecherweise selber, da das was hier im Moment läuft irgendwie an Sackhüpfen im Minenfeld erinnert ....
Hubert.G
08.01.2007, 16:33
Ich habe auch schon angeboten das Programm mit meinem M16 zu testen. Aber man kann nur dem helfen der sich auch helfen lassen will.
Hubert
Hier der Code:
$regfile = "m16def.dat"
$crystal = 6000000
Dim I As Byte
ddra.3=1
Porta.3=0
Ddrd.3 = 0
Portd.3 = 1
On Int1 Lichtschranke
Mcucr.2 = 1
Mcucr.3 = 1
Enable Interrupts
Config Timer0 = Timer , Prescale = 8
Enable Timer0
On Timer0 Zeit
Stop Timer0
I = 0
Enable Int1
Do
If I = 10 Then
Stop Timer0
I=0
End If
Loop
Lichtschranke:
Start Timer0
Timer1 = 0
Return
Zeit:
Toggle porta.3
Incr I
Return
Es ist nun so, dass der Lichtschranken-Interrupt nicht immer ausgeführt wird, manchmal aber schon ==> auch wenn ich den Draht langsam durch die Lichtschranke bewege, wird er zum Teil ausgelöst (flache Flanke). Normalerweise läuft er schnell durch (innert 300 Mikrosekunden ist der LS-Spalt vollständig abgedeckt), aber auch dann wird nicht immer ausgelöst.
1. finde ich den Code trotz seiner kürze sehr unübersichtlich.
2. wofür soll das gut sein: Timer1 = 0
3. wonach verifizierst du, das der Interupt ausgelöst wurde ?
Timer1=0 stellt ihn auf einen definierten Wert ein.
Ich seh ja, falls etwas blinkt ==> Interrupt, falls nicht ==> kein Interrupt.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.