Forum: Compiler & IDEs Int nach Char und umgekehrt


von ralle (Gast)


Lesenswert?

hi,

hab grad nen problem mit der umwandlung von int nach char und umgekehrt. 
hab auch keine lösung gefunden warum es nicht funktioniert.

ich will auf einem uC eine int variable in 2 chars umwandeln damit ich 
die per I2C übertragen kann. auf dem anderen uC sollen diese beiden 
chars empfangen werden und wieder zur ursprünglichen int variable 
zusammengesetzt werden. die I2C übertragung funktioniert, auch werden 
die beiden chars in der richtigen reihnfolge gesendet bzw. empfangen. 
ich sende erst den high char und dann den low char. ebenso empfange ich 
die beiden in der gleichen reihnfolge

hier mal der code für die umwandlung eines int in 2 chars:
1
unsigned int Data;
2
unsigned char HiChar, LoChar;
3
4
HiChar = Data / 0x100;
5
LoChar = Data % 0x100;

und hier der code für die umwandlung von den 2 empfangenen chars nach 
int:
1
unsigned int orig_Data;
2
unsigned char buffer, buffer1;
3
4
orig_Data = ((unsigned int)buffer<<8) | buffer1;

wo is da der fehler?

ich hoffe ihr könnt mir helfen.

von Klaus W. (mfgkw)


Lesenswert?

Auf den ersten Blick sehe ich kein Problem.
Wie äußert sich denn der Fehler?

von ralle (Gast)


Lesenswert?

danke für die antwort.

ich sollte eigentlich einen wert von 880 +- 10 erhalten. halt ein 
relativ schwankender wert, aber das sollte ja kein problem sein. ich 
empfange allerdings einen wert von 65281 konstant.

hab auch mal die reihnfolge der empfangenen chars vertauscht. dann 
bekommen ich einen wert von 511 konstant.

von Karl H. (kbuchegg)


Lesenswert?

ralle schrieb:
> danke für die antwort.
>
> ich sollte eigentlich einen wert von 880 +- 10 erhalten. halt ein
> relativ schwankender wert, aber das sollte ja kein problem sein. ich
> empfange allerdings einen wert von 65281 konstant.
>
> hab auch mal die reihnfolge der empfangenen chars vertauscht. dann
> bekommen ich einen wert von 511 konstant.

Sieh dir die einzelnen Byes an, ehe du sie zusammensetzt. Stimmen die 
noch?

von Volker Z. (vza)


Lesenswert?

Du sendest oder empfängst was anderes.
Sende einen konstanten Wert und beobachte den spi-bus.
Dann weist du ob du fasche werte Sendest oder Empfängst (oder beides).

von ralle (Gast)


Lesenswert?

ich glaube jetzt will mich mein uC veräppeln :)

die einzelnen bytes stimmen nicht mehr. voher stimmten sie 
lustigerweise. ich empfange jetzt als high byte ein 255 und als low byte 
1. damit komme ich auf diese 65281.

ok d.h. ich muss meinen fehler erstmal woanders suchen. aber gut zu 
wissen das die umwandlung schonmal korrekt ist :)

danke nochmals.

von ralle (Gast)


Lesenswert?

es scheint so als ob die umrechnung von int nach char nicht richtig 
funktionieren würde.

hab, wie Volker verschlug, mal einen konstanten wert verschickt. hab 
dabei 34952 gewählt, was binär 0b1000 1000 1000 1000 entspricht. 
demzufolge müsste ich den gleichen wert für das high und low byte 
erhalten, nämlich 136.

das high byte wird allerdings mit 135 empfangen und das low byte mit 1. 
aber ich sehe wirklich nicht wo da der fehler liegen könnte bei dieser 
umwandlung.

von Karl H. (kbuchegg)


Lesenswert?

ralle schrieb:
> es scheint so als ob die umrechnung von int nach char nicht richtig
> funktionieren würde.

Hast du das kontrolliert?

Sieh dir die Bytes nach der Zerlegung an.

> hab, wie Volker verschlug, mal einen konstanten wert verschickt. hab
> dabei 34952 gewählt, was binär 0b1000 1000 1000 1000 entspricht.
> demzufolge müsste ich den gleichen wert für das high und low byte
> erhalten, nämlich 136.

Keine gute Idee.
Nimm einen Wert, der unterschiedliches High und Low Byte ergibt. Dann 
siehst du dann auch gleich ob die Reihenfolge stimmt.

> aber ich sehe wirklich nicht wo da der fehler liegen könnte bei dieser
> umwandlung.

Wir auch nicht.
Aber der Fehler muss auch nicht dort liegen.
Die einzelnen Bytes zu haben ist ja erst die halbe Miete. Mit denen 
passiert ja noch so einiges, ehe sie beim Empfänger wieder eintreffen 
und zusammengesetzt werden. An jeder einzelnen Stelle dazwischen, kannst 
du iregendwo einen Fehler gemacht haben.

Also: Die komplette Kette vom int weg testen und die Zwischenergebnisse 
ansehen. Nimm nichts als gesichert an! Bezweifle alles und jedes so 
lange bis du es getestet und kontrolliert hast.

von Oliver (Gast)


Lesenswert?

>aber ich sehe wirklich nicht wo da der fehler liegen könnte bei dieser
>umwandlung.

Da deine beiden oben gezeigten Umwandlungen richtig sind, wird der 
Fehler wohl irgendwo dazwischen liegen.

Oliver

von ralle (Gast)


Lesenswert?

also die umwandlung von den 2 empfangenen chars zu int funktioniert 
schonmal.

werd die restlichen einzelnen schritte ebenfalls noch nachprüfen, 
irgendwo muss der fehler sich versteckt haben :)

von ralle (Gast)


Lesenswert?

mahlzeit,

habe nun herausgefunden wo das problem liegt. die übertragung per I2C 
stimmt nicht. daher hab ich erstmal die verschidenen codeschnipsel hier 
im forum und über google zusammengesucht und festgestellt das meine 
version absolut identisch ist mit dem was ich gefunden habe.

das problem äußert sich so, dass der slave konstante werte für das high 
byte von 128 und das low byte von 8 per I2C überträgt. anstatt 128 und 8 
empfängt der master die werte 8 für high byte und 1 für low byte.

es scheint so als ob das high byte immer um 4 stellen nach rechts 
verschoben ist, und das low byte nur um 3 stellen nach rechts.

ich poste mal meine I2C funktionen, vllt fällt euch ja etwas falsches 
daran auf.

hier mal das protokoll und funktionen für den I2C slave atmega.
1
i2c_write_slave(HiChar);
2
i2c_write_slave(LoChar);
3
i2c_stop_slave();
4
5
6
//-------------------------------------------------------------------------------------------------
7
8
void i2c_write_slave(unsigned char Data)
9
{
10
  TWDR = Data;          // Load Data into TWDR Register.
11
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);    // Clear TWINT bit in TWCR to start transmission of Data
12
13
  while(!(TWCR & (1<<TWINT)));      // Wait for TWINT Flag set. This indicates that the Data has been    
14
              // transmitted, and ACK/NACK has been received.
15
}
16
17
//-------------------------------------------------------------------------------------------------
18
19
void i2c_stop_slave(void)
20
{
21
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO)|(1<<TWEA);  // Transmit STOP condition
22
}

das protokoll des masters und die dazugehörigen funktionen sehen so aus:
1
i2c_start(I2C_SLAVE+READ);
2
buffer = i2c_read_more();      // HiChar
3
buffer1 = i2c_read_more();      // LoChar
4
i2c_stop();
5
6
7
//-------------------------------------------------------------------------------------------------
8
9
void i2c_start(unsigned char address)
10
{
11
  unsigned char twst;
12
13
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);      // Write START condition
14
15
  while(!(TWCR & (1<<TWINT)));        // Wait until transmission completed
16
17
  twst = TWSR & 0xF8;          // Check value of TWI Status Register. Mask prescaler bits.
18
19
  if( (twst != TW_START) && (twst != TW_REP_START) )  // If status different from START display error
20
  {                      
21
    printf_P(start_error);
22
  }
23
24
  TWDR = address;            // Load SLA_R (Slave address and R/W) into TWDR Register.
25
26
  TWCR = (1<<TWINT)|(1<<TWEN);
27
28
  while(!(TWCR & (1<<TWINT)));        // Wait until transmission completed
29
30
  twst = TWSR & 0xF8;          // Check value of TWI Status Register. Mask prescaler bits
31
32
  if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) // If ACK not received => address false and device not found
33
  {
34
    printf_P(device_error);
35
  }
36
}
37
38
//-------------------------------------------------------------------------------------------------
39
40
void i2c_stop(void)
41
{
42
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);    // Transmit STOP condition
43
44
  while(TWCR & (1<<TWSTO));      // Wait until stop condition is executed and bus released
45
}
46
47
//-------------------------------------------------------------------------------------------------
48
49
unsigned char i2c_read_more(void)
50
{
51
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);    // Clear TWINT bit in TWCR to read a data byte and another data byte (send Master ACK)
52
53
  while(!(TWCR & (1<<TWINT)));      // Wait for TWINT Flag set. This indicates that the address/data has
54
              // been transmitted, and ACK/NACK has been received.
55
56
  return TWDR;
57
}
58
59
//-------------------------------------------------------------------------------------------------
60
61
unsigned char i2c_read(void)
62
{
63
  TWCR = (1<<TWINT)|(1<<TWEN);      // Clear TWINT bit in TWCR to read a data byte (send Master NACK)
64
65
  while(!(TWCR & (1<<TWINT)));      // Wait for TWINT Flag set. This indicates that the address/data has
66
                      // been transmitted, and ACK/NACK has been received.
67
68
  return TWDR;
69
}

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.