STm32F103: Unix Time und RTC

Gast #4517033
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.
Moderator Persönliche Seite #4517117
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.
Gast #4517370
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.
Gast #4517426
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 :-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren