Forum: Mikrocontroller und Digitale Elektronik uart atoi fehlerhafte Zeichen


von Bernd (Gast)


Lesenswert?

Hallo,
ich möchte über die Serielle Schnittstelle bestimmte Sachen steuern. 
Dazu schicken ich Zeichen über Putty an den AVR.
Die gesendeten Zeichen sind von 0 bis 4097.

Jeweils 255 Werte gehören zu einem Befehl.
1
void read_commands(void)
2
{
3
  if(uart_str_complete)
4
  {
5
    uart_str_complete = 0;
6
    
7
    int16_t incoming = atoi(uart_string);
8
    uint8_t command = incoming / 255;
9
    uint8_t value = incoming % 255;
10
    uart_puti(incoming);
11
    uart_puts(uart_string);
12
    
13
    uart_puts_P("\r\nBefehl : ");
14
    uart_puti_formatted(command);
15
    
16
    uart_puts_P("\tWert : ");
17
    uart_puti_formatted(value);
18
    
19
    uart_puts_P("\r\n");
20
  }
21
}
1
ISR(USART0_RX_vect)
2
{
3
  unsigned char nextChar;
4
  // Daten aus dem Puffer lesen
5
  nextChar = UDR0;
6
7
  // wenn uart_string gerade in Verwendung ist, neues Zeichen verwerfen
8
  if( uart_str_complete == 0 ) {
9
    
10
    // Daten werden erst in uart_string geschrieben, wenn nicht String-Ende/max Zeichenlänge erreicht ist/string gerade verarbeitet wird
11
    if( nextChar != '\n' &&  nextChar != '\r' &&  uart_str_count < UART_MAXSTRLEN )
12
    {
13
      uart_string[uart_str_count] = nextChar;
14
      uart_str_count++;
15
    }
16
    else {
17
      uart_string[uart_str_count] = '\0';
18
      uart_str_count = 0;
19
      uart_str_complete = 1;
20
    }
21
  }
22
}

Mein Output sieht auf der Konsole aber nicht komplett richtig aus, ich 
habe der Reihe nach folgende Werte eingegeben und mit Enter bestätigt.

15, 255, 256,
1
05
2
Befehl :   0    Wert :   0
3
055
4
Befehl :   0    Wert :   0
5
0"56
6
Befehl :   0    Wert :   0

von lrep (Gast)


Lesenswert?

Bernd schrieb:
> Die gesendeten Zeichen sind von 0 bis 4097.

Mit 8 Bit?

Da wirst du nachsynchronisieren müssen, denn wenn ein Byte verloren 
geht, oder am Empfänger durch einen Störimpuls dazukommt, stimmt der 
ganze Rest nicht mehr.

von Peter II (Gast)


Lesenswert?

lrep schrieb:
> Mit 8 Bit?
>
> Da wirst du nachsynchronisieren müssen, denn wenn ein Byte verloren
> geht, oder am Empfänger durch einen Störimpuls dazukommt, stimmt der
> ganze Rest nicht mehr.

er überträgt strings mit Zeilenumbruch. Das sollte schon passen.

von Bernd (Gast)


Lesenswert?

Richtig, die Eingabe erfolgt als Zeichenkette und da sollte es noch 
keine Probleme geben. Es werden auf der UART Schnittstelle max. 6 
Zeichen eingelesen.

von Peter II (Gast)


Lesenswert?

kannst du etwas mehr code zeigen? Es fehlt noch einiges. (initalisierung 
der Variablen usw.)

von lrep (Gast)


Lesenswert?

Bernd schrieb:
> Die gesendeten Zeichen sind von 0 bis 4097.

Peter II schrieb:
> er überträgt strings mit Zeilenumbruch. Das sollte schon passen.

Dann muß er aber darauf achten, daß die Zeichenzahl gerade ist.
Falls ungerade, dann den ganzen String verwerfen, denn man weiß ja 
nicht, wo der Fehler passierte.
...oder die ungenutzen Bits zur Übertragung einer Sequenznummerr 
verwenden.

Fraglich auch, ob wirklich 0..4097 übertragen werden soll

von Peter II (Gast)


Lesenswert?

lrep schrieb:
> Dann muß er aber darauf achten, daß die Zeichenzahl gerade ist.
> Falls ungerade, dann den ganzen String verwerfen, denn man weiß ja
> nicht, wo der Fehler passierte.
> ...oder die ungenutzen Bits zur Übertragung einer Sequenznummerr
> verwenden.

versteht ich nicht? Er überträgt genau eine Zahl die dann in 2 Byte 
umgerechnet wird.

von Bernd (Gast)


Lesenswert?

Peter II schrieb:
> kannst du etwas mehr code zeigen? Es fehlt noch einiges.
> (initalisierung
> der Variablen usw.)

Hallo Peter,

ich hoffe du meinst das hier.


// aus der uart.h
1
#define UART_MAXSTRLEN  6
2
#define BAUD      19200
3
4
extern volatile uint8_t uart_str_complete;
5
extern volatile char uart_string[UART_MAXSTRLEN + 1];
6
extern volatile char c;

Ansonsten wüsste ich nicht, war hier noch interessant ist.

von Walter S. (avatar)


Lesenswert?

Bernd schrieb:
> uart_str_complete = 0;

das solltest du erst machen wenn der String ausgewertet ist sonst machen 
einkommende Zeichen evtl. deinen String kaputt,

von Konrad S. (maybee)


Lesenswert?

Wie sieht es denn mit uart_str_count aus? Da sind noch ein paar Fragen 
offen, die das beobachtete Verhalten erklären könnten.

von lrep (Gast)


Lesenswert?

Peter II schrieb:
> Er überträgt genau eine Zahl die dann in 2 Byte
> umgerechnet wird.

Na ja, ich bin kein C-Programmierer, aber ich sehe da einen Wertebereich 
0..4097, der vermutlich in Wirklichkeit nur 0..4095 umfasst, und ich 
sehe da die Division durch seltsame 255, was vermutlich 256 sein soll.
Bei der Verwendung von LF oder CRLF terminierten Strings, sehe ich die 
Möglichkeit, dass die Falle schon zuschnappt, und der  Strings verhunzt 
wird, wenn an irgend einer Stelle des Strings eine dezimale 10 oder 13 
über die  Leitung rauscht.

von Klugschiss (Gast)


Lesenswert?

lrep schrieb:
> wenn an irgend einer Stelle des Strings eine dezimale 10 oder 13
> über die  Leitung rauscht.

Dies kann aber nicht geschehen, da Zahlen von 0 - 4097 Übertragen werden 
sollen.
Daraus ergibt sich eine Nutzzeichenlänge von 1 - 4 Byte im Wertebereich 
von 0x30 - 0x39.

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.