Forum: Mikrocontroller und Digitale Elektronik tmie.h und RTC


von Joachim J. (felidae)


Lesenswert?

Ich habe einen msp430 und eine RTC.

Ich lese die werte für Tag, Monat, Jahr, Stunde, Minute und Sekunde aus 
der RTC, in BCD format, aus. Dann wandle ich sie in int werte um.

jetzt möchte ich tm aus time.h verwenden um die Zeit in einer variable 
zu speichern und mit dieser zu rechnen.

1
Ausschnitt aus time.h 
2
struct tm 
3
{
4
    int tm_sec;      /* seconds after the minute   - [0,59]  */
5
    int tm_min;      /* minutes after the hour     - [0,59]  */
6
    int tm_hour;     /* hours after the midnight   - [0,23]  */
7
    int tm_mday;     /* day of the month           - [1,31]  */
8
    int tm_mon;      /* months since January       - [0,11]  */
9
    int tm_year;     /* years since 1900                     */
10
    int tm_wday;     /* days since Sunday          - [0,6]   */
11
    int tm_yday;     /* days since Jan 1st         - [0,365] */
12
    int tm_isdst;    /* Daylight Savings Time flag           */
13
14
};

Einer Variable vom Typ tm werte direkt zuzuweisen funktioniert nicht,
denn wenn ich tm_mday den wert 12 zuweise bleiben tm_wday tm_yday 
unangetastet also 0.

Ich habe schon viele Tutorials zu time.h im Internet gefunden. Dort wird 
aber immer nur die Systemzeit ausgelesen und angezeigt.

kennt sich jemand mit time.h aus und weiß wie es richtig geht?

von Dirk B. (dirkb2)


Lesenswert?

Joachim J. schrieb:
> Einer Variable vom Typ tm werte direkt zuzuweisen funktioniert nicht,
> denn wenn ich tm_mday den wert 12 zuweise bleiben tm_wday tm_yday
> unangetastet also 0.

Was machst du dazwischen? Einfach nur Werte rein schreiben reicht nicht.
Da muss noch ein mktime gemacht werden.

http://www.cplusplus.com/reference/ctime/mktime/

von Forum: Mikrocontroller und Digitale Elektronik (Gast)


Lesenswert?

> Forum: Projekte & Code
>
> Hier könnt ihr eure Projekte, Schaltungen oder Codeschnipsel
> vorstellen und diskutieren. Bitte hier keine Fragen posten!

von Joachim J. (felidae)


Lesenswert?

Hier ein Ausschnitt aus meinem jetzigen Code.
mit dieser Funktion Stelle ich die RTC.


1
time_t RTC_timestep = 0; // Systemzeit wird über Timer jede sec erhöht
2
3
4
void RTC_stelle(unsigned char jahr,unsigned char monat,unsigned char tag,unsigned char stunde,unsigned char minute,unsigned char seckunde)
5
{
6
  if( (monat-1)<=12 && (tag-1)<=31 && stunde<=23 && minute<=59 && seckunde<=59)
7
  {
8
    struct tm *timeinfo;
9
10
    timeinfo = localtime(&RTC_timestep);
11
12
    timeinfo->tm_year  =  jahr - 1900;
13
    timeinfo->tm_mon  =  monat - 1;
14
    timeinfo->tm_mday  =  tag;
15
    timeinfo->tm_hour  =  stunde;
16
    timeinfo->tm_min  =  minute;
17
    timeinfo->tm_sec  =  seckunde;
18
19
    RTC_timestep = mktime(timeinfo);
20
21
    CHIP_SELECT_ON;
22
23
    SPI_send_byte(SECUNDE_W);
24
    SPI_send_byte(HEX_to_BCD(seckunde));
25
26
    SPI_send_byte(MINUTE_W);
27
    SPI_send_byte(HEX_to_BCD(minute));
28
29
    SPI_send_byte(STUNDE_W);
30
    SPI_send_byte(HEX_to_BCD(stunde));
31
32
    SPI_send_byte(TAG_W);
33
    SPI_send_byte(HEX_to_BCD(tag));
34
35
    SPI_send_byte(MONAT_W);
36
    SPI_send_byte(HEX_to_BCD(monat));
37
38
    SPI_send_byte(JAHR_W);
39
    SPI_send_byte(HEX_to_BCD(jahr-2000));
40
41
    CHIP_SELECT_OFF;
42
  }
43
}

von Karl H. (kbuchegg)


Lesenswert?

Joachim J. schrieb:

>     timeinfo = localtime(&RTC_timestep);

localtime wirst du wohl nicht benutzen können.
Woher soll denn dein µC wissen, wie spät es ist oder in welcher Zeitzone 
du lebst?

>     CHIP_SELECT_ON;
>
>     SPI_send_byte(SECUNDE_W);
>     SPI_send_byte(HEX_to_BCD(seckunde));
>
>     SPI_send_byte(MINUTE_W);
>     SPI_send_byte(HEX_to_BCD(minute));
>
>     SPI_send_byte(STUNDE_W);
>     SPI_send_byte(HEX_to_BCD(stunde));
>
>     SPI_send_byte(TAG_W);
>     SPI_send_byte(HEX_to_BCD(tag));
>
>     SPI_send_byte(MONAT_W);
>     SPI_send_byte(HEX_to_BCD(monat));
>
>     SPI_send_byte(JAHR_W);
>     SPI_send_byte(HEX_to_BCD(jahr-2000));
>
>     CHIP_SELECT_OFF;

Frage:
Wenn du die Werte sowieso nur brauchst, damit du die RTC stellst, wozu 
dann der ganze Umweg über die struct tm?
Nimm die Werte von Benutzer und schreib sie in die RTC und gut ists.

Ob Funktionen wie mktime auf einem µC der keine eingebaute RTC hat auch 
tatsächlich mit Leben 'gefüllt' sind, würde ich im Zweifel ausprobieren. 
Recht viel mehr, als das mir der Wochentag errechnet wird würde ich mir 
da nicht erwarten. Auf so einem µC würde ich (bis zum Beweis des 
Gegenteils) eher davon ausgehen, dass ich auf mich allein gestellt bin.

von Dirk B. (dirkb2)


Lesenswert?

Joachim J. schrieb:
> if( (monat-1)<=12 && (tag-1)<=31

Wenn du 1 vom Monat abziehst, ist der höchste gültige Monat 11.
Dann ist die 12 oder das <= falsch.

https://www.google.de/search?q=seckunde

von Joachim J. (felidae)


Lesenswert?

Karl Heinz schrieb:

> Frage:
> Wenn du die Werte sowieso nur brauchst, damit du die RTC stellst, wozu
> dann der ganze Umweg über die struct tm?
> Nimm die Werte von Benutzer und schreib sie in die RTC und gut ists.

diese Funktion ist nur ein Ausschnitt aus meinem Programm.
an einer anderen stelle lese ich die Zeit aus der RTC aus wandle sie in 
eine variable vom Type time_t um und speichere sie zusammen mit 
Messwerten auf einen Flash. Außerdem berechne ich noch Zeitdifferenzen.

von Dirk B. (dirkb2)


Lesenswert?

1
void RTC_stelle(unsigned char jahr,unsigned char monat,...)
2
...                             
3
    timeinfo->tm_year  =  jahr - 1900;

Welchen Wert hast du denn in jahr gespeichert? Da passt ja nur das 
Jahrzent vernünftig rein. Warum dann noch - 1900?
Oder übergibst du die komplette Jahreszahl, dann wird die aber 
abgeschnitten.

von Ingo L. (corrtexx)


Lesenswert?

Meine Fubnktion sieht so aus:
1
void Set_RTC ( volatile struct tm * Time )
2
{
3
  uint16_t Temp = 0;
4
5
  CS_RTC_ENABLE();
6
  Usi_Data(WRITE | HOURSET);
7
  Usi_Data( ((Time->tm_hour/10) << 4) + (Time->tm_hour%10) );
8
  CS_RTC_DISABLE();
9
  
10
  CS_RTC_ENABLE();
11
  Usi_Data(WRITE | MINUTESET);
12
  Usi_Data( ((Time->tm_min/10) << 4) + (Time->tm_min%10) );
13
  CS_RTC_DISABLE();
14
  
15
  CS_RTC_ENABLE();
16
  Usi_Data(WRITE | SECONDSET);
17
  Usi_Data( ((Time->tm_sec/10) << 4) + (Time->tm_sec%10) );
18
  CS_RTC_DISABLE();
19
  
20
  CS_RTC_ENABLE();
21
  Usi_Data(WRITE | YEARSET);
22
  /* 2015 => 115 */ 
23
  Temp = Time->tm_year;
24
  Temp = Temp + 1900 - 2000;
25
  Usi_Data( ((Temp/10) << 4) + (Temp%10) );
26
  CS_RTC_DISABLE();
27
  
28
  CS_RTC_ENABLE();
29
  Usi_Data(WRITE | MONTHSET);
30
  Temp = Time->tm_mon;
31
  Temp++;
32
  Usi_Data( ((Temp/10) << 4) + (Temp%10) );
33
  CS_RTC_DISABLE();
34
  
35
  CS_RTC_ENABLE();
36
  Usi_Data(WRITE | DAYSET);
37
  Usi_Data( ((Time->tm_mday/10) << 4) + (Time->tm_mday%10) );
38
  CS_RTC_DISABLE();
39
  
40
  CS_RTC_ENABLE();
41
  Usi_Data(WRITE | WDAYSET);
42
  Usi_Data( Time->tm_wday + 1);
43
  CS_RTC_DISABLE();
44
  
45
  WriteEEprom(Time->tm_isdst);
46
}
Du musst nach jedem Register mit dem CS Wackeln, sonst klappts nicht ;)
Meiner Meinung nach ist also deine Schreibfunktion falsch

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.