Forum: Mikrocontroller und Digitale Elektronik STm32F103: Unix Time und RTC


von Christian J. (Gast)


Lesenswert?

Hallo,

mit diesem 32 Bit Zähler, einer verkrüppelten RTC werde ich nicht so 
recht glücklich derzeit :-( Sie läuft nach Beispiel von ST. Ok. Aber 
flashe ich den Baustein bleibt sie auch genauso lange stehen. Der 407 
lief einwadfrei durch, die RTC lässt durch nichts beinflussen.

Das ist natürlich ärgerlich wenn man per Debug die Zeit stellt, also den 
Stellbefehl genau dann ausführt, wenn eine genau Uhr diese Zeit zeigt. 
Oder mache ich da was falsch?

Mangels sec,min, hour kam ich auf die Idee die Unix Time einzustellen, 
es gibt da Online Zähler im Internet.

Selbst wenn ich das Flash Problem mal außer Betracht lasse... weiss 
zufällig jemand, ob es fertige Routinen gibt, die mir 1458641787 wie 
gerade jetzt fertig umrechnen in eine time_t Struktur aus time.h? Und 
wenn es geht auch rückwärts? Ich finde da seltamerweise kaum etwas zu.

von Pete K. (pete77)


Lesenswert?

geht das nicht mit localtime()?

Oder schau mal hier:
Beitrag "unix zeit -> normale Zeit."

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Christian J. schrieb:
> Selbst wenn ich das Flash Problem mal außer Betracht lasse... weiss
> zufällig jemand, ob es fertige Routinen gibt, die mir 1458641787 wie
> gerade jetzt fertig umrechnen in eine time_t Struktur aus time.h?

Ja. Wird in der WordClock mit WS2812 benutzt, da findest Du es im 
Source, nämlich timeserver.c:
1
void
2
timeserver_convert_time (struct tm * tmp, uint32_t seconds_since_1900)
3
{
4
    time_t          curtime;
5
6
    struct tm *      mytm;
7
    uint_fast8_t    summertime = 0;
8
9
    curtime = (time_t) (seconds_since_1900 - 2208988800U);
10
    curtime += 3600 * timezone;                                             // localtime() on STM32 returns GMT, but we want ME(S)Z
11
12
    mytm = localtime (&curtime);
13
14
    // calculate summer time:
15
    if (mytm->tm_mon >= 3 && mytm->tm_mon <= 8)                             // april to september
16
    {
17
        summertime = 1;
18
    }
19
    else if (mytm->tm_mon == 2)                                             // march
20
    {
21
        if (mytm->tm_mday - mytm->tm_wday >= 25)                            // after or equal last sunday in march
22
        {
23
            if (mytm->tm_wday == 0)                                         // today last sunday?
24
            {
25
                if (mytm->tm_hour >= 2)                                     // after 02:00 we have summer time
26
                {
27
                    summertime = 1;
28
                }
29
            }
30
            else
31
            {
32
                summertime = 1;
33
            }
34
        }
35
    }
36
    else if (mytm->tm_mon == 9)                                             // it's october
37
    {
38
        summertime = 1;
39
40
        if (mytm->tm_mday - mytm->tm_wday >= 25)                            // it's after or equal last sunday in october...
41
        {
42
            if (mytm->tm_wday == 0)                                         // today last sunday?
43
            {
44
                if (mytm->tm_hour >= 3)                                     // after 03:00 we have winter time
45
                {
46
                    summertime = 0;
47
                }
48
            }
49
            else
50
            {
51
                summertime = 0;
52
            }
53
        }
54
    }
55
56
    if (summertime)
57
    {
58
        curtime += 3600;                                                    // add one hour more for MESZ
59
        mytm = localtime (&curtime);
60
    }
61
62
    tmp->tm_year    = mytm->tm_year;
63
    tmp->tm_mon     = mytm->tm_mon;
64
    tmp->tm_mday    = mytm->tm_mday;
65
    tmp->tm_wday    = dayofweek (mytm->tm_mday, mytm->tm_mday + 1, mytm->tm_year + 1900);
66
    tmp->tm_isdst   = mytm->tm_isdst;
67
    tmp->tm_hour    = mytm->tm_hour;
68
    tmp->tm_min     = mytm->tm_min;
69
    tmp->tm_sec     = mytm->tm_sec;
70
}

Wenn Du die Sekunden seit 1.1.1970 und nicht 1.1.1900 hast, dann enfällt 
diese Zeile:
1
curtime = (time_t) (seconds_since_1900 - 2208988800U);

Als Schmankerl ist da noch die automatische 
Sommer-/Wintzerzeit-Umstellung drin, die Dir localtime() auf einem STM32 
ohne Betriebssystem nicht liefern kann.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Zusatz:

timezone ist die Zeitzone in Differenz zu GMT. Bei uns wegen GMT+1 also 
gleich 1.

von Christian J. (Gast)


Lesenswert?

Frank M. schrieb:
> Wenn Du die Sekunden seit 1.1.1970 und nicht 1.1.1900 hast, dann enfällt
> diese Zeile:curtime = (time_t) (seconds_since_1900 - 2208988800U);

Kannste mal die datei und den header anhängen? Da fehlt noch was... 
finde ich auch so schnell nicht.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Christian J. schrieb:
> Kannste mal die datei und den header anhängen? Da fehlt noch was...

  http://www.mikrocontroller.net/svnbrowser/wordclock24h/?view=tar

timeserver.h und timeserver.c. Die anderen in timeserver.c enthaltenen 
Funktionen brauchst Du wahrscheinlich nicht.

von Christian J. (Gast)


Lesenswert?

Hat sich auch erledigt, das ist alles "drin" in time.h

struct tm mytime;

  time1.tm_hour = 15;
    time1.tm_min  = 30;
    time1.tm_sec  = 0;
    time1.tm_mday = 22;
    time1.tm_year = 116;
    time1.tm_mon  = 2;
    time1.tm_wday = 2;

    uint32_t ret = mktime(&time1);
    strftime(buffer, sizeof(buffer), "%c", &time1 );


ret ergibt dann den Unix Wert. strftime gibt einen String in US 
Schreibweise aus. Bläst den Code allerdings auch ganz schön auf fast 8kb 
frisst das :-(((

Mit localtime komme ich allerdings noch nihct klar, die soll das 
Gegenteil machen aber tut sie nicht.

von Christian J. (Gast)


Lesenswert?

Die Umwandlung einer Unix Zeit in einen String läuft

struct tm *ptr;
   char buf [80];
   time_t utime =  1458658803;
   ptr = localtime(&utime);
   sprintf(buf,"%s",asctime(ptr));

ergibt "Tue Mar 22 15:00:03 2016\n"

Aber wie kriege ich jetzt den tm Struct mit den gefüllten Feldern?

edit: ok, erledigt. Mit

struct tm inhalt;
memcpy(&inhalt,ptr,sizeof(inhalt));

hole ich mir die Daten in meinen eigenen Struct.

Nettes Feature :-)

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.