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 Ok ja klar Danke Hier ist meine Tages berechnung seit 1.1.1970 habe natürlcih jetzt die Schaltjahre drin uint8_t schaltjahr_berechnen(uint16_t jahr) { if ( ( (jahr%4==0) && (jahr%100!=0) ) || (jahr%400==0) ) { return 1; } else { return 0; } } unsigned int daysumm=0; for (int i=1970;i<year;i++) { if(schaltjahr_berechnen(i)==1) { daysumm+=366; } else { daysumm+=365; } } if(month==1 || month>1)daysumm+=31; if(month==2 || month>2) { if(schaltjahr_berechnen(year)==1) { daysumm+=(29); } else { daysumm+=(28); } } if(month==3 || month>3)daysumm+=31; if(month==4 || month>4)daysumm+=30; if(month==5 || month>5)daysumm+=31; if(month==6 || month>6)daysumm+=30; if(month==7 || month>7)daysumm+=31; if(month==8 || month>8)daysumm+=31; if(month==9 || month>9)daysumm+=30; if(month==10 || month>10)daysumm+=31; if(month==11 || month>11)daysumm+=30; if(month==12)daysumm+=day; Ergebnis =14960 Tage.
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_t s=0,jahr=1970; |
2 | s=(int)day/365; |
3 | for(int i=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_t jahr = 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_t jahr = 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_t jahr = 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!
Wie wärs wenn Du ab 1.1.2010 +(const Tage_1.1.1970-31.12.2009 = 14609) zählst ? Dann kommt das Problem mit dem Schaltjahr später :-)
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.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.