Forum: Mikrocontroller und Digitale Elektronik Timer Wert überschreiben LPC1769


von Michael1988 (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe folgendes Problem. Ich habe am ADC ein Potentiometer 
angeschlossen über den ich die Geschwindigkeit des Timer Aufrufes 
steuern möchte. Leider Funktioniert es nicht wirklich, da der Controller 
immer abstürzt.
Ich schreibe quasi einfach den Wert aus der AD-Wandlung in das MR0 
Register des timers. Hat jemand ein Tipp woran es liegen kann?

Druß

Michael

von Jim M. (turboj)


Lesenswert?

Wird MR0 kleiner als die Ausführungszeit des Interrupt Handlers, dann 
wird das Hauptprogramm in der Tat nicht weiter ausgeführt.

Stichwort: Tail-Chaining: Beim Verlassen des Handlers wird auf weitere 
aktive Interrupts geprüft und bei Bedarf via Tail-Chaining in deren 
Handler hineingesprungen. Ist der Interrupt noch oder wieder aktiv 
(pending), läuft auch der aktuelle Handler von vorne los.

Zusammenfassend muss entweder MR0 oder der Prescaler groß genug sein, 
dass nach Verlassen des Handlers noch Takte für das Hauptprogramm übrig 
bleiben.

Etwas Ähnliches passiert übrigens, wenn man ein Interrupt Flag vergisst 
zu löschen...

von Michael1988 (Gast)


Lesenswert?

Vielen Dank für die schnelle Antwort, ich habe erst versucht den 
Prescaler zu erhöhen, was aber leider keinen Erfolg brachte. Dann habe 
ich in die Funktion wo ich MR0 überschreibe ein short_delay eingefügt 
von 50ms. Jetzt ist mir aufgefallen, dass zwar etwas länger läuft, aber 
nach ca. 30 sekunden wieder abstürzt (Egal ob ich Poti bewege oder 
nicht). Kommentiere ich die Funktionn aus und lasse den Interrupt auf 1 
mikrosekunden fest laufen funktioniert es (Also ohne die Funktion 
geschw_aendern). Ich verstehe nicht ganz wo der Fehler liegen könnte

von Stefan (Gast)


Lesenswert?

Was verstehst du unter "Absturz"? Ich vermute daß MR0 auf einen Wert 
kleiner TC gesetzt wird bei einem der Updates.
Wenn TC z.B. gerade 8000 enthält, MR0 meinetwegen 10000 und dann MR0 auf 
5000 gesetzt wird, wird lange Zeit kein Match auftreten.
Mit dem delay verringerst du nur die Wahrscheinlichkeit daß das 
passiert.

von Michael1988 (Gast)


Lesenswert?

Also die switch-case steuert die Schrittvorgabe eines Schrittmotors und 
ich lasse mir die Signale zur Ansteuerung auf einem Oszilloskop 
ausgeben. Unter Absturz verstehe ich jetzt, das die Signale auf dem Oszi 
alle auf 0 sinken und der Conttroller nicht mehr reagiert.

von Stefan (Gast)


Lesenswert?

Versuche es doch mal so:
1
volatile uint32_t newVal = 1250;
2
3
void Timer0ISR() // oder wie die gerade heißt
4
{
5
   LPC_TIM0->MR0 = newVal;
6
   ...
7
}
8
9
void geschw_aendern(uint32_t neu)
10
{
11
   newVal = neu;
12
}

Solange "neu" nicht zu klein wird (also nahe 0, abhängig von Prescaler), 
sollte der von mir oben skizzierte Effekt nicht mehr auftreten.
MR0 wird damit erst aktualisiert wenn TC gerade zurückgesetzt wurde.

von Matthias (Gast)


Lesenswert?

Was sagt denn der Debugger?

von Michael1988 (Gast)


Angehängte Dateien:

Lesenswert?

Die Idee ist wirklich gut und schein auch eigentlich zu funktionieren, 
aber er ändert den Wert der Variable newVal auch in der ISR Routine aber 
übernimmt ihn komischer Weise nicht in MRO. in der Anweisung ist dann 
der Wert in MR0 = 1250, obwohl newVal = 1183 ist.
LPC_TIM0->MR0 = newVal;      // Reset Value

von Michael1988 (Gast)


Lesenswert?

Es funktioniert, ich muss natürlich den neuen Wert nicht in der Init 
übergeben sondern in dem IRQ_Handler (Ich Idiot). Und vor allem muss man 
ein Kill Flag setzen bevor man den Wert schreibt LPC_TIM0->IR |= (0x1 << 
0); // kill flag

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.