Int nach Char und umgekehrt

Gast #1628305
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.
Gast #1628322
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.
#1628326
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?
Gast #1628341
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.
Gast #1628380
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.
#1628386
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.
Gast #1628388
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
Gast #1629476
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
}

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