Hallo an alle,
hier mal ein Programmschnippsel für die Neugierigen, die wissen wollen wie es geht: (Und es geht gut!)
Code:
/*----------------------------------------------------------------------------
Defines: Adresse vom BMA020-3D-Beschleunigungssensor
*/
#define I2C_BMA_W 0x70
#define I2C_BMA_R 0x71
int16_t x, y, z;
uint8_t ret;
/*
Lesen von 6 Registern ab Register 0x02. X, Y, Z-Koordinate
*/
ret = StartI2C (I2C_BMA_W);
ret = WriteI2C (0x02);
StopI2C ();
ret = StartI2C (I2C_BMA_R);
ret = ReadI2C (ACK); x = (int16_t)ret;
ret = ReadI2C (ACK); x = x | ((int16_t)ret << 8); x /= 64;
ret = ReadI2C (ACK); y = (int16_t)ret;
ret = ReadI2C (ACK); y = y | ((int16_t)ret << 8); y /= 64;
ret = ReadI2C (ACK); z = (int16_t)ret;
ret = ReadI2C (NAK); z = z | ((int16_t)ret << 8); z /= 64;
StopI2C ();
Um z.B. das Status-Register 14 (Hex) auszulesen macht man folgendes:
Code:
/*----------------------------------------------------------------------------
Defines: Adresse vom BMA020-3D-Beschleunigungssensor
*/
#define I2C_BMA_W 0x70
#define I2C_BMA_R 0x71
/*
Lesen des Status-Registers 0x14 : reserviert:7:5 range:4:3 bandwidth:2:0
*/
uint8_t ret, r14;
uint8_t range;
ret = StartI2C (I2C_BMA_W);
ret = WriteI2C (0x14);
StopI2C ();
ret = StartI2C (I2C_BMA_R);
r14 = ReadI2C (NAK);
StopI2C ();
range = (r14 & 0b00011000) >> 3;
Und bei mir betrug die Lieferzeit nur ca. 10 Tage. Jippie 
Gruß
Sternthaler
[edit 11.10.2010]
Auf Wunsch eine kleine Erklärung für die Berechnung der x-, y-, z-Werte.
Für X steht im oberen Code-Block folgendes:
Zeile 1) ret = ReadI2C (ACK); x = (int16_t)ret;
Zeile 2) ret = ReadI2C (ACK); x = x | ((int16_t)ret << 8 ); x /= 64;
In Zeile 1) wird beim ersten ReadI2C der Wert vom Register 0x02 aus dem Chip gelesen. Darin sind nur die beiden obersten Bit relevant für das X-Ergebnis. Es sind die beiden untersten Bits vom gesamten 10-Bit-Messwert.
Trotzdem wird diese Byte nun als 16-Bitwert in der Variablen x gespeichert.
In Zeile 2) wird mit dem nächsten ReadI2C das Register 0x03 aus dem Chip gelesen. (Die Adresse wird automatisch vom Chip hochgezählt.)
Dahinter wird nun das in Zeile 1) gelesene BIT-Muster mit |-Zeichen und dem in Zeile 2) gelesenen und mit dem <<8 um 8 BIT nach links geschobenem Registerwert aus 0x03 'verbunden'.
=> 0000 0000 ??-- ----: Die 2 Bits aus Zeile 1) in der 16-Bit-Variablen x
Bit-ODER-Verknüpft (|-Zeichen) mit dem um 8 Bit nach links geschobenem Wert aus Zeile 2)
=> ???? ???? 0000 0000: Die oberen 8 Bit vom Messwert. Ergibt:
----------------------------
=> ???? ???? ??-- ----
Die ? sind also nun die 10 Bit Messergebnis
Die - sind Bits, die auch gelesen wurden, aber hier nicht interessieren.
Die 0 sind Bits, die wir bewusst gesetzt hatten.
Jetzt noch in Zeile 2) mit dem x /= 64 diese Ergebnis einfach um 6 Bit nach rechts schieben. (Man kann auch schreiben x = x / 64
Man hätte auch x = ( x | ((int16_t)ret << 8 ) ) >> 6; schreiben können. Das macht der Compiler sowiso daraus.
Also ist das Ergebnis nun:
=> 0000 00?? ???? ????
Und damit haben wir die 10 Bit X-Messwert 'greifbar'.
ACHTUNG: Das höchste ?-Bit ist ein Vorzeichen.
Die Zählweise für den Betrag des Wertes kann man am besten in der Doku nachlesen.
Datenblatt: BMA020
Die Register sind auf Seite 9 beschreiben.
Die Zählweise vom Ergebnis ist auf Seite 21.
Viel Spaß beim Lesen wünscht
Sternthaler
Lesezeichen