Forum: Projekte & Code float via UART am ATMega16 empfangen (in C)


von Johannes (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

hier ein Programm das eine float Variable innerhalb eines ganz simplen
protocols empfaengt.
getestet mit folgendem System:
Code in C
WinAVR Compiler
ATMega16 mit 16 MHz

Source Code ist relativ gut auskommentiert.

mg,
Johannes

von Johannes (Gast)


Lesenswert?

hallo,

vielleicht sollte ich noch kurz dazuschreiben wie die bytes uebertragen
werden:

....

union{
     float r;
     uint8_t v[sizeof(float)];
     } u;
unsigned char send_command[7];
....
u.r = 123.456;  //hier die float Variable speichern

//... protocol implementieren ...

send_command[0]=0xFE;  //STX
send_command[1]=0x00;  //Data description
send_command[2]=u.v[0];  //floatbytes
send_command[3]=u.v[1];
send_command[4]=u.v[2];
send_command[5]=u.v[3];
send_command[6]=0xEF;  //ETX

//hier send_command[] ueber die serielle Schnittstelle schicken.
sendMyCommandToSerialPort();

Die Darstellung der bytes auf dem ATMEL Controllern ist little Endian,
auf den meisten PCs ebenfalls (Intel Procs). Die Darstellung muss
natuerlich auf uC und Rechner die gleiche sein sonst hauts nicht hin.

Link zu litte Endian:
http://de.wikipedia.org/wiki/Little_Endian

mg,
Johannes

von sni (Gast)


Lesenswert?

Wäre es nicht einfacher nen Pointer auf die float-Variable zu legen.
Dann nen cast auf unsigned char und die 4 Bytes per UART
wegschicken...geht auch bei strukturen prima.... wozu dann union..

von Johannes (Gast)


Lesenswert?

Meine Bedenken hatte ich mit den pointern wegen der Pointerarithmetik.
Ich war/bin mir nicht ganz sicher was passiert wenn man einen Pointer
auf eine Float-Variable zeigen laesst und dann inkrementiert... werden
die Speicherstellen dann um sizeof(unsigned char) oder um sizeof(float)
inkrementiert, das muss man ja manuell machen; bei der Union ist das
automatisch der Fall, dass die Variablen auf die gleiche Speicherzelle
zeigen und sie sind explizit dazu gedacht verschiedene Datentypen zu
speicher...

ich muss zugeben meine Freude an der Union zu haben, denn ich verwende
sie wirklich nur sehr sehr selten...

Kann sein, dass es auch mit deiner Methode funktioniert, ich wills
nicht bestreiten; ich  habs aber nicht probiert und getestet.

Danke jedenfalls fuer die Anregung.

mg,
Johannes

von Johannes (Gast)


Lesenswert?

mit "manuell machen", meinte ich die Definitionen der pointer und das
zuweisen in der Form *(pointer+i) = ...   Das Inkrementieren der
Speicheradresse geht natuerlich automatisch.

mg,
Johannes

von sni (Gast)


Lesenswert?

wo ist das Problem?

@Johannes

nach dem cast auf unsigned char wird beim pointer++ nur um ein byte
weitergezäht. Mache das schon ewig so.. Funktioniert auch super mit
Strukturen oder dergleichen.

Schema ungefähr so...ohne sich mal Syntax zu halten

float x=1.234;
unsigend char p*;
unsigned char buffer[4];

p = (unsigned char) x;

buffer[0]= *p++;
buffer[1]= *p++;
buffer[2]= *p++;
buffer[3]= *p;

so ungefähr!

von Stephan Rein (Gast)


Lesenswert?

Hallo,
hier ist ein Beispiel mit einem von mir getesteten C-Code im
Sinne des oben angegebenen Beispiels.
Viel Erfolg,
Stephan Rein

main(){
  printf("Welcome to the test program!\n");
  float a=4.2351894;
  unsigned char *p;
  p=(unsigned char*) &a;

  unsigned char ch[4];
  int i;
  for (i=0;i<4;i=i+1) ch[i]=p[i];

  float b;
  unsigned char *p2;
  p2=(unsigned char*) &b;
  for (i=0;i<4;i++) p2[i]=ch[i];

  printf("%f\n",b);
}

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.