PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : I2C - 16Bit übertragen



aircode
09.12.2009, 21:01
Hallo I2C Profis,

schön langsam komme ich mit dem I2C klar und ich kann vom Slave zum Master und umgekehrt Werte hin und her verschieben wie ich will. Allerdings leider nur Werte bis 255! Eigentlich eh klar, da ja das Leseregister mit 8Bit deklariert ist, sehe ich das richtig?

Wie sieht es aber dann aus, wenn ich 16Bit Variablen in das Leseregister schreiben will?

Zur Veranschaulichung hier ein kleines Beispiel -> siehe mein Kommentar!

Danke...




#include "RP6RobotBaseLib.h"
#include "RP6I2CslaveTWI.h"

// ************************************************** ************************************************** ******
// ************************************************** ************************************************** ******
// ****************************************** ***********************************************
// ****************************************** Hauptprogramm ***********************************************
// ****************************************** ***********************************************
// ************************************************** ************************************************** ******
// ************************************************** ************************************************** ******

int main(void)
{
initRobotBase();
I2CTWI_initSlave(10);
powerON();

task_ADC();

while(true)
{
if(!I2CTWI_readBusy)
I2CTWI_readRegisters[0] = 255; // Alles funktioniert so lange der Wert <=255 ist - leider ;-)

if (bumper_left) // wird der Bumper gedrückt wird der Wert im Terminal ausgegeben
{
writeString("\n");
writeString("Wert: ");writeIntegerLength(I2CTWI_readRegisters[0], DEC, 5);writeString("\n");
}
task_Bumpers();
}

return 0;
}

021aet04
09.12.2009, 21:15
Du musst die Daten dann in mehrere 8bit Teile splitten.

aircode
09.12.2009, 21:25
Hab ich schon gemacht - dachte nur, es gäbe eine einfachere Lösung :-k

SlyD
09.12.2009, 22:56
Schau Dir das I2C Protokoll an - da werden nunmal (wie auch bei UART und SPI und ... ) immer Bytes übertragen.

Einfach eine passende Funktion schreiben!
Schau Dir z.B. die Funktion "move" im RP6Control_10_move2 / RP6Control_I2CMasterLib.c an. Dort werden 16 Bit Werte übertragen.
Die umgekehrte Richtung findest Du im I2C Slave programm Zeile 365.


Das lässt sich natürlich auch auf 32 Bit erweitern.

MfG,
SlyD

aircode
10.12.2009, 00:23
Habe es immo so gelöst, dass ein Wert (z.B. 599) im Slave durch 255 dividiert wird und dann der Quotient sowie der Rest (in dem Fall 89) an den Master übergeben wird. Dort dann wieder zurück gerechnet komme ich wieder auf die 599.

Etwas kompliziert und deshalb gut zu wissen, dass es auch mit 16bit oder 32bit usw. geht...

Werde das morgen durch ackern... Für heute raucht mein Kopf schon genug... und die Akkus vom RP6 sind auch leer :-)

radbruch
10.12.2009, 01:03
Hallo

Du solltest besser durch 256 dividieren.

Ein 2-Byte-Wert ist 256*highbyte+lowbyte. Bit0 des Highbytes ist auch Bit8 der 16bit-Variablen und hat die Wertigkeit 2^8=256.
Mit 255 funktioniert es nur bei Werten die kleiner als 256*255-1 sind, in eine 16Bit-Variable passen aber 256*256-1=65535 Werte.

Klassisch macht man das wohl so wie bei der Baudratenberechnung:

highbyte = 16bit-Variable >> 8;
lowbyte = (uint8_t) 16bit-Variable;

Und zurückrechnen geht so:

16bit-Variable=256*highbyte+lowbyte;

Gruß

mic

aircode
10.12.2009, 14:56
Du solltest besser durch 256 dividieren.

Bei meiner Division habe ich eh schon 256 verwendet!

Aber trotzdem Danke für deinen Lösungsansatz mit der Bit-Verschiebung... Ist zwar auf den ersten Blick die verwirrendere Lösung, aber wenn man's einmal kapiert hat wie die Verschiebung um 8Bit funzt (hab die letzte halbe Stunde mit Nullen und Einsern herumjoungliert) eindeutig die elegantere. Werde ich zu Hause gleich mal umschreiben...

THX

Aircode