32 bit über rs232 einlesen

Gast #845154
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.
#845224
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
1
union _Receiver
2
{
3
  long int Value;
4
  unisgned char Bytes[4];
5
}
6

7
  _Receiver rec;
8

9
  rec.Bytes[0] = Byte1_von_der_Uart;
10
  rec.Bytes[1] = Byte2_von_der_Uart;
11
  rec.Bytes[2] = Byte3_von_der_Uart;
12
  rec.Bytes[3] = Byte4_von_der_Uart;
13
  
14
  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.
Gast #845238
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
#845248
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
1
  long Result;
2
  unsigned char* pPtr = (unsigned char*)&Result;
3

4
  pPtr[0] = Byte1_von_der_Uart;
5
  pPtr[1] = Byte2_von_der_Uart;
6
  pPtr[2] = Byte3_von_der_Uart;
7
  pPtr[3] = Byte4_von_der_Uart;
8

9
  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.
Gast #845259
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.
#845281
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 :-)
Gast #845314
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;
#845514
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

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren