www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik UART-string(mit Trennzeichen) in ascii-array speichern (AVR-GCC)


Autor: Hubert (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

ich bin relativ neu mitm programmieren (ca 1a) und will einen String 
über UART empfangen der ASCII-zeichen und Trennzeichen enthält, und die 
Werte in ein Array[][] speichern, um die werte dann in Binärzahlen 
umzuwandeln.
Wobei die Trennzeichen nicht mit ins Array sollen, sondern eben nur zur 
Trennung da sind
Leider funzts's ni (avr-studio mit Jtag und Atmega 1281) da (vielleicht) 
die entsprechenden for-schleifen cryptisch durchlaufen werden

die codeschnippsel gibts im anhang

was habe ich falsch gemacht(oder nicht verstanden)?

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
if(usart1==('S'||'s')&&('t'||'T')){

Was hier eigentlich steht, ist: if (usart1 == 1)

for (i=0;((usart_rx[i]!='T')||(usart_rx[i]!='t'))&&((usart_rx[i-1]!='E')||(usart_rx[i-1]!='T'));i++){

"(usart_rx[i]!='T')||(usart_rx[i]!='t')" ist immer true. Das würde nur 
false werden, wenn usart_rx[i] gleichzeitig 'T' und 't' wäre.

"usart_rx[i-1]!='E'": da i bei 0 beginnt, greifst du hier auf 
usart_rx[-1] zu.


PS: Ich habe nur einen kurzen Blick in den Sourcecode geworfen. Nimm es 
mir nicht übel, aber angesichts der Charakteristik der Fehler werden im 
Code sicher noch mehr sein.

Autor: Hubert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja die For-schleife ist für mich nicht leicht zu verstehen, aber wenn 
ichs wüsste, bräucht ich ja nicht fragen

Ich habe einen String gebaut...
char usart_rx[94]=("ST;12345678;14725836;32165498;98765432;96385274;75342865;95162845;85274163;98745632;256;ET");

...der die Charakteristik beschreibt, da der sendende AVR ca 100km 
enfernt ist, und ET is das ende;-) Ich suche nach dem fehler in der 
Bildung des Arrays, das die Werte für die Umwandlung in Binärzahlen 
vorbereitet, und ich programmiere ca 9 monate in C.

Trotzdem, oder gerade deshalb, Danke!

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Dann erst mal was Grundsätzliches:

Warum sollen die Anfangs- und Ende-Marke aus zwei Buchstaben bestehen? 
Das verkompliziert es doch nur unnötig.

Autor: Hubert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das sind die Vorgaben^^
da kann ich nix dran drehen

Autor: Hubert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oh oder gibt es in ASCII Start Transmission und End Transmission Tags? 
Dann könnten auch die gemeint sein, aber mein problem ist, das das 
Array[][] leer is

Autor: Stefan Ernst (sternst)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> oh oder gibt es in ASCII Start Transmission und End Transmission Tags?

Ja, gibt es.

> aber mein problem ist, das das Array[][] leer is

Den Grund, warum das Array leer ist, habe ich doch schon aufgezeigt:
if(usart1==('S'||'s')&&('t'||'T')){
> Was hier eigentlich steht, ist: if (usart1 == 1)

Und da usart1 vermutlich nie 1 ist, wird die for-Schleife auch nie 
ausgeführt.

Das zu ändern wird dir aber nicht wirklich viel weiterhelfen, denn der 
ganze Aufbau ist Murks, z.B. die Tatsache, dass du versuchst, alle 
Zeichen in einem Interrupt einzulesen. Du solltest im Interrupt immer 
nur ein Zeichen einlesen. Am besten wirfst du den kompletten 
Interrupt-Code weg und machst dir nochmal intensiv Gedanken darüber.

Autor: Hubert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
mag ja sein das die interrupt routine mist is, lässt sich ja ändern, 
aberdie Anderen zwei funktionen sind wichtiger, da ich die Daten von 
ASCII in Binär umwandeln will.

Aber Hilfe hatte ich mir anders vorgestellt denn Hilfe ist nicht nur 
Fehler zeigen!

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
uint32_t ascii_to_binary(uint8_t ascii[j][h]){
  uint32_t binary=0;
//  uint8_t ascii[j][h];

  if(j>0){
    binary = ascii[j][h] - '0';
    if(j>1){
      binary = binary + (ascii[j][h] - '0') * 10;
      if(j>2){
        binary = binary + (ascii[j][h] - '0') * 100;
        if(j>3){
          binary = binary + (ascii[j][h] - '0') * 1000;
          if(j>4){
            binary = binary + (ascii[j][h] - '0') * 10000;
            if(j>5){
              binary = binary + (ascii[j][h] - '0') * 100000;
              if(j>6){
                binary = binary + (ascii[j][h] - '0') * 1000000;
                if(j>7){
                  binary = binary + (ascii[j][h] - '0') * 10000000;
                }
              }
            }
          }
        }
      }
    }
  }
  return binary;
}  

total umständlich (von mangelnder Übersicht gar nicht zu reden...)

Wenn du der Funktion ascii_to_binary einen String in Form von 
"1234567890;" übergibst, kannst du das in einer Schleife wesentlich 
einfacher realisieren:
uint32_t ascii_to_binary(uint8_t ascii[])
{ 
   uint32_t binary=0;
   unigned char i=0;
  

  while (ascii[i] != ';')
  {
    binary = binary * 10 + (ascii[i++] - '0');
  }
  return binary;
}

Das Einlesen solltest du lieber erst mal per Polling (ohne ISR) machen.

Autor: Hubert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
naja ich weis aber nicht, wie ich aus
 ascii[] = ("wert1;wert2;..;wert10") 
die einzelnen werte isolieren kann.
Daher dachte ich ja zwei verschachtelte for schleifen zu nehmen die ein 
2D-Array füllen, wobei der eine index für die zahl steht und der andere 
für die stelle. wie der UART-string zustande kommt ist noch ca 1 woche 
unwichtig^^
 das lässt sich dann auch einfach ändern, wenn ichs wirklich brauche.

Autor: STK500-Besitzer (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Daher dachte ich ja zwei verschachtelte for schleifen zu nehmen die ein
>2D-Array füllen, wobei der eine index für die zahl steht und der andere
>für die stelle.

WasfürnDing?
Welche Stelle willst du dir da merken?

Dein String ist relativ einfach zu zerlegen.

0. volatile unsigned char STRING[256]; // Array, in das die Daten vom 
USART
                                       // geschrieben werden
   volatile unsigned char N = 0;       // Schreibposition in STRING
   volatile unsigned char Event = 0;   // Ereignisübermittlungsvariable

1. Empfang per ISR:
//USART--------------------------------------------------------------------------------------
ISR(USART1_RX_vect)
{
  static unsigned char Z = 4;   // Zustandszähler
  unsigned char temp;           // Temporäre Variable

  temp = UDR;

  switch (Z)
  {
    case 4 : if ((temp == 's') || (temp == 'S')) Z= 3; break;
    case 3 : if ((temp == 't') || (temp == 'T')) Z= 2; break;
    case 2 : if ((temp == 't') || (temp == 'T')) Z= 1; break;
    case 1 : if ((temp == 't') || (temp == 'T')) Z= 0; break;
    default : STRING[N++} = temp;
  }
  if (Z==0) Event |= 0x01;
}
//---------------------------------------------------------------------------------------------


Im Hauptprogrammm guckt man dann nach, ob ((Event & 0x01) != 0) ist.
Dann zerlegt man den String, indem man nach Zeichen sucht, die wie 
Ziffern aussehen. Das sollte nur noch das ';' sein...

irgendwie kann man sich das mit deinem 2D-Array auch noch 
vereinfachen...

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.