Forum: Compiler & IDEs 32 bit über rs232 einlesen


von Till (Gast)


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.

von Karl H. (kbuchegg)


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.

von Michael Wilhelm (Gast)


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

von Karl H. (kbuchegg)


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.

von Michael Wilhelm (Gast)


Lesenswert?

@ Karl-Heinz,

Tricksereien abgespeichert.

Danke vielmals.

MW

von Bartholomäus Steinmayr an der Uni (Gast)


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.

von Karl H. (kbuchegg)


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 :-)

von Till (Gast)


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;

von Till (Gast)


Lesenswert?

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

von Karl H. (kbuchegg)


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.

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.