PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ext. Interrupt löst nur unregelmässig aus



Murus
05.01.2007, 12:42
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

Murus
05.01.2007, 23:02
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.

Murus
05.01.2007, 23:58
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

wkrug
06.01.2007, 01:59
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...

Murus
06.01.2007, 09:58
Geht net... Chip schon verlötet (SMD) und auf der Unterseite der Platine, die bereits eingebaut ist...

wkrug
06.01.2007, 10:54
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 ?

Murus
06.01.2007, 10:56
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?

wkrug
06.01.2007, 11:23
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.

Hanni
06.01.2007, 11:27
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

Rofo88
06.01.2007, 13:35
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.

Murus
06.01.2007, 22:47
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

PICture
07.01.2007, 05:34
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

Murus
07.01.2007, 09:59
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

PICture
07.01.2007, 11:57
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 :)

Hanni
07.01.2007, 12:00
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.

Murus
07.01.2007, 12:11
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?

Murus
07.01.2007, 16:29
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)

Murus
08.01.2007, 15:55
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.

Hanni
08.01.2007, 16:05
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

Murus
08.01.2007, 17:54
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.

Hanni
08.01.2007, 18:32
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 ?

Murus
08.01.2007, 18:34
Timer1=0 stellt ihn auf einen definierten Wert ein.
Ich seh ja, falls etwas blinkt ==> Interrupt, falls nicht ==> kein Interrupt.