mikrocontroller.net

Forum: Compiler & IDEs Ein kleines Schleifendurchlaufproblem und ich raffs ned


Autor: Chris Tian (chris0086)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute, ich hab ein Kleines Problem und zwar wird in meiner 
Schleife warscheinlich nicht richtig umgewandelt und dann nicht richtig 
gerechnet.
Hier erstmal der Code:
void USART_readline(char *daten)
   {
  char  NextChar;
     unsigned char DataCntTmp = 0;
     uint16_t NextInt;
     uint16_t Checksumme = 0;
     while (1)
     {
       NextChar = USART_getchar();
       NextInt = atoi(NextChar);



         if (NextInt == Checksumme) /* Hier steht die checksumme am Ende */
         {
           /* Ende des Strings erreicht,
              also Schleife verlassen */
           USART_Transmit(NextChar);

           return;

         }
         else /* Normales Zeichen, anhängen an die Zeichenkette */
         {
           daten[DataCntTmp] = NextChar;
           DataCntTmp++;
           Checksumme = Checksumme + NextInt;
           USART_Transmit(Checksumme);
         }
       }

   }
also die Schleife soll chars empfangen und in ein array speichern, 
leider läuft die Schleife gleich nach dem ersten String durch und wird 
beendet obwohl nach dem ersten Durchgang NextInt != Checksumme sein 
sollte.
Denn wenn ich ihm Hex 45 schicke dann sollte NextInt auf keinen Fall den 
Wert 0 haben weil ihr über atoi(nextchar) ja der Wert 45 zugewiesen wird 
und somit die Schleife nicht durch return verlassen werden.
aber das tut sie offensichtlich. Da nach dem ersten Zeichen die 
Programmausführung auserhalb der Schleife weiter  geht.

Irgendwas haut mit der atoi Funktion nicht hin
NextInt ist nämlich danach immernoch 00 obwohl es 45 sein müsste oder 
auf jeden fall ungleich 0.
Ich hoffe ihr habt mein Problem verstanden und könnt mir helfen

Autor: Jörg G. (joergderxte)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
a) Lies nochmal ganz genau nach, was *atoi()* macht (und warum du da 
eine Warnung vom compiler bekommst)
b) Du bist dir ganz sicher, das die Checksumme einmal in der Nachricht 
vorkommt? (besonders weil du da uint16 mit uint8 vergleichst)
c) Finde noch den Unterschied zwischen 'char', 'char *' und 'char[]' 
heraus.

rtfcbuch, Jörg

Autor: Chris Tian (chris0086)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
zu a)
Prototyp: int atoi ( const char *ntpr);
Wandelt den Anfangsteil einer Zeichenfolge, auf die nptr zeigt, in eine 
int- Zahl um.
zu b)
sind doch beides uint16_t, aber werds in int ändern.
Ja die Checksumme sind einfach alle bytes aufsummiert und die kommt 
irgendwann in der Zeichenkete vor und ist das Endzeichen. Die Zeichen 
die empfangen werden sind alles hex-Ziffern.
zu c)
char ist ein Variablen typ, char[] ist ein array und char * ist ein 
Pointer oder?

Wo liegt jetzt mein Denkfehler ich seh ihn nämlich nicht.

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

Bewertung
0 lesenswert
nicht lesenswert
Christian Hohmann schrieb:
> zu a)
> Prototyp: int atoi ( const char *ntpr);
> Wandelt den Anfangsteil einer Zeichenfolge, auf die nptr zeigt, in eine
> int- Zahl um.

Exakt.
Und jetzt schaun wir mal was du machst
NextInt = atoi(NextChar);

Welchen Datentyp hat NextChar?
In deiner Beschreibung sprichst du von einer Zeichenfolge. Ist NextChar 
eine Zeichenfolge? Kann es aufgrund seines Datentyps überhaupt eine 
Zeichenfolge sein?

Autor: Chris Tian (chris0086)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ist vom typ char, also brauch ich da irgendwie einen pointer oder wie 
sieht das aus?

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

Bewertung
0 lesenswert
nicht lesenswert
PS: Das ganze Protokoll sieht seltsam aus.
Da werden solange Zeichen empfangen, bis sich mit dem nächsten Byte die 
Checksumme ergibt, die als erstes übertragen wurde. Irgendwie kommt mir 
das schon sehr restriktiv vor. Da stelle ich mir das Generieren eines 
beliebigen Datensatzes schon teuflisch schwer vor. Wenn sich zufällig in 
den Daten das richtige byte an der richtigen Stelle befindet, dann kann 
es durchaus vorkommen, dass die Checksumme schon vor Ende des 
Datensatzes bereits erreicht ist und die Leseroutine bricht vorzeitig 
ab.

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

Bewertung
0 lesenswert
nicht lesenswert
Christian Hohmann schrieb:
> ist vom typ char, also brauch ich da irgendwie einen pointer oder wie
> sieht das aus?

atoi will einen String haben!
Du hast keinen String. Du hast ein einzelnes Zeichen!
Ergo: atoi ist das falsche Werkzeug.

http://www.mikrocontroller.net/articles/FAQ#Wie_fu...

(Und das ist nur ein klitzekleiner Auszug aus dem was man wissen muss um 
in C Stringverarbeitung zu machen. Der ganze auch noch wichtige Rest 
findet sich in jedem noch so grindigen C-Buch)

Autor: Chris Tian (chris0086)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nicht ganz richtig.
Mit Checksumme = Checksumme + NextInt; wird ja immer das folgende Byte 
zur Checksumme hinzuaddiert.
So sieht eine Anweisung aus die der MC empfangen und (vorerst) speichern 
soll:
4D4105530001000200E9

E9 ist die Checksumme alle Bytes aufaddiert...

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

Bewertung
0 lesenswert
nicht lesenswert
Christian Hohmann schrieb:
> nicht ganz richtig.
> Mit Checksumme = Checksumme + NextInt; wird ja immer das folgende Byte
> zur Checksumme hinzuaddiert.
> So sieht eine Anweisung aus die der MC empfangen und (vorerst) speichern
> soll:
> 4D4105530001000200E9
>
> E9 ist die Checksumme alle Bytes aufaddiert...

Ah. ok.
Aber das macht es auch nicht besser. Eher sogar schlimmer.

Autor: Chris Tian (chris0086)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie würdest du es machen wenn ich fragen darf?
An den Zeichenketten die der MC empfängt kann ich nix ändern die kommen 
von einer Steuerung. aber ich brauch diese hexwerte in einem Array 
sodass ich auf jedes einzelne zugreifen kann.
Das ist natürlich jetzt nicht alles in der Funktion aber ich will mich 
herantasten und und wenn das eine funktioniert will ich zum nächsten 
gehen. deswegen auch der schlechte code...

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

Bewertung
0 lesenswert
nicht lesenswert
Christian Hohmann schrieb:

> An den Zeichenketten die der MC empfängt kann ich nix ändern die kommen
> von einer Steuerung.

Aber diese Steuerung wird ja wohl eine Protokollbeschreibung haben. Ich 
will einfach nicht glauben, dass die Protokollbeschreibung lautet: Lies 
solange dahin, bis die Summe der Bytes mit dem empfangenen Byte 
übereinstimmt.
Wenn dem tatsächlich so ist, sollte man dem der die Steuerung gemacht 
hat mal mit dem nassen Fetzen aufsuchen.

Angenommen die zu übertragenden Daten wären:

4D4105930001000200

Du rechnest du jetzt noch eine schöne Checksumme aus und hängst sie 
hinten drann.
Aber dein Lesecode
4D  ist noch ok.   Checksumme bisher 4D
41  auch noch ok.  Checksumme bisher 8E
05  auch noch ok.  Checksumme bisher 93
93 oops. Das ist identisch zur bisherigen Checksumme, woraufhin deine 
Leseroutine den Datensatz als beendet erklärt :-)

Autor: Chris Tian (chris0086)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das Protokoll der Steuerung ist nicht offen aber ich hab dir noch etwas 
unterschlagen, hab ich glatt vergessen.
Das dritte byte gibt die länge der nachfolgenden Zeichen ohne Checksumme 
an also bei
4D4105530001000200E9

4D41 Steurkommandos
05 anzahl der nachfolgenden Zeichen ohne checksumme
5300010002 Nutzzeichen
00E9 Checksumme( tut mir leid sind 2 bytes)+ich hoffe jetzt wirds besser 
das ist jetzt aber alles

wurde alles durch probieren mit terminalprogramm und nem Delphi programm 
rausgefunden, ( da bin ich mehr firm drin)

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

Bewertung
0 lesenswert
nicht lesenswert
Christian Hohmann schrieb:
> Das Protokoll der Steuerung ist nicht offen aber ich hab dir noch etwas
> unterschlagen, hab ich glatt vergessen.
> Das dritte byte gibt die länge der nachfolgenden Zeichen ohne Checksumme
> an

Ah, Na also.
Dann mach deine Schleife über diese Anzahl und benutze die Checksumme 
danach um zu kontrollieren, ob die Übertragung richtig war.

> 00E9 Checksumme( tut mir leid sind 2 bytes)+ich hoffe jetzt wirds besser
> das ist jetzt aber alles

Und als Zahl kriegst du die so

  Checksumme = Byte1 * 256 + Byte2;

und benutze unbedingt unsigned char (oder uint8_t) für die Bytes.

Autor: Chris Tian (chris0086)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok ich schau mal ob ichs hinbekomme, danke erstmal für deine Hilfe aber 
jetzt geh ich erstmal das Bett aufsuchen. Danke Vielmals

Autor: Chris Tian (chris0086)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kannst du mir das mit der Checksumme am obigen Beispiel nochmal 
erklären? komm da nicht auf 00E9 wenn ich die ersten beiden bytes 
nehme...

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

Bewertung
0 lesenswert
nicht lesenswert
Punkt 1:
  wenn du es mit Bytes zu tun hast, dann ist unsigned char (oder
  uint8_t) der Datentyp der Wahl

Punkt 2:
  In C ist ein char (bzw. signed char bzw. unsigned char) im Grunde
  auch nur ein Integer, mit dem man genauso rechnen kann, wie mit
  allem anderen. Das ist anders als in den meisten anderen
  Programmiersprachen, bei denen ein Character ausschliesslich
  zur Speicherung und Verarbeitung von tatsächlichen ASCII-Zeichen
  reserviert ist.

Hast du also 2 Bytes

  uint8_t Byte1 = 0xDE;
  uint8_t Byte2 = 0x89;

dann kannst du die beiden zu einem uint16_t zusammensetzen:

  uint16_t Wert = Byte1 * 256 + Byte2;

oder was gleichwertig ist:

  uint16_t Wert = ( Byte1 << 8 ) | Byte2;

(Beides wird vom Compiler höchst wahrscheinlich gleich übersetzt, da 
alles unsigned ist und die Multiplikation eine Operation mit einer 2-er 
Potenz darstellt).

Wert enthält dann 0xDE89

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

Bewertung
0 lesenswert
nicht lesenswert
So ungefähr würde ich die Funktion ansetzen:
unsigned char USART_readcommand(char *command, unsigned char *daten)
{
  unsigned char  NextByte;
  unsigned char  Len;
  unsigned char  i;
  unsigned int   CheckSummCalc;
  unsigend int   CheckSummRead;

  command[0] = USART_getchar();   // CommandoByte 1
  command[1] = USART_getchar();   // CommandoByte 2

  // ev. einen String aus den Commandobytes machen, die sehen
  // wie sinnvolle ASCII Codes aus
  command[2] = '\0';               

  // ev. hier prüfen, ob das Commando gültig ist
  // if( strcmp( command, "MA" ) != 0 )   // alles ausser MA ist nicht gültig
  //   return FALSE;

  // Anzahl der Datenbytes lesen
  Len = USART_getchar();

  // Jetzt kommen die Datenbytes
  CheckSummCalc = 0;
  for( i = 0; i < Len; ++i )
  {
    NextByte = USART_getchar();

    CheckSummCalc += NextByte;
    daten[i] = NextByte;
  }

  // Daten sind gelesen. Jetzt kommen noch 2 Bytes Checksumme
  CheckSummRead = USART_getchar();
  CheckSummRead = ( CheckSummRead << 8 ) + USART_getchar();

  // Wenn die übertragene Checksumme nicht mit der selbst berechneten
  // übereinstimmt, dann ist irgendwo ein Fehler passiert
  if( CheckSummRead != CheckSummCalc )
    return FALSE;

  return TRUE;
}

Welche Bytes genau in die empfängerseitige Checksummenberechnung 
einfliessen, musst du dir noch ansehen.

Autor: Chris Tian (chris0086)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hm sieht eigentlich gut aus aber das mit der Checksumme stimmt irgendwie 
nicht, er gibt jedenfalls immer false zurück wenn ich ihm 
4D4105530001000200E9 schicke...

Wenn ich mir die Checksumme ausgeben lasse:
CheckSummRead = USART_getchar();
  CheckSummRead = ( CheckSummRead << 8 ) + USART_getchar();

  if( CheckSummRead != CheckSummCalc )
    USART_Transmit(CheckSummCalc);
    return 0;

  return 1;
}
steht Hex 56 drin.

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

Bewertung
0 lesenswert
nicht lesenswert
Christian Hohmann schrieb:
> hm sieht eigentlich gut aus aber das mit der Checksumme stimmt irgendwie
> nicht, er gibt jedenfalls immer false zurück wenn ich ihm
> 4D4105530001000200E9 schicke...
>
> Wenn ich mir die Checksumme ausgeben lasse:
>
> CheckSummRead = USART_getchar();
>   CheckSummRead = ( CheckSummRead << 8 ) + USART_getchar();
> 
>   if( CheckSummRead != CheckSummCalc )
>     USART_Transmit(CheckSummCalc);
>     return 0;
> 
>   return 1;
> }
> 
> steht Hex 56 drin.

Ich sagte doch, dass du noch kontrollieren musst, welche Bytes in die 
Checksummenberechnung einfliessen müssen.

Wenn du den Code ansiehst, habe ich nur die Datenbytes in die Berechnung 
mit eingehen lassen:

4D 41 05 53 00 01 00 02 00 E9
   0x53 + 0x00 + 0x01 + 0x00 + 0x02   ergibt 0x56

Aber anscheinend werden KommandoBytes und Länge auch mit eingerechnet, 
da

0x4D + 0x41 + 0x05 + 0x53 + 0x00 + 0x01 + 0x00 + 0x02 = 0xE9

das richtige Ergebnis ergibt.

Diese Änderung im Code wirst du doch wohl noch alleine hinkriegen.

Autor: Chris Tian (chris0086)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ah ok habs noch geändet und funzt jetzt DANKE Dir , jetzt kann ich mich 
an die nächsten Probleme wagen...

Autor: Chris Tian (chris0086)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und ich hab ein weiteres Problem:
Also hab ein GrafikDisplay am Controller hängen was mir die Daten 
anzeigt die die eigentliche Steuerung an den Controller sendet.
Bei trockenübungen mit Kommandos vom PC klappt auch alles aber wenn ich 
den Controller an die Steuerung anschließe dann rattern die Daten so 
schnell rüber das ich nichts auf dem Display erkennen kann da ständig 
neue Sachen angezeigt werden, also die Daten kommen zu schnell rüber 
weil der MC die Quittierungsstrings so shcnell sendet, ich bräuchte 
jetzt eine Verzögerung für die Quittierungsstrings, von sagen wir mal 1 
Sekunde.
Wie kann man das am schnellesten und einfachsten machen?
Habe das mit den Timern gelesen nur habe ich damit noch nix gemacht,
oder kann man auch immer ne schleife zählen lassen bis 100000 damit er 
beschäftigt ist?  Wär aber bestimmt quick and dirty
Hier mal noch mein Code zum Antwortstring und Anzeige auf Display falls 
gewünscht:
//Sonst hier weiter: Antwortstring generieren und senden

     //Kommando für Temperaturwerte schicken (nur einmal)
          if(TempKommando == 0 && Steuerdaten[1] == 31)
          {
            TempKommando = Tempanfordern();
            goto Kommunikation;
          }

     Steuerdatenalt[0]=Steuerdaten[0];
     Steuerdatenalt[1]=Steuerdaten[1];
     Steuerdaten[5]= Steuerdaten[0]+Steuerdaten[1]+2;

     for(zaehler=0; zaehler<=5 ;zaehler++)
       {
         USART_Transmit(Steuerdaten[zaehler]);


       }
     //Anzeige der Nutzdaten auf LCD

   wait_while_chip_is_busy();
   if(zeile >= 64)
   {
     zeile = 0;
     lcd_clear();
   }
     lcd_set_cursor(0,zeile);

     for(zaehler=0;zaehler<=Datenlaenge;zaehler++)
     {
       lcd_putc(small_font,Nutzdaten[zaehler]);
       wait_while_chip_is_busy();
       lcd_set_cursor(zaehler*5,zeile);
       wait_while_chip_is_busy();
     }
     zeile+=8;
     //Anzeige Ende

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

Bewertung
0 lesenswert
nicht lesenswert
Dein Hauptproblem ist die Unsitte, den Schirm ständig löschen zu müssen. 
Das ist erstens langsam und führt zweitens bei schnellen Datenänderungen 
zu flackern bzw. dazu, dass man überhaupt nichts mehr lesen kann.

Entscheide dich wo am Schirm Daten dargestellt werden und schreibe 
dorthin ohne jedesmal den Schirm komplett zu löschen. Daten sollen sich 
überschreiben und nicht vorher gelöscht werden müssen. Bei schnellen 
Datenänderungen kann man dann zwar ebenfalls nicht viel lesen, aber 
sobald sich der erhaltene Wert stabilisiert hat man dann ein wunderbar 
stehendes Bild, bei dem sich der angezeigte Wert ab und zu mal ohne 
Zeitverzug ändert.

Aber wenn du eine Quick&Dirty Warterei brauchst ....

http://www.mikrocontroller.net/articles/AVR-GCC-Tu...

#include <util/delay.h>

...

  _delay_ms( 1000 );    // 1000 Millisekunden = 1 Sekunde

Autor: Chris Tian (chris0086)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jetzt hab ich mal ne Frage nachdem mein Controller nicht mit der 
Steuerung reden will.
Kann ich über die isp Schnittstelle sehen was auf der Seriellen 
Schnittstelle geschrieben wird?
Hab ein mysmart usb programmer, wär nicht schlecht weil ich ned weis ob 
die Steuerung was zurück sendet, weil mit dem Pc funktionierts aber mit 
dem controller nicht...
Wenn man das direkt anzeigen lassen könnte wär das nicht schlecht

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

Bewertung
0 lesenswert
nicht lesenswert
Christian Hohmann schrieb:
> Jetzt hab ich mal ne Frage nachdem mein Controller nicht mit der
> Steuerung reden will.
> Kann ich über die isp Schnittstelle sehen was auf der Seriellen
> Schnittstelle geschrieben wird?
> Hab ein mysmart usb programmer, wär nicht schlecht weil ich ned weis ob
> die Steuerung was zurück sendet, weil mit dem Pc funktionierts aber mit
> dem controller nicht...
> Wenn man das direkt anzeigen lassen könnte wär das nicht schlecht

Du musst deine Teststrategien noch verfeinern.

Bei so etwas benutzt man den PC zum Testen von beidem

* zuerst kommt die Steuerung an den PC und mit einem Terminalprogramm
  'spielt' man ein wenig mit der Steuerung und sieht sich an, was sie
  so sendet und ob/wie sie auf Kommandos reagiert

* dann kommt der µC an den PC und mit sieht wieder im Terminalprogramm
  nach, wie der µC reagiert wenn man ihm die Steuerung über das
  Terminalprogramm vorgaukelt und ob er die richtigen Kommandos
  sendet

und erst dann verbindet man Steuerung und µC und da beide Komponenten 
unabhängig voneinander ihre Funktionstüchtigkeit gezeigt haben und in 
ihrem Verhalten bekannt sind und aufeinander abgestimmt wurden wird die 
Kommunikation auf Anhieb klappen. Zudem hat man mit der 'erst mal beide 
an den PC' Methode auch verifiziert, ob die physikalischen Parameter 
sowohl der Steuerung als auch des µC stimmen (Baudrate, Handshake, 
sonstige Einstellungen)

Autor: Chris Tian (chris0086)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hab ich ja eigentlich alles gemacht, ich arbeite mit nem usb zu seriell 
wandler und dem Programm hterm. Habe das Gefühl das wenn ich den PC an 
der Steuerung habe nur die Hälfte des Strings angezeigt wird und beim 
nächsten string der Rest des Vorherigen, das ist mir mit dem Lappi 
eigentlich erstmal egal da ich eh den gleichen Antwortstring zurück 
sende, aber der MC weis das ja ned und er kommt ´mit seiner Checksumme 
durcheinander und macht ned weiter.
Wie ist das eigentlich mit dem Empfangspuffer des MC macht der wenn noch 
daten im empfangspuffer liegen trotzdem mit seinem Programm weiter oder 
muss ich sicherstellen das dieser leer ist bevor er weiter im Programm 
geht?

Ich musss das nochmal mit der Steuerung mit nem pc mit richtiger 
serieller Schnittstelle probieren, wie da die Daten nun kommen.

Autor: Christian Hohmann (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So ich habe jetzt mal meinen pc mit dran gehängt um zu sehen ob die 
Kommunikation zwischen den beiden klappt, aber ich hab jetzt ein Problem 
wie ich die erste antwort der steuerung verarbeiten soll:
Also folgendes:
ICh schicke initialisierungskommando:
52 61 01 01 00 B5 (Ra)
darauf antowrtet die Steurung aber mit gleich 2 Befehlen hinterienander:
52 61 01 01 00 B5     4D 41 05 53 00 01 00 02 00 E9 (Ra...) und (MA...)
jetzt schreibt die mir natürlich den eingangsbuffer vom controller voll 
mit dem ersten Befehl den ich eigenlich ignorieren kann und nur am 2ten 
interessiert bin , später werden auch nur immer ein Befehl gesendet aber 
bei der initialiserung ist eben dieser blöde befehl davor gesetzt.
Wie kann ich dem Controller am einfachsten sagen das er die ersten 5 
Zeichen ignorieren soll, das er das aber nur einmal tun soll?
Hier nochmal mein leider wieder etwas wild gewordener Quellcode:
//Daten empfangen Routine
unsigned char USART_readcommand(unsigned char *Nutzdaten, char *Steuerdaten, int h)
{
  unsigned char  NextByte;
  unsigned char  Len;
  unsigned int   i;
  unsigned int   CheckSummCalc;
  unsigned int   CheckSummRead;
  CheckSummCalc = 0;
  Steuerdaten[0] = USART_getchar();   // CommandoByte 1
  CheckSummCalc += Steuerdaten[0];
  Steuerdaten[1] = USART_getchar();   // CommandoByte 2
  CheckSummCalc += Steuerdaten[1];


  // Anzahl der Datenbytes lesen
  Len = USART_getchar();
  CheckSummCalc += Len;
  // Jetzt kommen die Datenbytes
  /*
                    lcd_clear();
                    lcd_set_cursor(0,0);
                    wait_while_chip_is_busy();
                    */
  for( i = 0; i < Len; ++i )
  {
    NextByte = USART_getchar();
    CheckSummCalc += NextByte;
    Nutzdaten[i] = NextByte;
/*

                    lcd_set_cursor(i*5,1);
                    lcd_putc(small_font,Nutzdaten[i]);
                    wait_while_chip_is_busy();
*/
  }

  // Daten sind gelesen. Jetzt kommen noch 2 Bytes Checksumme
  CheckSummRead = USART_getchar();
  CheckSummRead = ( CheckSummRead << 8 ) + USART_getchar();
  if(h==0)
  {
  Steuerdaten[0] = USART_getchar();
  Steuerdaten[1] = USART_getchar();
  }
  h=1;

  if( CheckSummRead != CheckSummCalc )
  {

    return 0;
  }
  return Len;
}

//Funktion Temperatur anfordern
unsigned char Tempanfordern()
{
  unsigned int j;
  unsigned char Tempstring[8];
  Tempstring[0]=0X52;
  Tempstring[1]=0X62;
  Tempstring[2]=0X03;
  Tempstring[3]=0X00;
  Tempstring[4]=0X00;
  Tempstring[5]=0X01;
  Tempstring[6]=0X00;
  Tempstring[7]=0XB8;
  for(j=0; j<=7 ;j++)
    {
      USART_Transmit(Tempstring[j]);

    }
  return 1;
}



int main(void)
{
    UCSRB |= (1<<TXEN);                // UART TX einschalten
    UCSRB |= (1<<RXEN);
    UCSRC |= (1<<URSEL)|(3<<UCSZ0);    // Asynchron 8N1

    UBRRH = UBRR_VAL >> 8;
    UBRRL = UBRR_VAL & 0xFF;


    // LCD Initialisieren

            lcd_init();
            lcd_clear();

    while (!bit_is_set(UCSRA, UDRE))
  ;
//Globale Daten:
  char Steuerdaten[8];
  char Steuerdatenalt[2];
  int zaehler;
  int TempKommando = 0;
  int h =0;
    unsigned char Nutzdaten[60];
    for(zaehler=0;zaehler<60;zaehler++)
    {
      Nutzdaten[zaehler]='\0';
    }

    uint16_t Datenlaenge = 0;
    int zeile = 0;

//Initialisierungsstring senden:

  Steuerdaten[0]=0X52;
  Steuerdatenalt[0]=0X52;
  Steuerdaten[1]=0X61;
  Steuerdatenalt[1]=0X52;
  Steuerdaten[2]=0X03;
  Steuerdaten[3]=0X00;
  Steuerdaten[4]=0X00;
  Steuerdaten[5]=0X01;
  Steuerdaten[6]=0X00;
  Steuerdaten[7]=0XB7;
  for(zaehler=0; zaehler<=7 ;zaehler++)
  {
    USART_Transmit(Steuerdaten[zaehler]);

  }

  /*Steuerdaten[0]=0X4D;
  Steuerdaten[1]=0X41;
  Steuerdaten[2]=0X01;
  Steuerdaten[3]=0X01;
  Steuerdaten[4]=0X00;
  Steuerdaten[5]=0X90;

    for(zaehler=0; zaehler<=5 ;zaehler++)
    {
      USART_Transmit(Steuerdaten[zaehler]);

    }
*/
//Initialisierung Ende



//Daten empfangen und Bestätigungskommando schicken
Kommunikation:
     Datenlaenge = USART_readcommand(Nutzdaten, Steuerdaten,h);
    /* while(Datenlaenge == 0)  //Wenn Checksumme nicht übereinstimmt, nochmal senden
     {
       USART_Transmit(66);
       char CheckSummealt;
       CheckSummealt=Steuerdatenalt[0]+Steuerdatenalt[1]+0X01+0X01;
       for(zaehler=0; zaehler<2 ;zaehler++)
         {

           USART_Transmit(Steuerdatenalt[zaehler]);
         }

       for(zaehler=2; zaehler<=4 ;zaehler++)
          {

        USART_Transmit(Steuerdaten[zaehler]);
          }
       USART_Transmit(CheckSummealt);
       Datenlaenge = USART_readcommand(Nutzdaten, Steuerdaten,h);
     }
*/
     //Sonst hier weiter: Antwortstring generieren und senden


     //Kommando für Temperaturwerte schicken (nur einmal)
          if(TempKommando == 0 && Steuerdaten[1] == 31)
          {
            TempKommando = Tempanfordern();
            goto Kommunikation;
          }

     Steuerdatenalt[0]=Steuerdaten[0];
     Steuerdatenalt[1]=Steuerdaten[1];
     Steuerdaten[5]= Steuerdaten[0]+Steuerdaten[1]+2;

     for(zaehler=0; zaehler<=5 ;zaehler++)
       {
         USART_Transmit(Steuerdaten[zaehler]);


       }
     //Anzeige der Nutzdaten auf LCD

             wait_while_chip_is_busy();
             if(zeile >= 64)
             {
               zeile = 0;
               lcd_clear();
             }
               lcd_set_cursor(0,zeile);

               for(zaehler=0;zaehler<=5;zaehler++)
               {
                 lcd_putc(small_font,Steuerdaten[zaehler]);
                 wait_while_chip_is_busy();
                 lcd_set_cursor(zaehler*5,zeile);
                 wait_while_chip_is_busy();
               }
               zeile+=8;
               _delay_ms( 100 );  //mal ein bisschen warten
               //Anzeige Ende

     goto Kommunikation;
[

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.