mikrocontroller.net

Forum: Compiler & IDEs dtostrf- Problem


Autor: Kunki_86 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
allo Zusammen,

ich habe vor kurzem angefangen mein Atmel in C zu programmieren (vorher
immer in Basic). Nun habe ich ein Problem und weiß nicht wo mein
Denkfehler oder Leichtsinnsfehler liegt. Ich möchte eine Kommazahl über
ein Uart senden. Ich verwende die dtostrf- Funktion. Leider geht das
aber nicht. Mein Terminalprogramm empfängt jediglich nur ein "H".
Wär echt klasse, wenn ihr mir helfen könntet.
Mein Code:

#include <avr/io.h>
#include <stdint.h>
#include <avr/delay.h>
#include <stdio.h>
#include <stdlib.h>


#define SYSCLK    8000000L
#define BAUD    9600L
#define UBRR_BAUD  ((SYSCLK/(16*BAUD))-1)

/* INT Deklarationen */
int init(void);
int uart_out(char sende_daten[8]);


int main()
{

     char s[8];
     float f = -12.345;

        init();

     dtostrf( f, 6, 3, s );

  while (1)
  {
  _delay_ms(1000);

  uart_out(s);

  }

}


int uart_out(char sende_daten[8])

{

  while (!(UCSRA & (1<<UDRE)));
        UDR = sende_daten;
  return(0);

}



int init(void)
{
  /* Baudrate einstellen ( Normaler Modus ) */
  UBRRH =  (unsigned char)(UBRR_BAUD>>8);
  UBRRL = (unsigned char)UBRR_BAUD;

  UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);

  /* Einstellen des Datenformats: 8 Datenbits, 1 Stoppbit */
  UCSRC = (1<<URSEL)|(1<<UCSZ1)|(1<<UCSZ0);

  return(0);
}

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du machst einen großen und einen kleinen Fehler.

Erst einmal der kleine Fehler: 1000 ms lassen sich mit _delay_ms() bei
gewöhnlichem AVR-Takt nicht erreichen.  10 ms ist ein sicherer Wert,
der selbst bei den derzeit schnellsten AVRs (20 MHz) immer
funktioniert.  Normalerweise nimmt man für lange Verzögerungen ja
sowieso einen Timer, für den einfachen Test kannst du die Funktion ja
100mal aufrufen.

Der große Fehler: du willst einen String ausgeben, gibst aber nur das
niedrige Byte der Adresse des Strings (die in "sende_daten" steht)
aus.  Bau die Funktion so um:
static void
uart_out_char(char c)
{
  while (!(UCSRA & (1<<UDRE)));
        UDR = c;
}

int uart_out(char *sende_daten)
{
  char c;

  while ((c = *sende_daten++) != '\0')
    uart_out_char(c);

  // Vielleicht willst du ja das hier noch?
  uart_out_char('\r');
  uart_out_char('\n');

  return 0;
}

Autor: Kunki_86 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
danke für Deine Antwort. Jedoch gehts bei mir irgendwie immer noch
nicht. Wär genial, wenn mir nochmal helfen könntest. Ich zweifel grad
echt an meiner Intelligenz:). Vielleicht könntest Du den Code
verbessern. Weil bei mir kommt nämlich gar nichts.


/* INT Deklarationen */
int init(void);
static void uart_out_char(char c);
int uart_out(char *sende_daten);

int main()
{
    char s;
    float f = -12.345;

    init();

    dtostrf( f, 6, 3, s );

  while(1)
  {
  _delay_ms(10);

  uart_out(s);
  }
}

int uart_out(char *sende_daten)

{

  char c;
  while ((c = *sende_daten++) != '\0')
  uart_out_char(c);
  return 0;

}

static void uart_out_char(char c)
{
  while (!(UCSRA & (1<<UDRE)));
  UDR = c;
}

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du einen float in einen Character-String umwandeln willst, dann
musst Du für den String auch ausreichend Speicherplatz zur Verfügung
stellen. "c" ist aber nur ein einfacher char, da passt nur eine
einzige Stelle (ASCII-Zeichen) rein. Du brauchst aber 7 Stellen (6
Stellen für die Zahl an sich, wenn Du als "width" 6 angibst und ein
Zeichen für den Nullterminator). Dazu muss c mindestens als Array mit 7
Elementen deklariert werden, also "char s[7];". Allerdings hat die im
Beispiel angegebene Zahl "-12.345" bereits 7 Stellen, da sich der
Parameter "width" auf die Gesamtlänge der Ausgabe bezieht, also auf
alle Ziffern zzgl. Dezimalpunkt und Vorzeichen. Du wirst diese Zahl
also so nicht darstellen können. Da muss also ein Array mit 8 Elementen
her, also "char s[8];". Damit sollte es funktionieren.

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.