PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Pulsbreitenmessung



Import-Script
11.08.2002, 11:22
Hallo zusammen, ich möchte gerne eine Pulsbreitenmessung per Basic vornehmen. jetzt weiss ich aber leider nicht 100% wie ich die Zeitmessung hinbekommen kann? Wird das per Interrupt gemacht oder per Timer/ Counter ??? <BR>Jedenfalls, brauche ich noch paar informationen, wie ich das machen könnte. <BR>Kann mir da jemand nen kleinen Tip geben? Wäre sehr nett. <BR>Vielen Dank <BR> <BR>Chris

Import-Script
12.08.2002, 09:48
Hallo Chris, <BR> <BR>wie daß in Basic geht, weiß ich nicht. <BR> <BR>Aber es geht ganz einfach mit nem 8051. <BR>Dessen Timer haben einen Gate-Eingang und wenn man diesen benutzt, zählt er nur solange, wie der Eingang auf High-Pegel ist. <BR> <BR>Gleichzeitig ist dieser Pin ein Interrupt-Eingang. Somit kannst Du bequem erkennen, wann das Signal von 1-&#62;0 wechselt und dann den Timer auslesen. <BR> <BR> <BR>Peter <BR>

Import-Script
13.08.2002, 11:41
mhh, das wäre ja einfach :-&#41; <BR>das ganze sollte allerdings mit einem AVR mega funzen. weiss falsches forum, aber das hilft mir ja schon weiter,, thx

Import-Script
13.08.2002, 13:30
Beim AVR gibt es soweit ich weiß, keine Gate-Funktion. <BR> <BR>Man kann dann nur die Capture-Funktion verwenden. Dazu setzt man die Capture-Funktion auf die 0-&#62;1 Flanke. Wenn dann der Interrupt kommt liest man ganz schnell diesen Wert aus und setzt dann auf die 1-&#62;0-Flanke. Wenn diese dann wieder einen Interrupt auslöst, liest man auch diesen Wert aus und subtrahiert beide Werte. <BR> <BR>Der Haken an der Sache ist bloß, daß man nach dem ersten Interrupt ganz schnell die Flanke umschalten muß. Da der AVR aber nur eine Interruptpriorität hat, kann es sein, daß inzwischen ein anderer Interrupt läuft und der Puls schon wieder zuende ist, ehe man umgeschaltet hat. <BR> <BR>D.h. bei sehr kurzen Pulsbreiten ist der 8051 klar im Vorteil, da das Gate voll in Hardware realisiert ist, bzw. der Interrupt zum Auslesen des Timers die höchste Priorität haben kann und dann alle anderen Interrupts unterbrechen kann. <BR> <BR> <BR>Peter <BR>

Dän
28.02.2005, 14:01
Hallo zusammen,

Gibt es eigentlich auch eine Möglichkeit, den Timer laufen zu lassen, während der Interrupt-Eingang LOW ist? Ich möchte nämlich bei folgendem digitalen Signal messen können, wie lange welcher Zustand anliegt:

__|-----|__|-----|__

D.h. Messung beginnt, dann wird Zeit zwischen Flanke 1 und 2, 2 und 3, 3 und 4 gemessen, Messung stoppt. Im Handbuch zum Altium TSK51x steht, es kann nur inkrementiert werden wenn HIGH Pegel an INT anliegt? Und wie macht man dem Interrupt klar, daß er von einer fallenden Flanke ausgelöst werden soll - im Handbuch ist nämlich nur die Rede von steigender Flanke oder HIGH Pegel? Vielen Dank schonmal im Voraus...

Winne
28.02.2005, 14:19
Hallo zusammen,

Gibt es eigentlich auch eine Möglichkeit, den Timer laufen zu lassen, während der Interrupt-Eingang LOW ist? Ich möchte nämlich bei folgendem digitalen Signal messen können, wie lange welcher Zustand anliegt:

__|-----|__|-----|__

D.h. Messung beginnt, dann wird Zeit zwischen Flanke 1 und 2, 2 und 3, 3 und 4 gemessen, Messung stoppt. Im Handbuch zum Altium TSK51x steht, es kann nur inkrementiert werden wenn HIGH Pegel an INT anliegt? Und wie macht man dem Interrupt klar, daß er von einer fallenden Flanke ausgelöst werden soll - im Handbuch ist nämlich nur die Rede von steigender Flanke oder HIGH Pegel? Vielen Dank schonmal im Voraus...


lass den Timer durch die Lowflanke starten, und durch die Hhighflanke stoppen.

oder Lass in durchlaufen und durch jede Flanke einen ExInt auslösen , dann die ISR die aktuellen Zählerstände auslesen , so bekommst du die Zeiten aller Flankenwechsel. Zuordnen must du sie dann noch.

Besser du liest in der ISR zusätzlich den Zustand des bits dann hast du nen record:
"zeit, level, zeit, level, zeit, level, ..........."

mit atmmega/tiny geht das 51er ?


Hardwaremäßig kanst du das Signal über einen Inverter schicken dan hast du es auch.

Dän
28.02.2005, 16:00
Also atmmega/atmtiny geht bei 51er wohl nicht...

Die ExInts durch jede Flanke auslösen zu lassen während der Timer einfach durchläuft wäre für die Zuordnung Zeit/Flankenwechsel machbar.
Das Handbuch von Altium ist bloß an der Stelle wo die Zuordnung von Interruptanforderungen zu externen Ereignissen beschrieben wird etwas verwirrend:

"IE1, Interrupt 1 Edge Flag. Set by hardware when falling edge on external pin INT1 is observed."

"IT1, Interrupt 1 type control bit. Selects whether a rising edge or a High Level on input pin INT1 will cause an interrupt."

Für mich heißt das, daß ein Interrupt hardwaremäßig durch Setzen des Interrupt Request Flags IE1 bei fallender Flanke an INT1 ausgelöst wird. Aber warum ist dann beim control bit IT1 die Rede von steigender Flanke?

Winne
28.02.2005, 16:18
Also atmmega/atmtiny geht bei 51er wohl nicht...

Die ExInts durch jede Flanke auslösen zu lassen während der Timer einfach durchläuft wäre für die Zuordnung Zeit/Flankenwechsel machbar.
Das Handbuch von Altium ist bloß an der Stelle wo die Zuordnung von Interruptanforderungen zu externen Ereignissen beschrieben wird etwas verwirrend:

"IE1, Interrupt 1 Edge Flag. Set by hardware when falling edge on external pin INT1 is observed."

"IE, Iterrupt 1 FlankenFlag. wird von Hardware gesetzt, wenn eine fallende Flanke am ext Pin Int1 beobachtet wird."




"IT1, Interrupt 1 type control bit. Selects whether a rising edge or a High Level on input pin INT1 will cause an interrupt." [QUOTE]

"IT1, Interrupt 1 Type-Control-Bit. Wählt, ob eine steigende Flanke oder ein High Level am Eingangspin INT1 eine Unterbrechung verursacht, ".

[QUOTE]Für mich heißt das, daß ein Interrupt hardwaremäßig durch Setzen des Interrupt Request Flags IE1 bei fallender Flanke an INT1 ausgelöst wird. Aber warum ist dann beim control bit IT1 die Rede von steigender Flanke?


Leider fehlt mir der gesamtte zusammenhang so kann ich nur die aussagen übersetzen den kontex musst du finden oder die quelle im zusamenhang einscannen. und auf mein Pobox werfen 200-300 dpi schwarz weis als *.jpg's hoch laden wen zuwenig platz kannst dus selbe freischaufeln.

Winne
28.02.2005, 16:19
Also atmmega/atmtiny geht bei 51er wohl nicht...

Die ExInts durch jede Flanke auslösen zu lassen während der Timer einfach durchläuft wäre für die Zuordnung Zeit/Flankenwechsel machbar.
Das Handbuch von Altium ist bloß an der Stelle wo die Zuordnung von Interruptanforderungen zu externen Ereignissen beschrieben wird etwas verwirrend:

"IE1, Interrupt 1 Edge Flag. Set by hardware when falling edge on external pin INT1 is observed."

"IE, Iterrupt 1 FlankenFlag. wird von Hardware gesetzt, wenn eine fallende Flanke am ext Pin Int1 beobachtet wird."




"IT1, Interrupt 1 type control bit. Selects whether a rising edge or a High Level on input pin INT1 will cause an interrupt." [QUOTE]

"IT1, Interrupt 1 Type-Control-Bit. Wählt, ob eine steigende Flanke oder ein High Level am Eingangspin INT1 eine Unterbrechung verursacht, ".

[QUOTE]Für mich heißt das, daß ein Interrupt hardwaremäßig durch Setzen des Interrupt Request Flags IE1 bei fallender Flanke an INT1 ausgelöst wird. Aber warum ist dann beim control bit IT1 die Rede von steigender Flanke?


Leider fehlt mir der gesamtte zusammenhang so kann ich nur die aussagen übersetzen den kontex musst du finden oder die quelle im zusamenhang einscannen. und auf mein Pobox werfen 200-300 dpi schwarz weis als *.jpg's hoch laden wen zuwenig platz kannst dus selbe freischaufeln.

Winne
28.02.2005, 16:22
Also atmmega/atmtiny geht bei 51er wohl nicht...

Die ExInts durch jede Flanke auslösen zu lassen während der Timer einfach durchläuft wäre für die Zuordnung Zeit/Flankenwechsel machbar.
Das Handbuch von Altium ist bloß an der Stelle wo die Zuordnung von Interruptanforderungen zu externen Ereignissen beschrieben wird etwas verwirrend:

"IE1, Interrupt 1 Edge Flag. Set by hardware when falling edge on external pin INT1 is observed."
"IE, Iterrupt 1 FlankenFlag. wird von Hardware gesetzt, wenn eine fallende Flanke am ext Pin Int1 beobachtet wird."




"IT1, Interrupt 1 type control bit. Selects whether a rising edge or a High Level on input pin INT1 will cause an interrupt."
"IT1, Interrupt 1 Type-Control-Bit. Wählt, ob eine steigende Flanke oder ein High Level am Eingangspin INT1 eine Unterbrechung verursacht, ".




Für mich heißt das, daß ein Interrupt hardwaremäßig durch Setzen des Interrupt Request Flags IE1 bei fallender Flanke an INT1 ausgelöst wird. Aber warum ist dann beim control bit IT1 die Rede von steigender Flanke?


Leider fehlt mir der gesamte Zusammenhang so kann ich nur die Aussagen übersetzen. den Kontex musst du finden oder die Quelle im Zusamenhang einscannen. und auf meine Pobox werfen 200-300 dpi schwarz/weiss als *.jpg's hoch laden wenn zuwenig Platz kannst, du ihn selber freischaufeln.

Dän
01.03.2005, 23:23
Ich versuche den gesamten Zusammenhang nochmal zusammenzufassen: Ein Timer soll sowohl bei steigender als auch bei fallender Flanke ausgelesen werden. Dazu müssen beide Flanken einen ExInt erzeugen können, mein TSK51 kann aber nur auf steigende Flanke oder HIGH Pegel Interrupts auslösen. Das hab ich aber inzwischen mit einem Inverter hinbekommen, indem das Originalsignal auf INT0 und das invertierte auf INT1 liegt, dann löst die steigende Flanke halt INT0 und die fallende INT1 aus. Aber eine Frage hab ich noch: Wie bekommt man die Zuordnung Zeit-Level aus der ISR raus, bevor bei der nächsten Flanke in dieselbe ISR eingesprungen und das ganze neu geschrieben wird?

Winne
02.03.2005, 07:31
Ich versuche den gesamten Zusammenhang nochmal zusammenzufassen: Ein Timer soll sowohl bei steigender als auch bei fallender Flanke ausgelesen werden. Dazu müssen beide Flanken einen ExInt erzeugen können, mein TSK51 kann aber nur auf steigende Flanke oder HIGH Pegel Interrupts auslösen. Das hab ich aber inzwischen mit einem Inverter hinbekommen, indem das Originalsignal auf INT0 und das invertierte auf INT1 liegt, dann löst die steigende Flanke halt INT0 und die fallende INT1 aus. Aber eine Frage hab ich noch: Wie bekommt man die Zuordnung Zeit-Level aus der ISR raus, bevor bei der nächsten Flanke in dieselbe ISR eingesprungen und das ganze neu geschrieben wird?


Lege ein Datenarray (z.B. unsigned fallend*255, steigend*255 ) an oder besser zwei, sowie zwei Integervariablen welche du als Zeiger(pointer) verwendest.

Beide ISR lesen jeweils den Zählerstand aus dem Timer und tragen ihn in das jeweilige Array ein und setzen den zugehörigen Zeiger eins weiter. Wenn deine Arrays voll sind, stoppe die Interupts und lasse die array's über die serielle schnittstelle als Datenfiles ans Hypertterminal senden Der Rest ist Rechnen(timertaktdauer * timerdifferenzen zwischen den Flanken) und kann im Pc erfolgen. Oder du berechnest im µC und bringst die Ergebnisse wie auch immer zur Anzeige, dann ist natürlich der Datentransfer überflüssig. Du kannst einzelne low und high Zeiten berechnen und oder Durchschnittswerte, sowie Abweichung bzw Konstanz.

Du kannst auch versuchen ob Du, während der highlevel ISR, gleich die Zeit berechnen und auf eine Anzeige zu bringen kannst. Aber das kann bei kurzen und nicht sehr gleichmäßigen Impulsen mit hoher Impulsfolge unablesbar werden.

Oder mußt du die Pulslängen sofort weiterverarbeiten ?

Ich habe leider keine Vorstellung was das Ganze werden soll. Davon kann aber die sinnvollste Vorgehensweise abhängen.

Dän
02.03.2005, 10:04
Stimmt, es wäre schon gut zu wissen wofür das ganze da ist...

Das Signal ist das digitalisierte Signal einer Fotodiode aus einem optischen Meßsystem. Die erste Flanke ist der Beginn der Messung, an dem meine Mechanik den Beginn des Meßfeldes erreicht, zwischen der zweiten und der dritten Flanke ist die Lichtquelle durch ein Meßobjekt abgeschattet, und die letzte Flanke markiert das Ende der Messung. Danach sind ca. 60ms Zeit bevor eine neue Messung erfolgen kann weil die entsprechende Mechanik erst wieder den Referenzpunkt anfahren muß. Ergebnis soll letztendlich sein, wie lange es dauert, bis die Abschattung eintritt, wie lange diese dauert, und wie lange es danach dauert bis das Meßfeld wieder verlassen wird. Also wäre es wohl am besten die Zeiten zunächst nur in ein Array zu schreiben und dann während der "Pause" im PC zu verarbeiten?

Winne
02.03.2005, 12:15
also ablauf wie folgt:

def array
def busyflag
JMP start

ISR 1: //HL
erste zwischenzeit + HL ident---> array
reti

ISR 2://LH
zweite zwischen zeit +LH ident--> array
clear busyflag
reti


start:

if Lichtschranke Low goto start //warte auf LH an Lichtschranke
timer start
set busyflag


do while (busyflag)

gosub send_data_to_PC

claer array

goto start

Winne
02.03.2005, 12:26
Klar,

ISR sollten nur der Datenrettung oder dem Request-Answering dienen den Rest erledigt das Hauptprogramm mittels Subroutines. Das Hauptprogramm geht in eine Init-Routine und dann in eine Warte-Schleife. In der Kontrolliert es Flags welche von ISR gesetz oder gelöscht werden je nachdem ob neue Daten vorliegen oder Stati abzugeben sind, und verzweigt in entsprechende Subs, diese setzen und löschen ihreseits Flags (wenn sie etwas erledigt haben oder zu erledigen ist und kehren dann zum Huptprogramm zurück.
wo weiter auf Ereignisse gewartet wird.

Dän
03.03.2005, 23:06
Alles klar,

etwa so habe ich das ganze jetzt mal programmiert...aber bisher konnte ich es nicht testen da ich den Timer0 nicht ans laufen bekomme. Kann es sein daß Interrupts für Timer nicht korrekt ausgeführt werden wenn man den Timer woanders noch als Baudratengenerator für die serielle Schnittstelle verwendet? ExInts und Timer0 haben doch eigentlich nichts damit zu tun, ob man die Baudrate mit Hilfe von Timer1 berechnet?

Winne
03.03.2005, 23:11
Alles klar,

etwa so habe ich das ganze jetzt mal programmiert...aber bisher konnte ich es nicht testen da ich den Timer0 nicht ans laufen bekomme. Kann es sein daß Interrupts für Timer nicht korrekt ausgeführt werden wenn man den Timer woanders noch als Baudratengenerator für die serielle Schnittstelle verwendet? ExInts und Timer0 haben doch eigentlich nichts damit zu tun, ob man die Baudrate mit Hilfe von Timer1 berechnet?

Das ist im höchsten Maße wahrscheinlich.
Du mußt die TIMER-Controllregister dann immer mit reinitilieseren, wenn du denselben Timer im Programmverlauf anderweitig verwenden willst. Oder nen anderen Timer verwenden. (wenn du davon genug im Chip hast).

Dän
11.03.2005, 01:40
Alles klar, Timer läuft, kann auch über die serielle Schnittstelle Flankenanzahl und Zeitpunkte auslessen :)

Habe aber immer noch ein Problem: Die ersten beiden Werte sind völlig unsinnig, danach geht es aber plausibel weiter...

Beispiel: Testsignal Rechteck mit 1 kHz, d.h. man sollte nach dem Zeitpunkt "0" doch alle 0,5ms eine Flanke erwarten können. Ausgelesen wird aber sowas wie:

Flanke# Zeitpunkt [ms]
0 0,004
1 0,045
2 0,230
3 0,730
4 1,230
5 1,730
.....

D.h. die Abstände stimmen erst ab dem dritten Wert, mit einem gewissen Offset weil der Timer ja schon vom ersten Wert an lief. Mein Code macht sowas wie

Zeitmessung start:
{
Timer Run Control=0;
Timerregister 0 setzen;
ExInt für steigende Flanke aktivieren;
}

Bei steigender Flanke
{
Timer Run Control=1;
Timer auslesen;
In Array schreiben;
ExInt für fallende Flanken aktivieren;
}

Bei fallender Flanke
{
Timer auslesen;
In Array schreiben;
}

Messung Stop:
An PC senden;
Umrechnen in Millisekunden.

Das ganze soll also durch die erste steigende Flanke starten und dann jede weitere erfassen. Sieht irgendwie so aus als würden am Anfang zwei völlig unsinnige Interrupts ausgelöst? Woran kann sowas liegen?

Winne
11.03.2005, 11:14
Da bräuchte ich meine Glaskugel, die ist aber zur Reparatur.:(

Helfen könnten aber ein Schaltbild der Messanordnung und der Assemblercode des ausgeführten Programmes.
Da die Startsequenz des Timers auch Zeit benötigt wäre es besser den mit einem Vorsprung vor dem eigentlchen Versuch zu starten bzw. wenn möglich den Versuchsstart an einem definerten Timerwert zu initieren zum Beispiel in dem der Timer gestartet wird und beim ersten Overflow einen Interupt auslöst der den Versuch startet.

Auch dabei werden auf Grund des sequentiellen Ablaufes der Prozesse im µC( kein verzögerungsfreier Echtzeitanalogrechner) Verzögerungen auftreten, welche sich aber durch aufrechnen der Systemtakte, welche zur Ausgabe des Startimulses odr anderer Operationen nötig sind vom ersten Timerwert abzuziehen sind.
Bedenke das jede Operation des µC Zeit braucht, um welche die gemessenen Werte zu korrigieren sind.

Mir sieht es aus , als würde erst der time gesartet, und dann die IRQs enabled woruf je einer sofort auftritt die solltest du vom auswertugsprogramm ignoririer lassen und deine bechnungen erst mit der ersten plausiblen Zeitdifferenz beginnen. das ist am einfachsten wenn dadurch nicht das eigentliche ergenis verfächt wird . Vielleicht benötigt aber auch Dein zu überwachendes sytem eine Einschwingphase? und generiert die impulse tatsächlich.
Das erfährst du in dem du die ersten Intrupts überwachst , ohne das zu messende System daran. Dann siehst du was von Deiner Messschaltung(fälchlich) und was von Deinem zu messendem System(tatsächlich) generiert wird.

Arne
15.03.2005, 11:54
Hallo erstmal (wieder),

ein Interrupt tritt auf, sobald beide IR-Flags gleichzeitig enabled werden. Das kann man aber umgehen, indem die eine ISR die andere ISR freigiebt. Um die Mess-Genauigkeit nicht zu beeinträchtigen, sollte dieses am Schluß der ISR geschehen.

Kommen diese Werte so (+/-2) eigentlich immer zu stande?

Flanke# Zeitpunkt [ms]
0 0,004
1 0,045
2 0,230
3 0,730
4 1,230
5 1,730 Nr.2 sollte ja zumindest bei 500ms stehen! Irgendwo verlieren sich hier rund 270µs - das ist häftig viel! Womit proggst Du da eigentlich?

Theoretisch müßte Dein Hauptprogramm die Messung vorbereiten, in dem der Timer vorbereitet wird und dann bei Änderung am Eingang als erstes der Timer gestartet wird und dann die 'gegenteilige' ISR enabled wird. Bei Interrupt für diese, wird auch die andere ISR zugelassen. Der erste Wert wird also nicht in die Tabelle geschrieben, da er ja eh 0,000 sein müßte. So kompliziert dürfte das also nicht sein... .

Probleme mit der Rechenzeit sehe ich vor allem, wenn dieses Projekt nicht in Assembler geschrieben wird. Die benötigte Rechenzeit läßt sich quasi nur schätzen und Fehlmessungen sind die Folge. Mit welchem internen Takt arbeitest Du eigentlich?

Gruß,
Arne

Dän
15.03.2005, 22:43
Die Idee daß die erste ISR für EX0, für die steigende Flanke, die andere freigibt, hatte ich auch schon. Hab allerdings nicht daran gedacht vor dem Setzen von EX1=1 EX0=0 zu setzen. Dann besteht tatsächlich die Möglichkeit daß beide Flags gleichzeitig gesetzt sind...

Ich werde das mit der gegenseitigen Freigabe gleich morgen versuchen. Interner Takt ist 24 Mhz.