mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik irgendwas stört rs232 übertragung von float-messwert?!


Autor: Martin S. (keniff)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo alle zusammen!

1.: avr studio 4.14, ATmega128, in C

bräucht ma wieder rat und beistand wegen folgendem problem:
ich sitz an ner empfangsroutine für ein rs485 bus, welche auf anfrage 
vom master den messwert von nem sensor berechnet und an den master 
sendet:
ISR (SIG_UART1_RECV)
{  
  cli();
  temp_str1 = USART_Receive1();
    if (temp_str1 == 0x03) {
    temp_str2 = USART_Receive1();
    temp_str3 = USART_Receive1();

  messen();
  
  if (erg2>9.99){
  dtostrf(erg2,1,1,puffer);}
  //printf(puffer,"err");}
    else if (erg2<=9.99) {dtostrf(erg2,1,2,puffer);}
      
  len = strlen(puffer);
  
    switch(temp_str3)      
      {
    case 0x05 : USART_Transmit1(len);USART_Puts1(puffer);break;
    case 0x04 : PORTB = 0b11100111;break;
      }
  }
  sei();
}

Dieser Interrupt wird ausgelöst, 3 bytes empfangen 
(adresse,status,status), bei korrekter adresse die funktion messen(); 
aufgerufen, umgewandelt und zurückgesendet.
wenn ich den code wie oben nicht verändere funktioniert er eig bis auf 
wenige messwerte, aber er funkioniert...

der fehler tritt dann auf (was ich wieder total nicht verstehen kann), 
wenn  ich
dtostrf(erg2,1,1,puffer);
durch
printf(puffer,"err");
oder
die isr einfach nur umschreiben möchte. und zwar bekomm ich dann nur 
noch ein "er" statt "err" und als messwert eine kommastelle zu wenig 
aber dafür ein "y","ö" oder "ü" also nicht mehr "5,67" sondern "5,6y" 
oder auch gerne nur "5,6 "!

da ich mir sicher bin, das die rs232 verbindung fehlerfrei läuft und 
allein der befehl printf die übertragung stört, bin ich völlig ratlos 
woran es hängen könnte!jegliche kleine änderung verursacht fehler bei 
der übertragung... :-(

wär froh, wenn mir einer sagen könnte, wie der hase zu laufen hat^^

mfg keniff

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

Bewertung
0 lesenswert
nicht lesenswert
Ich rate mal.

puffer ist als

char puffer[3];

definiert?

Noch ein Hinweis: die erste Zahl bei dtostrf ist die Gesamtzahl an zu 
benutzenden Stellen (die Feldbreite). Dies beinhaltet ein eventuelles 
Vorzeichen und auch den Kommapunkt.

Eine Angabe von   1, 1 ist daher sinnlos. Du willst eine Kommazahl in 
einem Feld der Breite 1 (inkl Vorzeichen und Kommapunkt) unterbringen 
UND das Ganze dann auch noch mit 1 Nachkommastelle.

Für eine Ausgabe von 5.2 benötigst du eine Feldbreite von 3 (1 
Vorkommastelle, 1 Dezimalpunkt, 1 Nachkommastelle = 1 + 1 + 1 = 3). Das 
empfangende char-Array muss aber dann mindestens eine Länge von 4 haben 
(wegen des obligaten '\0' Zeichens am String-Ende)

Aber vorsicht: dtostrf kann deine erste Angabe (die Feldbreite) 
ignorieren, wenn es ansonsten die Zahl nicht unterbringen kann. Dadurch 
ist es unklug, den Ausgabepuffer ganz knapp zu dimensionieren. Array 
Overflows sind die Folge mit den typischen Folgen wie du sie 
beschreibst.

Edit:
printf(puffer,"err");

macht auch keinen Sinn. Wenn schon, dann sprintf. Und um den Text "err" 
dort unterbringen zu können, muss puffer mindestens eine Länge von 4 
haben.

Autor: Martin S. (keniff)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hey karl-heinz,
du schon wieder! ;-) freut mich!

ehm nein^^, puffer is [10]

der befehl dtostrf is mir noch bissel neu, da werd ich nochma schaun, 
aber an dem liegts ja nicht unbedingt...

habs auch schon mit sprintf, strcpy oder sonstigem probiert...
selbst wenn ich ein def. string verschicken möchte aber die 
sprintf-zeile benutze, hab ich den selben fehler...

eig kann ich nicht den kompl code posten, aber denk auf rate spielchen 
hat hier keiner lust! aber bitte nicht köpfen, wenn nicht alles 1A 
C-Syntax is ;-)

mfg keniff

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

Bewertung
0 lesenswert
nicht lesenswert
Hmm.

Was mir mal überhaupt nicht gefällt ist, dass du die Empfangerei in eine 
ISR gelegt hast. ISR mit Warten auf Ereignisse ist meistens keine gute 
Idee. Zumindest solltest du den cli() und sei() da rauswerfen. Sowas hat 
in einer ISR nichts verloren.

Welche UART Funktionen benutzt du, was machen die?

Edit:
Meist ist es eine gute Idee, explizit zu sein. Manchmal ist es das aber 
nicht. Das hier
  if (erg2>9.99){
  dtostrf(erg2,1,1,puffer);}
  //printf(puffer,"err");}
    else if (erg2<=9.99) {dtostrf(erg2,1,2,puffer);}
  //sprintf(puffer,"%f",a); 

scheint mir ein Fall für "es ist keine gute Idee" zu sein.
Wenn eine Zahl nicht kleiner als 9.99 ist, dann muss sie größer oder 
gleich 9.99 sein. Es gibt keine andere Möglichkeit
    if( erg2 > 9.99 )
      dtostrf( erg2, 4, 1, puffer);
    else
      dtostrf( erg2, 4, 2, puffer );

PS: Der Code ist durch die vielen Auskommentierungen sehr schlecht zu 
lesen. Der Fehler an den ich ursprünglich dachte, liegt allerdings nicht 
vor. Die Ausgabepuffer sind gross genug dimensioniert.

Autor: Martin S. (keniff)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
ich weiss, ich sollte die ISR so kurz wie möglich halten, aber auch das 
auslagern des codes in eine extra-funktion bringt kein unterschied...

benutz usart-routinen, welche aber denk standard sind?! (anhang)
steh echt vorm berg...

hoff du siehst vllt, was da schief läuft!

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

Bewertung
0 lesenswert
nicht lesenswert
Martin S. wrote:
> ich weiss, ich sollte die ISR so kurz wie möglich halten, aber auch das
> auslagern des codes in eine extra-funktion bringt kein unterschied...

Darum gehts nicht. Mit 'so kurz wie möglich' meint man nicht Codegröße 
sondern wie lange die Interrupts gesperrt sind. In deiner ISR sind die 
Interrupts sehr, sehr lange gesperrt. Nämlich solange wie es dauert 3 
Bytes zu empfangen, zu messen und das Ergebnis auf den Weg zu bringen.

Auf der anderen Seite macht deine Hauptschleife gar nichts. Da wäre 
vieles gut aufgehoben.

Autor: Martin S. (keniff)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
denkst du, da liegt der hund begraben? also, dass durch falschen aufbau 
vom main/isr usw, das programm irgendwann aussetzt?
hmm, wenn das was bringt mach ichs gern ^^
was mich aber bischen wundert, da der µC als slave eig eh nichts andres 
zu tun hat, als die isr abzuarbeiten.

bei dem >9,99 fehlt eig auch noch die abfrage <0,00 , aber das waren 
alles mehr spielereien, und auch nicht wirklich überlegt...

das problem ist halt eher das oben genannte. hab dich ja vorgewarnt, 
dass es manchma recht verwurstelt is.

kann es sein, dass µC-programmierung manchma was von zauberei hat??? ;-)
verstehs grad echt net

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

Bewertung
0 lesenswert
nicht lesenswert
Martin S. wrote:
> denkst du, da liegt der hund begraben? also, dass durch falschen aufbau
> vom main/isr usw, das programm irgendwann aussetzt?

Ich weiß es nicht.
Ich seh im Moment eigentlich kein offensichtliches Problem mehr.

Ich würds auf jeden Fall mal machen.

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.