Forum: Mikrocontroller und Digitale Elektronik [AVR][ATMega328] UART Receive und Echo mit Fleury Lib


von S. G. (goeck)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

nach einigen Tagen des Rumexperimentierens sehe ich mich gezwungen, mein 
Problem hier zu schildern, in der Hoffnung, jemand hat einen wertvollen 
Tipp für mich. Ich schlage mich mit einem ATMega328 und der 
aktualisiertenUART Library von Peter Fleury herum, die hier zu beziehen 
ist: http://beaststwo.org/avr-uart/index.shtml .

Zusätzlich habe ich eine Funktion, die eine String einlesen soll und ein 
Gerät am UART hängen, dass stumpfsinnig zyklisch Messwerte verschickt 
(mit 19200 8N2) und diese Strings sind immer 16Byte lang, beginnen mit 
0x96 und enden mit 0x8D.

Mein gestrippter Code ist befindet sich im Amhang.

Ich lasse mir nun den kompletten eingelesenen String einmal 
zurückschicken, also ein Echo ausgeben. Dort sehe ich, dass etweas nicht 
stimmt. Ist ein Byte 0x00 wird es generell nie so zurückgegeben, 
zwischendrin, am Anfang und manchmal auch am Ende fehlen einzelne Bytes 
im Echo. Die Verteilung, welche Bytes jedesmal fehlen, scheint mir 
zufällig. Beispielhaft habe ich einen Logic Screenshot 
angehängt(grün=ATMega_RX, rot=ATMega_TX) . Ich habe bereits verschiedene 
Implementationen von uart_gets() aus dem Forum probiert (siehe Code) und 
auch ein blockierendes uart_getc() versucht, anstatt das nciht 
blockierende von Fleury, kein Erfolg...lediglich die Charakteristik der 
zurückgesendeten Fehler ändert sich (mal mehr mal weniger fehlende 
Bytes, je nach Implementierung).

Der Atmega läuft mit einem 16Mhz Quarz, CKDIV8 ist nicht gesetzt. Fuses 
sind: Ext:0xFF H:0xD9 L:0xFF.

Ich weiß mir so langsam keinen Rat mehr. Es kann doch kein Hexenwerk 
sein, dass die UART Kommunikation auf 19200Baud klappt?!?!

Bin sehr dankbar für jeden ernst gemeinten Hinweis.

Danke und Grüße vom Rhein.
Stefan

von Stefan E. (sternst)


Lesenswert?

S. G. schrieb:
> Ist ein Byte 0x00 wird es generell nie so zurückgegeben,

Natürlich nicht, schließlich signalisiert eine 0 das Ende eines Strings 
für uart_puts, also wird weder die 0, noch das, was eventuell noch 
danach kommt, gesendet.

Da du nicht einen null-terminierten Text-String senden willst, sondern 
einen Datenblock fester Länge, musst du dir dafür eine eigene Funktion 
schreiben.

von S. G. (goeck)


Lesenswert?

Hallo Stefan,

OK, werde mir mal fix eine basteln. Allerdings erklärt das nicht die 
übrigen Aussetzer, bspw. dass die ersten beiden Bytes fehlen o.ä. Der 
Screenshot zeigt das gerade nicht, aber ich kann gerne nochmal ein paar 
hochladen.

Werde die Änderung auch posten.

Bis dahin schon mal Danke!

Grüße
Stefan

von S. G. (goeck)


Angehängte Dateien:

Lesenswert?

So,

ich habe jetzt die uart_putc() angepasst, welche von uart_puts() 
zyklisch gerufen wird. Immer, wenn das zu versendende Byte Null ist, 
wird es einfach um eins inkrementiert und so zu einer Eins. Ich sehe 
allerdings diese Eins nirgens, nächster Versuch war dann, die Null zu 
überschreiben mit einer 33 (rein willkürlich gewählt). Ich sehe nirgens 
eine 33 im Echo, siehe Screenshot. Setze ich direkt, ohne if Abfrage 
alles auf 33 sieht es aus, wie im zweiten Screenshot.
1
/*************************************************************************
2
Function: uart_putc()
3
Purpose:  write byte to ringbuffer for transmitting via UART
4
Input:    byte to be transmitted
5
Returns:  none          
6
**************************************************************************/
7
void uart_putc(unsigned char data)
8
{
9
    unsigned char tmphead;
10
11
//++++++++++++++++++++++++++++++++
12
    if(data == 0)
13
  data=33;
14
//++++++++++++++++++++++++++++++++
15
    
16
    tmphead  = (UART_TxHead + 1) & UART_TX_BUFFER_MASK;
17
    
18
    while ( tmphead == UART_TxTail ){
19
        ;/* wait for free space in buffer */
20
    }
21
    
22
    UART_TxBuf[tmphead] = data;
23
    UART_TxHead = tmphead;
24
25
    /* enable UDRE interrupt */
26
    UART0_CONTROL    |= _BV(UART0_UDRIE);
27
28
}/* uart_putc */
29
30
31
/*************************************************************************
32
Function: uart_puts()
33
Purpose:  transmit string to UART
34
Input:    string to be transmitted
35
Returns:  none          
36
**************************************************************************/
37
void uart_puts(const char *s )
38
{
39
    while (*s) 
40
      uart_putc(*s++);
41
42
}/* uart_puts */

Das verstimmt mich nur noch mehr...hmpf

Könnnen denn überhaupt mehrere Nullbytes mit normalen UART Routinen dann 
empfangen werden, oder endet dann immer der String? Ich habe die 
Empfangsroutine extra erst bei Empfang von 0x96 abbrechen lassen.

Viele Grüße
Stefan

von Stefan E. (sternst)


Lesenswert?

S. G. schrieb:
> ich habe jetzt die uart_putc() angepasst, welche von uart_puts()

Das bringt doch überhaupt nichts. Bei einer 0 wird doch die uart_putc() 
gar nicht erst von uart_puts() aufgerufen. Du brauchst eine eigene 
Version von uart_puts(), nicht von uart_putc().

von S. G. (goeck)


Lesenswert?

Du hast Recht, wie ich selbst gesehen habe...

Ich habe eine Senderoutine nach dem Datenblatt gebaut, die will aber 
noch keine Strings versenden, allerdings schon mal einzelne Character...
Werde morgen dran schrauben, und hoffe wirklich, ich bekomme was hin.

Wie sieht es denn mit dem Empfangen aus, meinst du hier liegt die gleich 
Problematik vor?

Grüße

von c-ler (Gast)


Lesenswert?

z.B.
1
void PutBytes(char *ptr, uint8_t n)
2
{
3
    while(n)
4
    {
5
        Sci0_PutChar(*ptr);
6
        ptr++;
7
        n--;
8
    }
9
}

von S. G. (goeck)


Angehängte Dateien:

Lesenswert?

Hallo,

danke für den Code. Ich habe in diesem Thread: 
Beitrag "0x00 über UART übertragen" ähnlichen Code gefunden und 
bei mir folgenden Code eingefügt und verwendet:
1
void uart_putx(const char *s, uint8_t n)
2
{
3
    while (n) 
4
  {
5
    uart_putc(*s++);
6
    n--;
7
  }
8
    
9
}/* uart_putx */

Das funktioniert auch, allerdings gewissermaßen zu gut. Jetzt werden 
immer Nullen verschickt und zwischendrin steckt die eigentliche 
Nachricht, siehe Screenshot. Irgendwie fühlt sich der AVR jetzt genötigt 
laufend Nullen auf den UART zu legen und zwar ohne Pause, muss ich evtl. 
noch den Sendebetrieb ausschalten oder so? Das wäre mir neu.

Grüße
Stefan

von Karl H. (kbuchegg)


Lesenswert?

S. G. schrieb:

> Das funktioniert auch, allerdings gewissermaßen zu gut. Jetzt werden
> immer Nullen verschickt und zwischendrin steckt die eigentliche
> Nachricht, siehe Screenshot. Irgendwie fühlt sich der AVR jetzt genötigt
> laufend Nullen auf den UART zu legen und zwar ohne Pause,

der fühlt sich nicht 'irgendwie' genötigt, sondern arbeitet dein 
Programm ab. Wenn du die Funktion immer wieder mit 0-Bytes aufruft, dann 
verschickt die UART die auch.

von Karl H. (kbuchegg)


Lesenswert?

S. G. schrieb:

> Wie sieht es denn mit dem Empfangen aus, meinst du hier liegt die gleich
> Problematik vor?

Sie liegt immer dann vor, wenn du deine Daten wie Strings behandelst!

Du hast keine Strings! Du hast Bytefelder mit allen überhaupt möglichen 
Werten drinn. Das sind keine Strings.

Und solange du nicht aufhörst, nicht zwischen Strings und Bytefeldern 
ztu unterscheiden, wirst du dich auch niemals aus deinen Dilemmi 
befreien können.

Nicht alles was mehrere Daten hintereinander in einem Array ablegt, ist 
ein String! Also behandle das auch nicht so, als ob das gleich wäre.

von S. G. (goeck)


Lesenswert?

Hallo Karl Heinz,

danke für deine Anmerkungen. Ich denke, uns beiden ist 
selbstverständlich klar, dass sich ein µC nicht nach Gefühlslage verhält 
sondern äußerst deterministisch. Ich wollte nur meinem Unmut damit 
Ausdruck verleihen...

Das es ein Problem mit den Strings gibt ist mir auch klar, seit Stefan 
das eingeschmissen hat. Mir ist im Code allerdings noch unklar, wo ich 
das beseitigen kann, da ich nirgens eine Stelle finde, wo bspw. nach 
einem \0 abgebrochen wird zu senden oder empfangen...Hier sehe ich mich 
noch im Wald, aber ich werde sehen, was ich noch finden kann. Mir ist 
wohl der Unterschied zwischen einem String udn einem uint8_t Array klar.
Mir ist allerdings nicht klar, wo die Funktion mit 0 als Argument 
dauernd aufgerufen wird, denn das sollte sie ja nur so oft, bis die 
while Schleife abgelaufen ist.

Danke euch allerdings nochmals für eure Hinweise.

Grüße
Stefan

von S. G. (goeck)


Lesenswert?

OK, Update,

was ich jetzt hinbekommen habe, ist ein vordefiniertes uint8_t Array zu 
versenden, und zwar folgendes:
1
const uint8_t SCS_CMD_RESET[] = {0xAA, 0xAA, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x3F, 0x01, 0x00, 0x5F, 0x55, 0x55};

Das ist entnommen aus diesem Thread: 
Beitrag "Flasharray an UART ausgeben"

Woran ich also noch scheitere ist anscheinend, das Einlesen der Daten 
vom UART.

von Peter II (Gast)


Lesenswert?

S. G. schrieb:
> Woran ich also noch scheitere ist anscheinend, das Einlesen der Daten
> vom UART.

dann zeige doch bitte mal den aktuellen code vom einlesen

von S. G. (goeck)


Angehängte Dateien:

Lesenswert?

Whop..sorry, ganz vergessen in der Hektik

verwende gerade diesen Code und bekomme folgendes Echo -> Screenshot
Leider finden sich hier auch die Nullen nach dem öffnenden Byte 0x96, 
die Anzahl der empfangenene Bytes (=16) scheint aber zu stimmen, also 
die Endbedingung auch zu funktionieren...

EDIT: Stimmt nicht, es lag nur daran, dass ich den Puffer genau 16 Byte 
groß gemacht hatte, wird er vergrößert, wird er auch mit Nullen 
vollgefüllt bzw. befinden sich nur Nullen und die Start-0x96 drin.

1
void uart_putx(const uint8_t *s, uint8_t n)
2
{
3
    while (n--) 
4
  uart_putc(*s++);    
5
}/* uart_putx */
6
7
8
void uart_getx( uint8_t* Buffer, uint8_t MaxLen )
9
{
10
  uint8_t NextChar;
11
  uint8_t Len = 0;
12
 
13
  NextChar = uart_getc();         // Warte auf und empfange das nächste Zeichen
14
  if(NextChar != 0x96)
15
      return;
16
 
17
  // Sammle solange Zeichen, bis entweder das String Ende Zeichen kam oder das aufnehmende Array voll ist
18
  while( NextChar != 0x8D && Len < MaxLen - 1 ) {
19
    *Buffer++ = NextChar;
20
    Len++;
21
    NextChar = uart_getc();
22
  }
23
     
24
  // Setze Flag "Neue Daten verfügbar"
25
  flagNewData = 1;
26
}

Grüße

von Karl H. (kbuchegg)


Lesenswert?

> NextChar = uart_getc();

Dir ist aber schon klar, dass das uart_getc aus der Fleury Lib ein 
'nicht wartendes getc' ist. D.h. das wartet nicht darauf, das da ein 
Zeichen eintrudelt, sondern kommt sofort wieder zurück und meldet dir 
mit einem Code (daher ist der Returntyp der Funktion auch int und nicht 
char), dass sie kein Zeichen für dich hat. Wenn du allerdings in deinem 
Code dann so tust, als ob da was reingekommen ist, darfst du dich nicht 
wundern, wenn du jede Menge Schmutz in deinen Arrays stehen hast. Denn 
das Programm arbeitet nun mal wesentlich schneller als die UART 
übertragen kann. Selbst wenn die UART voll ausgelastet ist, wirst du 
sowas wie ungefähr 30 bis 40 getc Aufrufe haben, die einfach nur melden 
'Ich hab nix'.

Peter hat so ein schönes Beispiel zu seiner Lib mitgeliefert. Hast du da 
noch nie reingeschaut, wie die Funktionen zu verwenden sind?

von S. G. (goeck)


Lesenswert?

Hallo Karl Heinz,

ich weiß, das das eine non-blocking Routine ist. Ich hatte weiter oben 
ja bereits beschrieben, dass ich es auch schon mit einer blockierenden 
probiert hatte - ohne Erfolg. Ich denke, ich werde jetzt, da es einige 
Fortschritte gibt nochmal fix implementieren und mich dann gleich wieder 
melden.

Grüße

von Karl H. (kbuchegg)


Lesenswert?

Tip:

mach dir fürs erste eine blockierende Version von uart_getc. Sonst bläht 
sich die uart_getx Funktion nämlich extrem auf.
1
char uart_getc_wait()
2
{
3
  int c = uart_getc();
4
5
  while( ..... ) {
6
    c = uart_getc();
7
  }
8
9
  return c;
10
}

von S. G. (goeck)


Lesenswert?

Habe gerade verifiziern können, das die Nullen also wirklich aus dem 
leeren FIFO stammen und an mit UART_NO_DATA gekennzeichnet sind. 
Allerdings habe ich für Debug Zwecke in die Lib eingegriffen. Das will 
ich vermeiden.
Peter fragt in seinem Testprogramm nach UART_NO_Data ab, aber bei mir 
scheint das keine Auswirkungen zu haben, da ich sofort ein uint8_t 
verwende, wo die Indikation verloren geht. Ich werde das mal ändern und 
dann hoffentlich diese Nullen erkennen und ignorieren können.

Melde mich dann mit Code wieder.

Danke und Grüße

von Karl H. (kbuchegg)


Lesenswert?

S. G. schrieb:

> Peter fragt in seinem Testprogramm nach UART_NO_Data ab, aber bei mir
> scheint das keine Auswirkungen zu haben, da ich sofort ein uint8_t
> verwende, wo die Indikation verloren geht.

Du lernst gerade eine Lektion.

Testprogramme werden nicht nur zum Spass mitgeliefert.
Und: man schaut sich die Testprogramme genau an! Inklusive Verwendung 
der Funktionen, inklusive der Datentypen der Variablen, inklusive der 
Auswertung von Returncodes, inklusive der Werte der Returncodes bzw. 
deren Wertebereiche (und den daraus resultierenden Anforderungen an die 
Datentypen von Variablen)

Sowas nennt man dann: Code-Studium

von S. G. (goeck)


Angehängte Dateien:

Lesenswert?

OK, ich denke, ich hab's. Siehe Screenshot.
1
void uart_putx(const uint8_t *s, uint8_t n)
2
{
3
    while (n--){ 
4
    uart_putc(*s++);  
5
    if(*(s+1) == 0x8D)  break;
6
  }  
7
}/* uart_putx */
8
9
10
//taken from: http://www.mikrocontroller.net/topic/153197 
11
void uart_getx( uint8_t* Buffer, uint8_t MaxLen )
12
{
13
  uint16_t NextChar;
14
  uint8_t Len = 0;
15
 
16
  NextChar = uart_getc();         // Warte auf und empfange das nächste Zeichen
17
  if(NextChar == 0x96)
18
  {
19
    // Sammle solange Zeichen, bis entweder das String Ende Zeichen kam oder das aufnehmende Array voll ist    
20
    while(NextChar != 0x8D) {
21
      if ( !(NextChar & UART_NO_DATA) ) {
22
        *Buffer++ = (uint8_t)NextChar;
23
        Len++;      
24
      }
25
      NextChar = uart_getc();
26
    }    
27
    // Setze Flag "Neue Daten verfügbar"
28
    flagNewData = 1;
29
  }    
30
}

Ich habe also - nachdem ich nochmal Peters Beispielprogramm durchforstet 
habe - den 16Bit Output aus uart_getc() verwendet, so konnte ich dann 
wieder prüfen, ob es sich um valide Daten handelt und kann diese dann 
verwerfen, habe so gewissermaßen eine blockierende uart_getc() erzeugt. 
Die Routine uart_getx() kehrt erst wieder, wenn das schließende 0x8D (in 
meinem Fall) gefunden worden ist. Die Längenbegrenzung habe ich komplett 
außer Kraft gesetzt.

Herzlichen Dank nochmal an alle, die mir in der Sache weiter geholfen 
haben. Ich muss zugeben, ich habe nicht mehr darauf geachtet, dass ich 
die Plausibilitätsprüfungen selbst machen muss und auch gar nicht mehr 
daran gedacht, dass in dem Puffer - auch wenn es Nullen sind (irgendwas 
muss ja immer drinstehen...klar) - nicht empfangene Daten stehen können, 
sondern andere.

Vielen Dank nochmal!

Grüße aus dem Rheinland
Stefan

von Karl H. (kbuchegg)


Lesenswert?

> void uart_putx(const uint8_t *s, uint8_t n)
> {
>     while (n--){
>     uart_putc(*s++);
>     if(*(s+1) == 0x8D)  break;
>   }
> }/* uart_putx */


kann man natürlich machen.

Da bei dir aber das 0x8D dieselbe Rolle spielt, die in einem String der 
Bytewert 0x00 spielt, kannst du auch die Techniken der 
Stringprogrammierung adaptieren.
Im Grunde hast du sowas ähnliches wie einen String, nur das der eben mit 
0x8D terminiert ist.
1
void uart_putx(const uint8_t *s)
2
{
3
  while( *s != 0x8D )
4
    uart_putc(*s++);
5
}

von S. G. (goeck)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Im Grunde hast du sowas ähnliches wie einen String, nur das der eben mit
> 0x8D terminiert ist.

Ganz genau, daher ist mir auch wohlbekannt, welche Vorteile ich hier 
nutzen kann. Allerdings klappt dein Code gerade nciht. ich schaue 
morgen, woran das nun iweder liegt, aber an solch eine schlanke 
Konstruktion hatte ich eigentlich auch gedacht, musste dann aber das mit 
der if Abfrage und dem break() verwenden, weil nur so der gewünschte 
Effekt zustande kam.

Grüße
Stefan

von Karl H. (kbuchegg)


Lesenswert?

S. G. schrieb:

> nutzen kann. Allerdings klappt dein Code gerade nciht.

Mach mich nicht schwach.

Scroll, scroll, scroll

Nö, das müsste funktionieren, wenn die Daten korrekt sind.

Ah. Ich seh gerade doch noch was.

gewöhn dir an:
  char     nimmst du für alles was mit Textverarbeitung zu tun hat.
           also alles wo Strings oder Zeichen im Spiel sind

  uint8_t  nimmst du für alles, was einfach nur als Byte bezeichnet
           werden kann.


Nicht mischen. Die Sichtweise 'oh, da habe ich ein paar Bytes, da nehme 
ich einfach einen char' kann ganz böse ins Auge gehen.

von S. G. (goeck)


Lesenswert?

Hallo Karl Heinz,

ja,...so hab ich auch gedacht, aber ich bekomme wieder nur überall 
Nullen dauerhaft zurückgesendet. Egal, ich schaue morgen, was da schief 
läuft.

Du hast vollkommen Recht mit dem char und int8...Das hatte mich schon 
immer irritiert, warum es so viele verschiedene Bennennungen für die 
vermeintlich selben Byteworte gibt. Aber jetzt hab ich da einen Einblick 
mehr gewonnen.
:-)

Danke nochmals.

Grüße

von S. G. (goeck)


Lesenswert?

Ich habe jetzt folgenden Code, musste deinen um die Extraforderung n-- 
ergänzen, erst dann lief er, wie meiner vorher.
1
void uart_putx(const uint8_t *s, uint8_t n)
2
{
3
  while( *s != 0x8D  && n--)
4
    uart_putc(*s++);
5
}

Lasse ich die Prüfung der Länge weg (n--) werden dauerhaft Nullen 
ausgegeben.

EDIT: Hm, Fehler eingeschlichen: mit diesem Code wird das schließende 
0x8D nicht mehr ausgegeben.

von Stefan E. (sternst)


Lesenswert?

1
    while(NextChar != 0x8D) {
2
      if ( !(NextChar & UART_NO_DATA) ) {
3
        *Buffer++ = (uint8_t)NextChar;
4
        Len++;      
5
      }
6
      NextChar = uart_getc();
7
    }
Wenn du das Ende-Zeichen beim Empfangen nicht mit in den Buffer 
schreibst, dann kannst du es bei der Ausgabe natürlich auch nicht als 
Ende-Kennung verwenden.

von S. G. (goeck)


Lesenswert?

Hm, Hallo Stefan,

da hast du natürlich Recht. Das ist mir bewusst, ich hatte jetzt 
allerdings bei der uart_putx das Problem, dass eine Zahlenkollone, die 
ein 0x8D am Ende hat (nicht also eine empfangene Kolonne, sondern eine 
vom AVR erzeugte) nur exklusive des letzten Bytes ausgegeben wird.

von Stefan E. (sternst)


Lesenswert?

Wenn du das Ende-Zeichen mit ausgeben willst, dann musst du halt die 
Schleife etwas umstellen:
1
void uart_putx(const uint8_t *s) {
2
3
  do {
4
    uart_putc(*s);
5
  } while (*s++ != 0x8D);
6
}

von S. G. (goeck)


Lesenswert?

Hey Stefan,

das leuchtet mir ein und hatte ich auch schon mal probiert. Ich bekomme 
allerdings wiederum nur Nullen am Stück und dauerhaft gesendet und 
irgendwo zwischendrin die eigentlich relevanten Bytes...

von S. G. (goeck)


Lesenswert?

Bis jetzt konnte ich es soweit optimieren
1
void uart_putx(uint8_t *s)
2
{  
3
  do{
4
    uart_putc(*s++);
5
  }while(*(s-1) != 0x8D); 
6
}/* uart_putx */

Aber Moment, sollte das nicht an sich das gleiche sein, wie dein letzter 
Code, Stefan?
1
void uart_putx(const uint8_t *s) {
2
3
  do {
4
    uart_putc(*s);
5
  } while (*s++ != 0x8D);
6
}

von Stefan E. (sternst)


Lesenswert?

S. G. schrieb:
> das leuchtet mir ein und hatte ich auch schon mal probiert. Ich bekomme
> allerdings wiederum nur Nullen am Stück und dauerhaft gesendet und
> irgendwo zwischendrin die eigentlich relevanten Bytes...

Innerhalb welchen Kontextes und mit welchem anderen Code zusammen?

Da blickt doch keine Sau mehr durch (zumindest ich nicht), was genau du 
da jeweils mit welchem Code probierst. Ich kann mich z.B. nicht 
erinnern, hier schon mal konkreten Code hierzu
> nicht also eine empfangene Kolonne, sondern eine vom AVR erzeugte
gesehen zu haben.

von S. G. (goeck)


Lesenswert?

Ja Stefan, du hast vollkommen Recht. Ich kann allerdings nicht immer 
allen Code posten, da ich ja auch ständig ändere. Deswegen habe ich von 
dem Startcode ausgehend immer nur die Funktionen gepostet. ich lade nach 
dem Mittag nochmal meinen kompletten Code hoch.

Jetzt gerade passiert aber alles, wo es noch Probleme gibt innerhalb der 
uart_putx();

Grüße

von Karl H. (kbuchegg)


Lesenswert?

S. G. schrieb:
> Hm, Hallo Stefan,
>
> da hast du natürlich Recht. Das ist mir bewusst, ich hatte jetzt
> allerdings bei der uart_putx das Problem, dass eine Zahlenkollone, die
> ein 0x8D am Ende hat (nicht also eine empfangene Kolonne, sondern eine
> vom AVR erzeugte) nur exklusive des letzten Bytes ausgegeben wird.


Weißt du was einer der ganz wichtigen Punkte in der Softwareentwicklung 
ist?

Das man sich mit sich selbst auf Konventionen einigt und die *dann auch 
durchzieht*

Entweder alle deine Datensätze enden mit 0x8D und du kannst das daher 
als Endekennung benutzen oder sie tun es nicht (und du musst daher 
ständig eine Länge mitführen).

Aber entscheide dich für eines von beiden und ZIEH DAS DANN AUCH DURCH!

Mal so und mal so ist ein sicherer Weg ins Desaster! Du magst das 
vielleicht heute noch so lala unter Kontrolle haben aber in spätestens 2 
Wochen hast du das nicht mehr.

von Stefan E. (sternst)


Lesenswert?

S. G. schrieb:
> Jetzt gerade passiert aber alles, wo es noch Probleme gibt innerhalb der
> uart_putx();

Eben nicht. Wenn du lauter Nullen bekommst, dann liegt das garantiert 
nicht an uart_putx, sondern einfach daran, dass die Daten, die der 
Funktion übergeben werden, nicht so aussehen, wie sie sollten. Und woran 
das liegt kann dir keiner sagen, wenn wir den Code nicht kennen, der die 
Daten produziert.

von S. G. (goeck)


Angehängte Dateien:

Lesenswert?

Hm,

Karl Heinz, ich sehe das genau wie du, daher sind alle diese 
Zeichenkolonnen mit 0x8D terminiert. Bisher konnte ich nicht zuverlässig 
mit dieser Terminierung arbeiten, daher musste ich immer einen Counter 
mitführen. Jetzt habe ich in allen betroffenen Routinen keinen Counter 
mehr, da ich mit der Terminierung arbeiten kann. Allerdings kann hier 
und da der Code noch effizienter sein, denke ich.

Stefan, ich stimme dir da nicht vollkommen zu. Ich weiß wie die 
übergebenen Bytes aussehen und kann sie ausgeben. Teilweise entstehen 
aber noch diese Nebeneffekte. Zur Verbesserung, habe ich den kompletten 
Code zum aktuellen Stand angehängt. So wie er jetzt angehängt ist, 
funktioniert er allerdings vollkommen zufriedenstellend.

Ich würde mich freuen, wenn ihr nochmals drüber schaut.

Vielen Dank
Stefan

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.