Hallo zusammen,
hab mal eine Frage zu Timern. Arbeite mit einem LPC2132 und programmiere
in C.Ich lege ein 512Hz Rechtecksignal mit einem Signalgenerator an den
CAP 1.0 PIN des Prozessors an. Ich will jetzt einfach nachmessen ob
tatsächlich 512Hz anliegen. Wie mache ich das am besten? Ist es möglich
den timer bei der ersten steigenden Flanke zu starten und bei der
nächsten steigenden Flanke anzuhalten und anschließend die Differenz zu
bilden?Wenn ja, wie mache ich das?
danke schonmal für die Antworten...
Ich habe sowas mal folgendermaßen realisiert.
Bei der steigenden Flanke, die Du mit einem external Interrupt erkennst,
startest Du einen Timer, den Du beim nächsten Interrupt (nächste
steigende Flanke) wieder abstellst. Dann rechnest Du in µs, ms oder s um
und nimmst den Kehrwert.
Timer-Interrupt ist möglich, aber etwas ungenau weil die unbekannte
Interrupt-Latenz mitmischt. Dank umfangreicher Capture-Möglichkeiten der
LPC2000 unnötig.
Dabei wird der Timer nicht durch das Signal gestartet, sondern läuft
dauerhaft durch. Bei eine wählbaren Flanke am Eingang wird vom Timer
selbst (!) der aktuelle Wert im Capture-Register gespeichert und ein
Interrupt ausgelöst. Die Differenz zweier solcherart erfassten Werte ist
die Zeit zwischen den Flanken. Exakt, quarzgenau, Auflösung bis 17ns.
irgendwie will das bei mir nicht klappen...hier mal der quellcode.
findet jemand einen fehler?
PINSEL0 |= 0x200000;
TIMER1_TCR = 0x01; // aktiviert Timer counter
TIMER1_TC = 00;
TIMER1_CCR = 0x01; // rising edge on CAP 1.0 ladet CRO Register
printf("Registerinhalt CR0 %lx\n\r", TIMER1_CR0);
das ist jetzt nur die aktivierung des timers und der erste wert soll
ausgegeben werden. der timer läuft also los und bei einer steigenden
flanke an CAP1.0 soll der wert ausgegeben werden...ist das so korrekt?
Naja, zaubern kann er (noch) nicht, Glaskugelraten ist Forenmitgliedern
vorbehalten. Wirst schon auf das Capture-Event warten müssen bevor im
entsprechenden Register was dazu drinsteht.
sorry wenn ich mich bisschen blöd anstelle aber ich vertehs grad
nicht...wie kann ich auf das event warten?
...TIMER1_CCR = 0x01; ...sagt mir doch, dass sobald ein event an CAP1.0
auftaucht der wert des TC Registers in das CR0 Register geschrieben
wird?!vielleicht hat ja auch jemand ein Beispiel dazu?
znil wrote:
> ...TIMER1_CCR = 0x01; ...sagt mir doch, dass sobald ein event an CAP1.0> auftaucht der wert des TC Registers in das CR0 Register geschrieben> wird?!
Ja. Aber wenn du es wie oben unmittelbar nach dem Einstellen des Timers
ausliest, steht da noch nichts drin.
ja schon...das ist mir klar...wenn ich nun eine printf() Anweisung
dazwischen setze steht etwas im Register drin...aber das ist doch nicht
Sinn der Sache?! Wie mache ich das besser?
mein nächstes problem wäre dann:
Wie weiß ich, dass ich beim zweiten mal genau die zweite flanke treffe
und nicht die dritte oder irgendeine andere?daher weiß ich dann ja nicht
welche differenz ich bilde und daher auch nicht wie lange ein Takt
dauert...
wäre um sinnvolle antworten sehr dankbar...;)
Ob es eine kluge Wahl war, den Einstieg in die Programmierung von
Microcontrollern ausgerechnet mit LPC2000 zu machen? Für AVRs gibts hier
recht gute Einführungstexte, bei LPC2000 wird i.A. eine gewisse
Grundkenntnis vorausgesetzt.
Jedenfalls ist der sinnvollste Ansatz, das Cature-Event als Interrupt zu
nutzen und den Capture-Wert folglich im Interrupt auszulesen. Da geht
normalerweise nichts verloren.
Dass Interrupts auf LPC2000 je nach Programmierumgebung nicht unbedingt
trivial sind, steh auf einem anderen Blatt. Es sollte jedoch auch
möglich sein, dass Interrupt-Flag vom Capture-Event direkt abzufragen.
Ich hatte keine andere Wahl...;)okey dann versuche ich das jetzt mal so
zu realiseren...dürfte ja eigentlich nicht so schwer sein...aber doch
nochmal eine frage:
Muss ich denn das Capture event unbedingt als interrupt nutzen?soweit
ich im datenblatt gelesen habe gibt es doch auch die möglichkeit bei
einem event einfach den TC Wert in das CR0 Register zu laden...damit
hätte ich doch meinen wert bei der ersten Flanke. was ich dann eben nur
nicht verstehe ist, wie ich den wert bei der zweiten flanke erhalte?das
müsste doch eigentlich recht simpel funktionieren..., oder?!
vielen dank nochmal für die antworten
znil wrote:
> ich im datenblatt gelesen habe gibt es doch auch die möglichkeit bei> einem event einfach den TC Wert in das CR0 Register zu laden...
Nein, so funktioniert das nicht. Das machst nicht du, sondern der Timer.
Deine Aufgabe ist es, den Wert aus CR0 wieder rauszuholen.
Ohne Interrupts, per Abfrage:
t0 = CR0;
while (CR0 == t0)
;
t1 = CR0;
t = t1 - t0;
okey das ist mir jetzt soweit klar. ich vertehe aber immer noch nicht,
wie ich den zweiten wert bei der nächsten flanke erhalte?wie macht man
das?hier mal noch der quellcode, vielleicht entdeckt noch jemand einen
Fehler...danke schonmal
TIMER1_TCR = 0x01; // aktiviert Timer counter
PINSEL0 |= 0x200000; // P0.10 as CAP 1.0
TIMER1_CCR = 0x01; // rising edge on CAP 1.0 ladet CRO Register
start_value = TIMER1_CR0;
while(TIMER1_CR0 == start_value);
end_value = TIMER1_CR0;
difference = end_value - start_value;
printf("Zeitdifferenz %li\n\r", difference);