Hallo,
Ich benutze folgenden Code um mit einem ATMega328P externe Interrupt
auszulösen:
1
;
2
; MultiLaserTrigger.asm
3
;
4
; Created: 24.10.2016 15:41:11
5
; Author : antonios.styogiannis
6
;
7
.def temp = r16
8
.def ledson = r17
9
.def ledsoff = r18
10
11
.org 0x0000
12
rjmp main ; Reset Handler
13
14
.org INT0addr
15
rjmp EXT_INT0
16
17
main:
18
; Stackpointer initialisieren
19
ldi temp, HIGH(RAMEND)
20
out SPH, temp
21
ldi temp, LOW(RAMEND)
22
out SPL, temp
23
ldi temp, 0b11111111 ; Port B auf Ausgang
24
out DDRB, temp
25
ldi ledson, 0b11111111
26
ldi ledsoff, 0b00000000
27
ldi temp, (1 << ISC01) | (1 << ISC00)
28
sts EICRA, temp
29
ldi temp, (1 << INT0)
30
out EIMSK, temp
31
sei
32
out PORTB, ledsoff
33
34
loop1:
35
rjmp loop1
36
37
EXT_INT0:
38
out PORTB, ledson
39
out PORTB, ledsoff
40
reti
Ich benutze eine 47 Ohm Pull-Down Widerstand in INT0 (Pin D2).
Der Interrupt ist zirka 502 ns von der steigende Flanke verzögert.
Das Problem ist dass, der Interrupt Impuls
(
EXT_INT0:
out PORTB, ledson
out PORTB, ledsoff
reti
)
hat viel Jitter, das nicht immer eine Takt Zyklus ist (62ns), aber kann
auch weniger sein. Die Verzögerung ist immer zwischen 500ns ud 650ns!
Warum gibt es so viel Jitter?
Kann man helfen?
Hm. Man braucht hier keinen Kalender mehr: Es MUSS Freitag sein.
Wie schon in Deinem anderen Thread
Beitrag "ATMega328P /avrasm External Interrupt funktioniert nicht" beruht Dein
Problem hauptsächlich darauf, dass Du das Datenblatt nicht gelesen hast.
Tu das bitte.
Du wirst feststellen, dass die Reaktionszeit auf einen Interrupt keine
Konstante ist und auch nicht sein kann, denn das Ereignis, dass den
Interrupt auslösen soll wird vermutlich nicht synchron zum Takt
erfolgen.
Ebenso solltest Du zumindest erklären, wie Du auf 47 Ohm
Pulldown-Widerstand kommst. Den solltest Du so schnell wie möglich
auslöten.
Ebenso solltest Du Dir hier im Forum den Artikel zur Tastenentprellung
durchlesen.
Viel Erfolg.
Antonis schrieb:> hat viel Jitter, das nicht immer eine Takt Zyklus ist (62ns), aber kann> auch weniger sein. Die Verzögerung ist immer zwischen 500ns ud 650ns!> Warum gibt es so viel Jitter?
Nein.
Bei gepostetem Program kann es nur ein Takt sein, also +/- 62.5ns.
Und es hängt davon ab, wann der INT (bei "rjmp loop1") feuert.
> Die Verzögerung ist immer zwischen 500ns ud 650ns!
Kann auch nicht sein.
Jump zum Vector = 5-6 Takte.
rjmp zur EXT_INT0 = 2 Takte
out PORTB, ledson = 1 Takt
===============================
Ergibt 8 oder 9 Takte = 500ns - 562.5ns
Wie du auf 650ns kommst (was ja bei der Frequenz unmöglich ist),
ist mir nicht klar.
S. Landolt schrieb:> Der Befehl rjmp benötigt 2 Takte, genauso groß wird der Jitter, eben> je nachdem wann die Flanke innerhalb rjmp loop1 eintrifft.
Nicht ganz.
Es kann nur bei Takt1 oder Takt2 eintreffen, dazwischen gibt es
nichts.
Bei Takt1 ist es +1 Takt, bei Takt2 gibt es keinen zusätzlichen Takt.
S. Landolt schrieb:> Wenn die auslösende Flanke nicht-synchron ist? Das verstehe ich nicht.
Hast auch wieder Recht, natürlich.
Ich sprach von Takten, also synchron.
Asynchron können es selbstverständlich +/- 124,9999999999ns sein...
P.S.
Was auch weniger als 2 Takte ist :-)
P.P.S.
Aber 650ns können es niemals sein.
Antonis schrieb:> hat viel Jitter, das nicht immer eine Takt Zyklus ist (62ns), aber kann> auch weniger sein. Die Verzögerung ist immer zwischen 500ns ud 650ns!> Warum gibt es so viel Jitter?
Du kennst scheinbar nichtmal den Unterschied zwischen "Jitter" und
"Delay"...
Der Jitter liegt bei dem gezeigten Programm natürlich bei 2 Takten,
einer resultiert aus dem temporalen Alignment zur rjmp-Instruktion in
main(), der andere aus der Asynchronität des externen Signals. Zusammen
nennt man den Kram "variable Interrupt-Latenz". Das ist etwas
treffender, weil weniger allgemein als "Jitter".
Dazu kommt dann noch die konstante Interrupt-Latenz, beim gezeigten
Programm sind das 6 Takte.
Zusammen ergibt sich daraus das "Delay". Dieses sollte also zwischen 6
und 8 Takten liegen.
> Die Verzögerung ist immer zwischen 500ns ud 650ns!
500/6=83.33
650/8=81.25
Passt auffallend gut. Man kann wohl mit an Sicherheit grenzender
Wahrscheinlichkeit behaupten, dass der Systemtakt wohl ungefähr bei 6MHz
liegt.
Du hast ihn ja in deinem Posting nicht einmal angegeben. Dabei sollte
doch wohl selbst absoluten Vollidioten klar sein, dass bezüglich
irgendwelcher Diskussionen über das Timing der Systemtakt eine so
wichtige Rolle spielen muss, dass man ihn besser wohl angeben sollte...
Oder anders ausgedrückt: Schleich dich, du Troll!
c-hater schrieb:> Passt auffallend gut. Man kann wohl mit an Sicherheit grenzender> Wahrscheinlichkeit behaupten, dass der Systemtakt wohl ungefähr bei 6MHz> liegt.>> Du hast ihn ja in deinem Posting nicht einmal angegeben.
Hat er doch, wahrscheinlich hast du es übersehen:
Antonis schrieb:> hat viel Jitter, das nicht immer eine Takt Zyklus ist (62ns), aber kann
Bis auf die fehlenden 0,5ns sieht es für mich wie 16MHz aus...
Womit er aber das gemessen haben will und wo kommen die 2ns her ?
Antonis schrieb:> Der Interrupt ist zirka 502 ns von der steigende Flanke verzögert.Antonis schrieb:> hat viel Jitter, das nicht immer eine Takt Zyklus ist (62ns), aber kann> auch weniger sein. Die Verzögerung ist immer zwischen 500ns ud 650ns!c-hater schrieb:> Der Jitter liegt bei dem gezeigten Programm natürlich bei 2 Takten,> einer resultiert aus dem temporalen Alignment zur rjmp-Instruktion in> main(), der andere aus der Asynchronität des externen Signals. Zusammen> nennt man den Kram "variable Interrupt-Latenz". Das ist etwas
Stimmt schon, nur ist der synchrone Jitter 1 Takt, d.h. der Portzustand
ändert sich im Vergleich zum vorigen Zustand höchstens 1 Takt später
als es sollte.
Asynchrones Jitter liegt natürlich bei (fast) 2 Takten, muss aber von
der steigenden Flanke gemessen werden und ich glaube ganz einfach
nicht, dass der TO dazu imstande ist, vor allem nicht mit der
angegebenen Präzision von 2ns.
Marc V. schrieb:> Stimmt schon, nur ist der synchrone Jitter 1 Takt, d.h. der Portzustand> ändert sich im Vergleich zum vorigen Zustand höchstens 1 Takt später> als es sollte.
Ja. Das ist genau das Thema "asynchrone Quelle". Dazu kommt halt noch:
temporales Alignment zu "rjmp" in main(). Da das halt nummal zwei Takte
dauert, kannst du es in zwei verschiedenen Zuständen erwischen. Und du
erwischst es zwingend, weil AVR8 zwischen zwei Interrupts nunmal immer
zwingend eine Instruktion in main() ausführen. -> 1 Takt Unwägbarkeit.
Und das ist noch der einfachere Fall. Normalerweise wird in main() ja
mehr getan als nur "rjmp main".
> Asynchrones Jitter liegt natürlich bei (fast) 2 Takten, muss aber von> der steigenden Flanke gemessen werden
???
Die Richtung der Flanke hat definitiv nix mit dem Zeitverhalten der
Interrupts zu schaffen...
c-hater schrieb:> Die Richtung der Flanke hat definitiv nix mit dem Zeitverhalten der> Interrupts zu schaffen...
Falsch ausgedrückt, also nochmal:
...von der Triggerschwelle aus gemessen...
c-hater schrieb:> Ja. Das ist genau das Thema "asynchrone Quelle". Dazu kommt halt noch:> temporales Alignment zu "rjmp" in main(). Da das halt nummal zwei Takte> dauert, kannst du es in zwei verschiedenen Zuständen erwischen.
Ja, das würde ich unter "Jitter" verbuchen - der Rest ist für mich
fraglich (Messung wo - Schaltung, etc).