mikrocontroller.net

Forum: Compiler & IDEs 32 bit über rs232 einlesen


Autor: Till (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

Ich würde gerne maximal 32 bit (eine Botschaft) vom PC über die RS232 
(9600) an den µC (Atmega 32) senden so 1-2 mal in der Sekunde aus 
LabView heraus, mit ISR einlesen und in ein long int stecken für die 
weitere Verwendung.

Ein Byte über ISR kann ich einlesen und ich kann auch schon eine long 
int senden in dem ich sie auf 4 Byte aufteile.

Ich hab sehr wenig Erfahrung mit C-Programmierung und bin für jede Idee 
sehr dankbar.

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

Bewertung
0 lesenswert
nicht lesenswert
Till wrote:

> Ein Byte über ISR kann ich einlesen und ich kann auch schon eine long
> int senden in dem ich sie auf 4 Byte aufteile.

Na, ja.
Dann machst du im µC genau das Umgekehrte von der Sendeseite
und pfriemelst du 4 bytes wieder in einen long int zusammen.

zb. so
union _Receiver
{
  long int Value;
  unisgned char Bytes[4];
}

  _Receiver rec;

  rec.Bytes[0] = Byte1_von_der_Uart;
  rec.Bytes[1] = Byte2_von_der_Uart;
  rec.Bytes[2] = Byte3_von_der_Uart;
  rec.Bytes[3] = Byte4_von_der_Uart;
  
  mach_was_mit rec.Value;

Das ganze beruht darauf, dass der Compiler über die Union
angewiesen wird, die beiden Variablen Value und Bytes
im Speicher an derselben Adresse anzuordnen, also quasi
übereinander zu legen.

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl-Heinz,

ich lese des öfteren, dass solche Probleme mit einer Union gelöst 
werden. Du sselbst hast mir bei einem ähnlich gelagerten Problem auch 
mal geholfen. Das Problem:

MISRA-konformes Programm schreiben. Union verboten. Und nun? Wie kann 
man ein solches Problem lösen ohne Union?

MW

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

Bewertung
0 lesenswert
nicht lesenswert
Michael Wilhelm wrote:
> @ Karl-Heinz,
>
> ich lese des öfteren, dass solche Probleme mit einer Union gelöst
> werden. Du sselbst hast mir bei einem ähnlich gelagerten Problem auch
> mal geholfen. Das Problem:
>
> MISRA-konformes Programm schreiben. Union verboten. Und nun? Wie kann
> man ein solches Problem lösen ohne Union?

Mittels Pointer Tricksereien
  long Result;
  unsigned char* pPtr = (unsigned char*)&Result;

  pPtr[0] = Byte1_von_der_Uart;
  pPtr[1] = Byte2_von_der_Uart;
  pPtr[2] = Byte3_von_der_Uart;
  pPtr[3] = Byte4_von_der_Uart;

  Result verwenden

Eines noch hinten drauf: Ohne 'schmutzige Tricks' geht es nicht.
Letztendlich musst du die einzelnen Bytes eines mehr-Byte Daten-
typs manipulieren. Da steht einem aber immer die Typ-Prüfung des
Compilers im Wege, die man irgendwie austricksen muss.

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Karl-Heinz,

Tricksereien abgespeichert.

Danke vielmals.

MW

Autor: Bartholomäus Steinmayr an der Uni (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Vollständigkeit halber, mit Bitshifts:
long result=Byte1 | (Byte2<<8) | (Byte3<<16) | (Byte4<<24);

Hab allerdings keine Ahnung, was genau der Compiler daraus macht, könnte 
übel sein.

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

Bewertung
0 lesenswert
nicht lesenswert
Bartholomäus Steinmayr an der Uni wrote:
> Der Vollständigkeit halber, mit Bitshifts:
> long result=Byte1 | (Byte2<<8) | (Byte3<<16) | (Byte4<<24);
>

Du hast übersehen, dass das Ergebnis ein long sein muss.
Daher gehen die Shifts für Byte3 und Byte4 in die Hose,
wenn sizeof(long) != sizeof(int)

long result = (long)( Byte1 |
                     ( Byte2 << 8 ) |
                     (((unsigned long)Byte3) << 16 ) |
                     (((unsigned long)Byte4) << 24 ) );

> könnte übel sein.

Spätestens jetzt wird der generierte Code aber ziemlich sicher
richtig übel sein.

Dafür hab ich auf diese Standard-konforme Variante vergessen :-)

Autor: Till (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank erstmal.
An die Shift Option hab ich auch schon gedacht, aber wie komm ich aus 
der ISR zu diesen vier Bytes ?

> pPtr[0] = Byte1_von_der_Uart;
> pPtr[1] = Byte2_von_der_Uart;
> pPtr[2] = Byte3_von_der_Uart;
> pPtr[3] = Byte4_von_der_Uart;

Autor: Till (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich versuchs nochmal:
wie bekomme ich das UDR aus der ISR in Byte 1 bis 4

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

Bewertung
0 lesenswert
nicht lesenswert
Till wrote:
> Ich versuchs nochmal:
> wie bekomme ich das UDR aus der ISR in Byte 1 bis 4

Indem du in der ISR mitzählst um festzustellen das wievielte
mal die ISR aufgerufen wird?

Für jedes Byte wird die ISR einmal aufgerufen.
Ist sie das 4. mal aufgerufen worden, sind alle Bytes angekommen.
Die vorhergehenden 3 Bytes muss man halt irgendwo zwischenspeichern,
bis alle 4 da sind.

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.