mikrocontroller.net

Forum: Compiler & IDEs Betriebssunden Zähler


Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
hab da mal wieder ein Rechen Problem das ich nicht gelöst bekomme. Ich 
habe einen Zähler der in 4 Byte die Betriebsstunden in Sekunden zählt. 
Die 4 Byte übertrage ich mit dem UART und möchte sie nun in HHHH:MM:SS 
anzeigen. Der Code ist nur der Anfang, aber das zusammensetzen der 4 
Byte zu einer 32-Bit Zahl geht schon nicht und die restliche Berechnung 
stimmt auch nicht. Ich hoffe Ihr könnt mir helfen, vielen Dank schon mal 
im Voraus.

  uint8_t x,z;
  uint16_t s,t;
  uint32_t u;

  if (UART.NEU_BEF)       // Neue Daten empfangen
  {
    Write_LCD (0xC6,0);  // Setze Cursor auf 2.Zeile 5.Stelle
    u = (UART_BYTE_EIN[5] << 24) | (UART_BYTE_EIN[4] << 16) | \
        (UART_BYTE_EIN[3] << 8) | UART_BYTE_EIN[2];
    t = u / 3600;
    x = t / 1000;
    x = x + 0x30;
    Write_LCD (x,1);

    s = t % 1000;
    x = s / 100;
    x = x + 0x30;
    Write_LCD (x,1);

    z = s % 100;
    x = z / 10;
    x = x + 0x30;
    Write_LCD (x,1);

    x = z % 10;
    x = x + 0x30;
    Write_LCD (x,1);

    Write_LCD (':',1);
  }

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernd wrote:

>     u = (UART_BYTE_EIN[5] << 24) | (UART_BYTE_EIN[4] << 16) | \

                                                                ^
                                        was soll den das hier sein
 Ein Fortsetzungszeichen in der letzten Spalte braucht man nur bei
Makros, sprich: wenn der Präprozessor zum Einsatz hommt.


>         (UART_BYTE_EIN[3] << 8) | UART_BYTE_EIN[2];

    u = ((uint32_t)UART_BYTE_EIN[5] << 24) |
        ((uint32_t)UART_BYTE_EIN[4] << 16) |
        ((uint16_t)UART_BYTE_EIN[3] << 8) |
         UART_BYTE_EIN[2];

Grundregel: In C werden alle Ausdrücke grundsätzlich im
Datenbereich int (beim WinAvr also: 16 Bit) ausgeführt, es
sei denn einer der beiden Operanden hat einen 'höheren'
Datentyp.
      UART_BYTE_EIN[5]  ist (vermutlich) ein Byte, also uint8_t
      24                ist definitiv ein int

also wird   UART_BYTE_EIN[5]  als int-Berechnung durchgeführt.
Einen 16 Bit um 24 Stellen nach links verschieben, gibt aber
auf jeden Fall 0, weil alle relevanten Bits links herausfallen.

Autor: Bernd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank Karl Heinz,

hat wunderbar geklappt. Die Definition von Variablen stellt mich immer 
vor größte Probleme. Habe vorher nur in Assembler Programmiert und das 
ist doch eine große Umstellung auf C. In meine C-Buch steht halt “Ein 
Rückstrich (Backslash \) am ende einer Zeile bedeutet eine Fortsetzung 
der Eingabe auf der nächsten Zeile.“ Also gleich 2 mal dazu gelernt.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bernd wrote:
> ist doch eine große Umstellung auf C. In meine C-Buch steht halt “Ein
> Rückstrich (Backslash \) am ende einer Zeile bedeutet eine Fortsetzung
> der Eingabe auf der nächsten Zeile.“

Aber nur beim Präprozessor

#define MAX(a,b)  (a) < (b)   \
                  :           \
                     (b)      \
                  ?           \
                     (a)

dort braucht man es um dem Präprozessor mitzuteilen: Die nächste
Zeile gehört auch noch dazu.

Ansonsten wird in C alles andere, Tabulatoren, mehrere Leerzeichen
hintereinander, Zeilenumbruch, Kommentare, wie ein einziges
Leerzeichen behandelt: Es dient zum Trennen der einzelnen
Schlüsselwörter, sofern sich aus den restlichen Sonderzeichen
gemäss Syntax nicht sowieso eine Trennung ergibt.

Ob du schreibst:
int main()
{
  int i = 5;
}

oder
int
main(
)
{
                  int
   i =  /* */
5
     ;
}

ist dem Compiler völlig egal. Er sieht nur die Sequenz
Schlüsselwort/int
Name_der_Funktion/main
öffnende_Klammer
schliessende_Klammer
öffnende_geschweifte_Klammer
Schlüsselwort/int
Name_einer_Variablen
Zuweisungszeichen
Zahl/5
Semikolon
schliessende_geschweifte_Klammer

und baut aus dieser sequenzierten Darstellung seine intern
zu übersetzende Programmstruktur zusammen.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> ist doch eine große Umstellung auf C. In meine C-Buch steht halt “Ein
>> Rückstrich (Backslash \) am ende einer Zeile bedeutet eine Fortsetzung
>> der Eingabe auf der nächsten Zeile.“
>
> Aber nur beim Präprozessor

Naja, der Präprozessor ist der Teil, der die Bearbeitung macht, aber 
gelten tut das überall, nicht nur in #defines. Zum Beispiel geht auch 
folgendes:
#include <stdio.h>
int main()
{
    puts("Hello \
world");
    return 0;
}

Oder sogar:
#include <stdio.h>
int testvariable = 5;

int main()
{
    printf("%d", test\
variable);
    return 0;
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus wrote:
> Naja, der Präprozessor ist der Teil, der die Bearbeitung macht, aber
> gelten tut das überall, nicht nur in #defines. Zum Beispiel geht auch
> folgendes:

Wow.
Das wusste ich wirklich noch nicht!

Merci.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>     puts("Hello \
> world");

Dafür gibt es eine deutlich elegantere Lösung:

   puts("Hello "
      "world");

Zwei Stringkonstanten, die ohne Operator aufeinander folgen werden vom 
Compiler concateniert.

Kommentare dürfen dazwischen stehen, denn die werden vom Preprozessor 
weggeworfen, bevor der Compiler sie sieht.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Uhu Uhuhu wrote:

> Dafür gibt es eine deutlich elegantere Lösung:

Es ging ja aber um die Demonstration, was die Folge
backslash-newline genau macht.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:
> Es ging ja aber um die Demonstration, was die Folge
> backslash-newline genau macht.

Die Chose mit dem Backslash hat leider erhebliche Tücken: Man sieht ihr
nicht so ohne weiteres an, ob das NL escaped wurde, oder nur ein Blank.

Ich rate von diesem Klimmzug ab - er ist ein Überbleibsel aus dden ganz
frühen C-Zeiten, den man vermutlich aus Kompatibilitätsgründen nicht
rausgeschmissen hat. Den Rausschmiß verdient hat er allemal.

Nachtrag: Genau genommen ist es eine Funktion des CPP, der escapte NLs 
einfach wegschmeißt.

Beheben könnte man das dadurch, daß man den CPP so ändert, daß er den \ 
am Zeilenende nur dann bearbeitet, wenn er in einer 
Preprozessoranweisung steht.

Autor: Rolf Magnus (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Die Chose mit dem Backslash hat leider erhebliche Tücken: Man sieht ihr
> nicht so ohne weiteres an, ob das NL escaped wurde, oder nur ein Blank.

Kommt auf den Editor an. Die, die ich kenne, können überflüssige 
Blank-Zeichen am Ende einer Zeile optisch markieren, und am 
Syntaxhighlighting sehe ich in der Regel auch, ob der Zeilenumbruch 
escaped ist.

> Ich rate von diesem Klimmzug ab - er ist ein Überbleibsel aus dden ganz
> frühen C-Zeiten, den man vermutlich aus Kompatibilitätsgründen nicht
> rausgeschmissen hat. Den Rausschmiß verdient hat er allemal.

Wie Jörg schon schrieb: Ich wollte damit nicht sagen, daß man es 
außerhalb von Makros einsetzen sollte, sondern nur, daß es theoretisch 
möglich ist. Ich wollte halt auch mal mehr wissen als Karl Heinz ;-)

> Beheben könnte man das dadurch, daß man den CPP so ändert, daß er den \
> am Zeilenende nur dann bearbeitet, wenn er in einer
> Preprozessoranweisung steht.

Beheben? Ich sehe kein Problem, das man beheben müßte. Wenn du es 
(berechtigterweise) außerhalb von Makro-Definitionen nicht nutzen 
willst, dann nutze es dort einfach nicht.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rolf Magnus wrote:

>> Die Chose mit dem Backslash hat leider erhebliche Tücken: Man sieht ihr
>> nicht so ohne weiteres an, ob das NL escaped wurde, oder nur ein Blank.

> Kommt auf den Editor an. Die, die ich kenne, können überflüssige
> Blank-Zeichen am Ende einer Zeile optisch markieren, ...

Macht meiner auch, und ich bin immer wieder irgendwas zwischen
überrascht und entsetzt, wie viele Leute da ihren ,,Datenmüll''
am Zeilenende liegen lassen.

Wer natürlich ein Leerzeichen mit einem Backslash versieht, gehört
sowieso erschlagen.

Autor: Uhu Uhuhu (uhu)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Richtig gute Editoren geben dem Benutzer die Möglichkeit zu 
konfigurieren, was mit Leerzeichen am Zeilenende passieren soll.

Einem reinen C/C++-Editor würde ich u.U. noch durchgehen lassen, Blanks 
am Ende immer automatisch wegzuschmeißen. Für Universal-Editoren ist das 
nicht sinnvoll.

> Wer natürlich ein Leerzeichen mit einem Backslash versieht, gehört
> sowieso erschlagen.

Sowas passiert zuweilen schneller, als man denkt; copy&paste ist ein 
sehr gutes Vehikel, solche Effekte mal eben schnell zusammenzuklicken.

Aber deswegen den armen Kerl gleich erschlagen?

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Spruch bei uns auf Arbeit heißt nicht umsonst: "Copy, paste, and 
die."

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.