mikrocontroller.net

Forum: Compiler & IDEs Int nach Char und umgekehrt


Autor: ralle (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
unsigned int Data;
unsigned char HiChar, LoChar;

HiChar = Data / 0x100;
LoChar = Data % 0x100;

und hier der code für die umwandlung von den 2 empfangenen chars nach 
int:
unsigned int orig_Data;
unsigned char buffer, buffer1;

orig_Data = ((unsigned int)buffer<<8) | buffer1;

wo is da der fehler?

ich hoffe ihr könnt mir helfen.

Autor: Klaus Wachtler (mfgkw)
Datum:

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

Autor: ralle (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

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

Bewertung
0 lesenswert
nicht 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?

Autor: Volker Zabe (vza)
Datum:

Bewertung
0 lesenswert
nicht 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).

Autor: ralle (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: ralle (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

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

Bewertung
0 lesenswert
nicht 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.

Autor: Oliver (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: ralle (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 :)

Autor: ralle (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
i2c_write_slave(HiChar);
i2c_write_slave(LoChar);
i2c_stop_slave();


//-------------------------------------------------------------------------------------------------

void i2c_write_slave(unsigned char Data)
{
  TWDR = Data;          // Load Data into TWDR Register.
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);    // Clear TWINT bit in TWCR to start transmission of Data

  while(!(TWCR & (1<<TWINT)));      // Wait for TWINT Flag set. This indicates that the Data has been    
              // transmitted, and ACK/NACK has been received.
}

//-------------------------------------------------------------------------------------------------

void i2c_stop_slave(void)
{
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO)|(1<<TWEA);  // Transmit STOP condition
}

das protokoll des masters und die dazugehörigen funktionen sehen so aus:
i2c_start(I2C_SLAVE+READ);
buffer = i2c_read_more();      // HiChar
buffer1 = i2c_read_more();      // LoChar
i2c_stop();


//-------------------------------------------------------------------------------------------------

void i2c_start(unsigned char address)
{
  unsigned char twst;

  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);      // Write START condition

  while(!(TWCR & (1<<TWINT)));        // Wait until transmission completed

  twst = TWSR & 0xF8;          // Check value of TWI Status Register. Mask prescaler bits.

  if( (twst != TW_START) && (twst != TW_REP_START) )  // If status different from START display error
  {                      
    printf_P(start_error);
  }

  TWDR = address;            // Load SLA_R (Slave address and R/W) into TWDR Register.

  TWCR = (1<<TWINT)|(1<<TWEN);

  while(!(TWCR & (1<<TWINT)));        // Wait until transmission completed

  twst = TWSR & 0xF8;          // Check value of TWI Status Register. Mask prescaler bits

  if ( (twst != TW_MT_SLA_ACK) && (twst != TW_MR_SLA_ACK) ) // If ACK not received => address false and device not found
  {
    printf_P(device_error);
  }
}

//-------------------------------------------------------------------------------------------------

void i2c_stop(void)
{
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWSTO);    // Transmit STOP condition

  while(TWCR & (1<<TWSTO));      // Wait until stop condition is executed and bus released
}

//-------------------------------------------------------------------------------------------------

unsigned char i2c_read_more(void)
{
  TWCR = (1<<TWINT)|(1<<TWEN)|(1<<TWEA);    // Clear TWINT bit in TWCR to read a data byte and another data byte (send Master ACK)

  while(!(TWCR & (1<<TWINT)));      // Wait for TWINT Flag set. This indicates that the address/data has
              // been transmitted, and ACK/NACK has been received.

  return TWDR;
}

//-------------------------------------------------------------------------------------------------

unsigned char i2c_read(void)
{
  TWCR = (1<<TWINT)|(1<<TWEN);      // Clear TWINT bit in TWCR to read a data byte (send Master NACK)

  while(!(TWCR & (1<<TWINT)));      // Wait for TWINT Flag set. This indicates that the address/data has
                      // been transmitted, and ACK/NACK has been received.

  return TWDR;
}

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.