Forum: Mikrocontroller und Digitale Elektronik 64 Bit Timer einstellen


von Kevin F. (entrax)


Lesenswert?

Hallo,

Ich habe ein Texas Instruments TM4C123GH6PM.
Programm: IAR Embedded Workbench.

Ich brauche ein 64 bit Timer der jede stunde ein Interrupt auslöst.
Interrupt ist kein Problem.

Die ganze Konfiguration ist auch kein Problem, nur bei einem Punkt komm 
ich nicht weiter. Denn LOAD wert bis wohin der Timer zählen soll muss 
ich in zwei 32 Bit Register schreiben. Also es wird für ein 64 Bit 
Timer, Intern Timer A (32 Bit) und B (32 Bit) benutzt/verschaltet.

Laut Handbuch: When a 32/64-bit Wide GPTM is configured to one of the 
64-bit modes, GPTMTAILR contains bits
31:0 of the 64-bit count and the GPTM Timer B Interval Load (GPTMTBILR) 
register contains bits
63:32.

Eingebunden wird natürlich dazu die "lm4f120h5qr.h"
1
    //Timer disable (GPTMCTL) //P.737
2
    WTIMER0_CTL_R = 0x0;
3
    
4
    //Timer A configuration, 64 Bit (GPTMCFG) //P.727
5
    WTIMER0_CFG_R = TIMER_CFG_64_BIT_TIMER; //64 Bit Timer
6
    
7
    //Timer A Mode, periodic (GPTMTAMR) //P.729
8
    WTIMER0_TAMR_R = TIMER_TAMR_TAMR_PERIOD; //Periodischer Timer
9
    
10
    //Interval Load value, 1h (GPTMTAILR) //P.756
11
    //57600000000 = 1h;
12
    WTIMER0_TAILR_R = ??????
13
    WTIMER0_TBILR_R = ??????
14
15
    //Interrupt Mask (GPTMIMR) //P.746
16
    WTIMER0_IMR_R = TIMER_IMR_TATOIM; //Interrupt wird an den NVIC geschickt
17
    
18
    //Timer enable (GPTMCTL) //P.737
19
    WTIMER0_CTL_R = TIMER_CTL_TAEN;

Die Register WTIMER0_TAILR_R und WTIMER0_TBILR_R sind jeweils die 
Internen Timer A und B die zu einem 64 Bit Timer verschaltet werden.

Hat wer eine Lösung oder ein Rat für mich was ich bei den ??????? rein 
schreibe?
Bei einem 16 Bit bzw 32 Bit timer ist es ja einfach mit den Registern.

von A. S. (Gast)


Lesenswert?

Kevin F. schrieb:
> //57600000000 = 1h;

ich weiss ja nicht, wer den Kommentar geschrieben hat, aber versuche es 
doch mit dem Wert bzw. korrigiere ihn nach Dreisatz.

Wenn Dir nicht klar ist, wo X%(2^32) und wo X/(2^32) reinkommt, ... dann 
probiere beide Möglichkeiten aus, am besten mit einem Wert der etwa 2s 
entspricht.

(und wenn es im ersten Schuss ungefähr passen soll, und X >> 2^32 ist, 
dann schreibe in beide einfach x/(2^32) rein.

von stiller Leser (Gast)


Lesenswert?

ins Blaue geschossen...
57600000000=0xD693A4000
MSB 0000000D
LSB 693A4000

Oder anders rum?
Keine Ahnung, denn ich kenne die Zielplattform nicht.

so ähnlich?
1
    //Interval Load value, 1h (GPTMTAILR) //P.756
2
    //57600000000 = 1h;
3
    WTIMER0_TAILR_R = 0x0000000D
4
    WTIMER0_TBILR_R = 0x693A4000

Ist aber nur geraten.

von Michael R. (mr-action)


Lesenswert?

stiller Leser schrieb:
>
1
>     //Interval Load value, 1h (GPTMTAILR) //P.756
2
>     //57600000000 = 1h;
3
>     WTIMER0_TAILR_R = 0x0000000D
4
>     WTIMER0_TBILR_R = 0x693A4000
5
>

Bei dem, was er oben schreibt, würde ich es genau anders herum machen... 
Aber wo ist jetzt eigentlich das Problem?

von Peter D. (peda)


Lesenswert?

Kevin F. schrieb:
> Ich brauche ein 64 bit Timer der jede stunde ein Interrupt auslöst.

Typisch nimmt man dazu den System-Tick-Interrupt (1ms) und zählt darin 
eine Variable von 3600000 abwärts.

von georg (Gast)


Lesenswert?

Peter D. schrieb:
> Typisch nimmt man dazu den System-Tick-Interrupt (1ms) und zählt darin
> eine Variable von 3600000 abwärts

So man einen hat (Linux, kann man aber auch selber machen) - aber was 
jedenfalls richtig ist: eigentlich braucht man keinen 64bit-Timer. Ich 
verwende immer einen Timer im ms-Bereich, wie Peters Systick, und für 
verschiedene Aufgaben werden Timevariablen in der Timer-ISR hoch- oder 
runtergezählt. So bedient die generelle Timerroutine z.B. 10 "virtuelle" 
Timer, und die haben nach oben keine Grenze, was Auflösung oder 
Zeitdauer angeht. Man kann leicht einen 128-bit-Timer implementieren 
oder einen, der bis zum Ende des Sonnensystems zählt.

Georg

von PittyJ (Gast)


Lesenswert?

Gibt es da keine Vorteiler?
Ich kenne diese CPU nicht. Aber bei vielen Timer-Subsystemen kann man 
erst einmal einen Vorteiler einstellen, damit das Timer-System nicht mit 
Systemtakt gespeist wird. Ich gebe da z.B. 48000 bei 48Mhz an, damit die 
Timer nur im Millisekunden-Intervall hochgezaehlt werden. Darauf kann 
man dann Interrupts in noch größeren Intervallen erzeugen.

Was sagt das Handbuch zu Vorteilern?

von time.h (Gast)


Lesenswert?

Für 1h braucht man keinen so gewaltigen Timer.

Ich verwende dazu üblicherweise time_t aus der time.h (C 
Standardlibrary) und zähle das jede Sekunde hoch.

Alles was man dazu braucht ist ein Timerinterrupt, der regelmässig kommt 
und mit einer Ganzzahl multipliziert genau 1s ergibt. Das kann zum 
Beispiel der 1ms-Timer von für FATFS sein. Den Rest erledigt ein kleine 
Prescaler in Software.

Damit hat man eine richtige Systemzeit, ohne eine RTCC oder einen 
Uhrenquarz zu benötigen. Mit Stunden, Minuten, Tagen und so weiter. 
mktime(), gmtime() und Konsorten sind dein Freund.

Dein Problem lässt sich damit sehr einfach lösen.

time.h liefert der C-Compiler meistens gratis mit.

von A. S. (Gast)


Lesenswert?

time.h schrieb:
> Für 1h braucht man keinen so gewaltigen Timer.

Sinn macht der ganze Quatsch wirklich nur, wenn man mit dem Timer jede 
Stunde aufstarten will (und kann). Ansonsten ist ein SysTicker das 
einzig sinnvolle, vor allem weil so ein riesiger Timer herrlich 
asy(nchron) ist. Wer soll dessen Wirkung wirklich sinnvoll debuggen.

von Kevin F. (entrax)


Lesenswert?

Hallo, danke für die zahlreichen Antworten.

Das große Timer asy(nchron) sind wusste ich. Danke dafür erst mal!

Wollte alles erst mal gerne ohne eine extra time.h machen damit man es 
natürlich auch alles versteht.

Das man Virtuelle Timer erzeugt sozusagen, über den Systick-Timer 
Interrupt, ist eine gute idee.
Muss mich dann nur informieren ob der Systick auch kleiner 1ms 
eingestellt werden kann, wenn benötigt.

Meine Idee war mit dem 64 Bit Timer, z.B. jede Stunde einmal alle 
Messwerte abspeichern als Übersicht.
Mein Projekt ist ein Inkubator und da sollte bzw. MUSS die Temperatur 
über all nahe zu Konstant sein. Deswegen wollte ich mit dem 64 Bit Timer 
ein 24h oder 48h Stunden Protokoll führen im Probelauf.
Ein weiterer 16 Bit Timer Interrupt (zur zeit alle 3ms) löst die Analog 
messung aus. Mit der Priorität 1.


stiller Leser schrieb:
> ins Blaue geschossen...
> 57600000000=0xD693A4000
> MSB 0000000D
> LSB 693A4000
>
> Oder anders rum?
> Keine Ahnung, denn ich kenne die Zielplattform nicht.
>
> so ähnlich?
>
1
>     //Interval Load value, 1h (GPTMTAILR) //P.756
2
>     //57600000000 = 1h;
3
>     WTIMER0_TAILR_R = 0x0000000D
4
>     WTIMER0_TBILR_R = 0x693A4000
5
>
>
> Ist aber nur geraten.

Da war ich mir erst selber nicht sicher, weil bei einem 16/32 Bit Timer 
kann man auch den LOAD wert als int zahl rein schreiben.

von A. S. (Gast)


Lesenswert?

Kevin F. schrieb:
> Mein Projekt ist ein Inkubator und da sollte bzw. MUSS die Temperatur
> über all nahe zu Konstant sein. Deswegen wollte ich mit dem 64 Bit Timer
> ein 24h oder 48h Stunden Protokoll führen im Probelauf.
> Ein weiterer 16 Bit Timer Interrupt (zur zeit alle 3ms) löst die Analog
> messung aus. Mit der Priorität 1.

Ich hoffe, Du hast Kollegen, die Dich bei Deinen ersten Schritten in der 
embedded-Programmierung vor Ort unterstützen. Oder zumindest 
Beispielcode, an dem Du die Grundstrukturen erkennen kannst.

Die ewige Frage (event-getriggert / zyklisch) und die typischen 
Umsetzungen (Synchronisierung / SysTicker) sollten zumindest bekannt 
sein (bzw. werden), wenn man sich an echte Geräte macht.

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.