Hallo
typedef struct
{
uint8_t seconds;
uint8_t minutes;
uint8_t hours;
} displ_time;
displ_time get_time;
uint32_t cantime=0;
cantime=(((message->data[4]<<16)|(message->data[3]<<8)|message->data[2])
);
//cantime seconds seit 24uhr.
get_time.hours=(cantime/3600);
sprintf(buffer,"%d#%2x-%2x-%2x\0",get_time.hours,message->data[4],messag
e->data[3],message->data[2]);
GLCD_chartext(&buffer[0],132,191,26,2,2);
die message->data daten stimmen
feld4=0
feld3=0xc8
feld2=sek z.b 0xd9
ich habe cantime im devcpp ausprobiert dort kommt wenn ich cantime/3600
teile 14 raus für 14 Uhr.
hier kommt 86 raus
kann mir einer meinen schlauch entfernen auf dem ich gerade stehe.
Viele Dank
Andreas Herrmann schrieb:> ich habe cantime im devcpp ausprobiert dort kommt wenn ich cantime/3600> teile 14 raus für 14 Uhr.
lass dir mal im devcpp die cantime ausgeben und dann vergleich mit dem
Wert, den du hier hast
message->data[4]<<16
arbeitest du auf einem AVR?
Wenn ja, dann hast du hier einen Überlauf.
Dieser Ausdruck wird in int gerechnet. int hat 16 Bit. Damit schiebst du
alle Bits links raus. Der Ausdruck ergibt immer 0.
Was ist die Frage und was kommt falsch, aber :
sprintf(buffer,"%d#%2x-%2x-%2x\0",
get_time.hours,message->data[4],message->data[3],message->data[2]);
z.B.: Parameter 1 erwartet integer, du übergibst aber ein uint8_t
Klaus Falser schrieb:> Was ist die Frage und was kommt falsch, aber :>> sprintf(buffer,"%d#%2x-%2x-%2x\0",> get_time.hours,message->data[4],message->data[3],message->data[2]);>> z.B.: Parameter 1 erwartet integer, du übergibst aber ein uint8_t
Kommt in dem Fall sogar das richtige raus.
der uint8_t wird vor Übergabe automatisch auf int aufgeblasen.
Hallo
message->data[4]<<16
arbeitest du auf einem AVR?
Wenn ja, dann hast du hier einen Überlauf.
Dieser Ausdruck wird in int gerechnet. int hat 16 Bit. Damit schiebst du
alle Bits links raus. Der Ausdruck ergibt immer 0.
Also uint32 ahbe zu int gemacht und es geht es kommt 14 raus so was
blödes ist uint32 nicht ausreichend????
Danke
Gruß
Andy
Andreas Herrmann schrieb:> Also uint32 ahbe zu int gemacht und es geht es kommt 14 raus so was> blödes ist uint32 nicht ausreichend????
das wird mir jetzt zu verwirrend.
Das war
* der falsche fix
* da data[4] sowieso 0 war, hat es sich nicht ausgewirkt
Zeig bitte alles. Die ganze Funktion. Copy&Paste
(So wie sie nicht funktioniert).
Aus dem was du gepostet hattest, ergibt sich nur dieser eine Fehler, der
sich aber aufgrund der tatsächlichen Daten nicht auswirkt.
Hallo
stimmt data[4] ist 0 das ist so io.
unsigned int cantime=0;
cantime=(((message->data[4]<<16)|(message->data[3]<<8)|message->data[2])
);
get_time.hours=(cantime/3600);
get_time.minutes=((cantime)-(get_time.hours*3600))/60;
sprintf(buffer,"%02d:%02d\0",get_time.hours,get_time.minutes);
GLCD_chartext(&buffer[0],130,191,26,2,2);
mit dem funktionierts
ne blöde frage wie bekomme ich auch die sekunden heraus aus cantime???
ich habe vor das Datum in tagen seit 1970 auszugeben oder über den Bus
zu übermitteln
Mein ansatz
day=16
month=12
year=2010
day=(rtc.date[0]*10)+rtc.date[1];
month=(rtc.date[3]*10)+rtc.date[4];
year=2000+(rtc.date[8]*10)+rtc.date[9];
diff=(year-1970)*12;
diff+=month;
diff=(diff*30.4368499)+day;
diff=tage seit 1970 = 14990 tage.
Gruß
Andy
Andreas Herrmann schrieb:> ne blöde frage wie bekomme ich auch die sekunden heraus aus cantime???
Na ja.
Wieviele Minuten und Sekunden sind denn in 234 Sekunden
Das sind 234 / 60 gleich 3 Minuten
d.h. von den 234 Sekunden sind 180 für die 3 Minuten schon verrechnet
worden und übrig bleiben: 234 - ( 3*60 ) gleich 54 Sekunden.
234 Sekunden sind also 3 Minuten und 54 Sekunden
Oder wie man in der Grundschule schon lernt:
Eine Mutter hat 14 Äpfel und 3 Kinder. Wenn alle Kinder gleich viele
Äpfel bekommen, wieviele Äpfel bekommt jedes Kind und wieviele bleiben
der Mutter übrig?
Division mit Rest
/ ist in C die Division.
% ist in C der Rest, der bei einer Ganzzahl-Division bleibt.
Hallo
jetzt habe ich den salat.
unsigned int cantime=0;
cantime=(((message->data[4]<<16)|(message->data[3]<<8)|message->data[2])
);
get_time.hours=(cantime/3600);
get_time.minutes=((cantime)-(get_time.hours*3600))/60;
sprintf(buffer,"%02d:%02d\0",get_time.hours,get_time.minutes);
GLCD_chartext(&buffer[0],130,191,26,2,2);
data[4] ist jetzt 1
im devcpp kommt das richtige ergebniss (18Uhr) der AVR liefert 0
cantime=67250.
Danke
Andreas Herrmann schrieb:> if(month==1 || month>1)daysumm+=31;
Echt?
Für den 7. Jänner werden wegen des Jänners (month == 1) immer 31 Tage
gutgeschrieben?
> if(month==12)daysumm+=day;
Das verblüfft mich jetzt ein wenig, dass das Tagesdatum nur dann mit
eingerechnet wird, wenn der Monat Dezember vorliegt. Eigentlich hätte
ich das immer erwartet, denn vom Jahresbeginn aus gerechnet ist der 7.
Jänner der 7. Tag im Jahr, wohingegen der 7. Februar der 38. Tag im Jahr
ist. 31 für den kompletten Jänner und dann noch 7 im Februar dazu.
Denk nachmal über deine Monatsabfragen nach. Tipp: Du brauchst da kein
Oder
Andreas Herrmann schrieb:> data[4] ist jetzt 1
Das 'Problem' ist nach wie vor, dass
message->data[4]<<16
in 16 Bit int gerechnet wird, weil message->data[4] nicht größer als ein
int ist.
Wenn du aber einen 16 Bit int um 16 Stellen nach links verschiebst
bleibt im Ergebnis, welches nach den C Regeln ebenfalls nur 16 Bit
umfasst, nichts mehr übrig.
Du hast sozusagen dein Auto zuweit über die Klippen rausgeschoben und
jetzt ist es weg.
Du musst also message->data[4] zuerst auf einen 32 Bit Typen hochcasten,
damit du ihn um 16 Bit nich links verschieben kannst UND im Eregbniss
dann auch noch was übrig bleibt, weil es dann 32 Bit groß ist.
Hallo
Das hier geht nicht
long cantime=0;
cantime=(((long)message->data[4])<<16)|(message->data[3]<<8)|message->da
ta[2];
als stunde kommt eins raus statt 19.
Danke
Gruß
Andy
Wie hast du eigentlich data definiert.
Ansonsten: Schau dir deine Werte an, rechne nach und finde raus, wo das
Programm etwas anderes machst als du erwartest.
Geht nicht anders. Du musst das lernen, wie du selber Fehler auf die
Schliche kommen kannst.
(D.h. das stimmt nicht ganz. Ein C-Buch wäre deine erste Anlaufstelle)
Hallo
hast Du vieleicht ein Tip für ein gutes Buch???
Danke
Habeübrigends den Fehler gefunden
Natürlch sollte man die Gegenstelle auch so definieren das wenn es über
die 65xxx grenze geht auch zu long wandeln.
danke
Andreas Herrmann schrieb:> Hallo>> hast Du vieleicht ein Tip für ein gutes Buch???
Der Klassiker
Kernighan&Ritchie
Programmieren in C
> Habeübrigends den Fehler gefunden>> Natürlch sollte man die Gegenstelle auch so definieren das wenn es über> die 65xxx grenze geht auch zu long wandeln.
gut.
Übrigens:
Wenn du auf Byte-Ebene arbeitest, dann willst du immer haben, dass dir
ein eventuelles Vorzeichenbit nicht in die Quere kommt.
Das heißt du arbeitest IMMER mit unsigned Datentypen!
Sei das jetzt unsigned char, oder unsigned int oder unsigned long.
Hauptsache unsigned.
Hallo
Danke
Klappt jetzt alles wunderbar
GPS CAN Modul sendet Datm(tage seit 1.1.1970) Uhrzeit(sekunden seit
00:00)
Display empfängt über CAN und rechnet zurück
Das Buch werde ich mir als erstes morgen betsellen.
Für heute ist feierabend
Danke
Gruß
Andy
Hallo
Buch bestellt bei Amazon neu.
Noch eine dringende frage habe jetzt das Problem das wenn Data[4]=0 ist
die Uhrzeit nicht mehr stimmt.
Ist es möglich wenn Data[4]==0 dann unsigned int cantime
wenn data[4]==1 dann unsigned long cantime.
Wenn ich jetzt wo data4[0] ist unsigned int nehme haut es wieder hin.
Danke
Andreas Herrmann schrieb:> Ist es möglich wenn Data[4]==0 dann unsigned int cantime wenn data[4]==1> dann unsigned long cantime.
Wozu sollte das gut sein? Wo ist denn das Problem, wenn cantime immer
unsigned long ist?
Andreas Herrmann schrieb:> Ist es möglich wenn Data[4]==0 dann unsigned int cantime> wenn data[4]==1 dann unsigned long cantime.>> Wenn ich jetzt wo data4[0] ist unsigned int nehme haut es wieder hin.
Dann muss man das Problem analysieren.
Diese "Ich probiere so lange rum bis es funktioniert"-Technik
funktioniert nicht auf Dauer.
Hallo
Ich schon wieder
Jetzt bin ich an die magische zahl 14965 angelangt für datum seit
1.1.1970.
wäre 21.12.2010.
long candate=14965;
dabei erhalte ich für tag=246 monat=12 year=2011
wenn ich 14964 setze dann 20.12.2010;
ich kann das ganze doch auch in ein uint32_t packen.
Habe mal den quellcode angehangen nur der Formatierung wegen.
Danke
Gruß
ANdy
Hallo
habe durch zufall entdeckt das 14965/365=41 Jahre sind dann hat es ja
nicht hin.
dies betrifft alles was ende dezember ist egal welches jahr
rechne ich gestern 14964 +1 Jahr drauf 365 und teile durch 365 kommen 41
Jahre wieder raus für 2011.
Wie kompensiere ich den Dezember????
Danke
Andreas Herrmann schrieb:> Hallo>> habe durch zufall entdeckt das 14965/365=41 Jahre sind dann hat es ja> nicht hin.>> dies betrifft alles was ende dezember ist egal welches jahr>> rechne ich gestern 14964 +1 Jahr drauf 365 und teile durch 365 kommen 41> Jahre wieder raus für 2011.>> Wie kompensiere ich den Dezember????
Was um alles in der Wet machst du da bloss
1
uint16_ts=0,jahr=1970;
2
s=(int)day/365;
3
for(inti=0;i<s;i++)
4
{
5
if(schaltjahr(jahr)==1)
6
{
7
day-=366;
8
}
9
else
10
{
11
day-=365;
12
}
13
jahr++;
14
}
Es gibt doch nicht nur for-Schleifen.
Sinn der Sache ist es offenbar das Jahr festzustellen und wieviele Tage
dann im nicht vollständig angerechneten Jahr noch übrig bleiben. Du
kannst dir doch nicht im Vorfeld mit day/365 ausrechnen, wieviele Jahre
das sind. Wenn du das könntest, dann bräuchtest du nicht so kompliziert
runterzählen sondern könntest ganz einfach: day = day - 365*s machen
und hast richtig reduziert. Da du das (aus naheliegenden Gründen) nicht
tun kannst, kannst du auch nicht in der Umkehrung dividieren. Wenn nicht
sicher gestellt ist, dass in 10 Jahren genau 3650 Tage vorkommen, dann
gilt logischerweise auch die Umkehrung nicht, dass 3650 Tage genau 10
Jahre sind.
1
uint16_tjahr=1970;
2
3
while(day>365){
4
if(schaltjahr(jahr))
5
day-=366;
6
else
7
day-=365;
8
9
jahr++;
10
}
die Abbruchbedingung der while Schleife muss ich noch überlegen. Da muss
noch was rein je nachdem ob man sich in einem Schaltjahr befindet oder
nicht, ist der 366.te Tag manchmal der 12.Dezember und manchmal der
1.Jänner
Schnellschuss
1
uint16_tjahr=1970;
2
3
while(day>365||(day>366&&schaltjahr(jahr+1)){
4
if(schaltjahr(jahr))
5
day-=366;
6
else
7
day-=365;
8
9
jahr++;
10
}
Ich habs nicht ausprobiert, ich denke es ist nicht so weit daneben.
Man könnte auch sowas machen
1
uint16_tjahr=1970;
2
3
while(day>366){
4
if(schaltjahr(jahr))
5
day-=366;
6
else
7
day-=365;
8
9
jahr++;
10
}
11
12
if(day==366&&schaltjahr(jahr)){
13
day-=366;
14
15
jahr++;
16
}
Also bis auf 366 Tage reduzieren und hinterher entscheiden, ob man noch
1 Jahr gutschreiben muss oder nicht.
Ein bischen besser systematisch testen und die richtigen Schlüsse
ziehen!
Eben. Das Problem lässt sich tabellenorientiert lösen. Die Betrachtung
von Jahren vor 2010 ist irrelevant, und die Schaltjahrbestimmung kann
auch über eine einfache Tabelle gelöst werden.
Die Tabelle enthält für die nächsten 15..20 Jahre die Nummer des ersten
Tages im Jahr. Damit sind gerade mal 15..20 uint16_t-Werte erforderlich.
(wie wahrscheinlich ist denn eine Nutzung des Programmes im Jahr 2030?)
Zur Jahresbestimmung wird also diese Jahrestabelle durchlaufen, bis der
Tage-seit-1970-Wert ins gefundene Jahr passt.
Der gefundene Jahresanfangswert wird abgezogen, und das Resultat ist der
Tag im Jahr.
Anhand der Differenz Jahresanfangswert[aktuelles Jahr] und
Jahresanfangswert[aktuelles Jahr + 1] kann festgestellt werden, ob ein
Schaltjahr vorliegt.
Dann gibt es eine zweite Tabelle, die die Nummer des ersten Tages im
Monat enthält, diese enthält 12 uint16_t-Werte und kann der Einfachheit
halber doppelt ausgeführt werden (mit entsprechender Verschiebung bei
Schaltjahren).
Jan Feb Mär Apr Mai Jun Jul Aug Sep Okt Nov Dez
0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335
Die Bestimmung des Monats erfolgt analog zur Bestimmung des Jahres, es
wird solange die Monatsanfangstabelle durchlaufen, bis der Tag im Jahr
in den gefundenen Monat passt.
Damit sind Monat und Tag im Monat bestimmt.
Nötig sind dazu drei Tabellen und zwei Schleifen.