Forum: Mikrocontroller und Digitale Elektronik Probleme mit Accelerometer LIS3LV02DQ über SPI an ARM7


von Stefan M. (Gast)


Lesenswert?

Hallo,

ich versuche nun schon ein paar Tage den oben genannten Sensor zur 
Kommunikation mit meinem ARM7 über SPI zu bewegen, vielleicht kann mir 
ja hier jemand sagen was ich dabei falsch mache. Die Threads die es zu 
diesem Thema gibt habe ich schon durch, kann dort aber keine Antwort für 
das Problem finden.

Folgendes Problem habe ich:

Wenn ich den Sensor anschließe, kann ich ohne Probleme das WHO_AM_I 
Register auslesen und bekomme auch den richtigen Wert (0x3A) zurück.

Sobald ich aber versuche den LIS3LV02DQ aus dem Powerdown zustand zu 
hohlen, indem ich in das Register CTRL_REG1 den Wert 0x47 oder 0x87 
schreibe, bekomme nur noch falsche Werte vom Sensor zurück. Dies 
passiert bei allen Registern die ich auslesen will.
Konkret schickt mir der LIS3LV02DQ entweder den Wert 0x07, oder das 
Dummy Byte welches ich zum lesen des Wertes geschickt habe zurück. 
Dieser Wert ändert sich auch nicht mehr bis ich den Sensor ausstecke und 
wieder einstecke (also die Spannung vom LIS3LV02DQ nehme und er neu 
bootet).

Konfiguriert habe ich die SPI des ARMS als Master, mit CPHA=1 und 
CPOL=1, MSB first. Die Schnittstelle läuft mit 1 MHz, hab aber auch 
schon niedrigere Werte probiert.

Der ARM7 ist ein LPC2129 /01 von NXP.

Das meine Senderoutine funktioniert, habe ich verifiziert indem ich mir 
mit nem Speicher Oszi die Kommunikation angeschaut habe.

Hier mal ein Ausschnitt der relevanten Teile meines Codes:
1
#define ACC_SENS_WRITE_MS0  0x00
2
#define ACC_SENS_WRITE_MS1  0x40
3
4
#define ACC_SENS_READ_MS0  0x80
5
#define ACC_SENS_READ_MS1  0xC0
6
7
#define ACC_SENS_WHO_AM_I  0x0F
8
#define ACC_SENS_STATUS_REG 0x27
9
10
#define ACC_SENS_CTRL_REG1 0x20
11
#define ACC_SENS_CTRL_REG2 0x21
12
#define ACC_SENS_CTRL_REG3 0x22
13
14
#define ACC_SENS_OUTX_L 0x28
15
#define ACC_SENS_OUTX_H 0x29
16
17
#define ACC_SENS_OUTY_L 0x2A
18
#define ACC_SENS_OUTY_H 0x2B
19
20
#define ACC_SENS_OUTZ_L 0x2C
21
#define ACC_SENS_OUTZ_H 0x2D
22
23
24
void vInitAccSensor(void)
25
{
26
  UINT8 u8cfg = 0;
27
  portENTER_CRITICAL();
28
29
  u8cfg = 0x87;
30
    
31
  SPI0_Enable(1);       //CS auf low
32
  SPI0_ByteTransmit( ACC_SENS_WRITE_MS0 | ACC_SENS_CTRL_REG1);
33
  vTaskDelay(1);
34
  u8cfg = SPI0_ByteTransmit(u8cfg);  //device on, data-rate 40Hz, no selftest, X,Y,Z enabled
35
  SPI0_Disable(1);      //CS auf high
36
37
  portEXIT_CRITICAL()    
38
}
39
40
UINT8 u8AccSensWhoAmI()
41
{
42
   UINT8 u8out;   
43
44
  portENTER_CRITICAL();
45
46
  SPI0_Enable(1);
47
  SPI0_ByteTransmit(ACC_SENS_READ_MS0 | ACC_SENS_WHO_AM_I);
48
  u8out = SPI0_ByteTransmit(0x00);
49
  SPI0_Disable(1);
50
        
51
  portEXIT_CRITICAL();  
52
53
  return u8out;
54
}
55
56
UINT8 SPI0_ByteTransmit(UINT8 u8Data)
57
  {
58
     S0SPDR = u8Data;        // write cData to the spi transmission register
59
     while (!(S0SPSR & 0x80));       // wait for transfer completed
60
    return S0SPDR;           // Return the status written back in the send/receive buffer
61
  }

Ich hoff irgendjemand hat ne Idee warum das bei mir nicht so will wie es 
soll.

Gruß

Stefan

von Stefan M. (Gast)


Lesenswert?

push

von R. W. (quakeman)


Lesenswert?

Also ich kenne mich mit ARM nicht aus, aber ich habe mit einem LPC936 
(8051er) in C mal den LIS3LV02DL erfolgreich angesteuert und ausgelesen. 
Ich glaube mich zu erinnern, dass der DL und der DQ die gleiche Syntax 
haben.

Was mir an deinem Code auffällt ist, dass du in deiner Senderoutine 
SPI0_ByteTransmit() das Transmit Flag zwar auswertest, aber nicht mehr 
löschst. Wird das Flag dann in deiner Hauptroutine wieder gelöscht?

Ansonsten sieht die Ansteuerung des Sensors in deinen Routinen 
eigentlich korrekt aus. Vieleicht hilft es dir ja etwas, wenn du dir mal 
meinen Code dazu anschaust unter [1] und [2]. Ich initialisiere mit 
0xC7, was aber laut Datenblatt identisch zu 0x87 und 0x47 sein sollte.

Ciao,
     Rainer

[1]
https://quakeman.homelinux.net/viewvc/uVision/trunk/Test_LIS3LV02DL_SPI/Test_LIS3LV02DL_SPI.c?view=markup

[2]
https://quakeman.homelinux.net/viewvc/uVision/trunk/Test_LIS3LV02DL_SPI/Test_LIS3LV02DL_SPI.h?view=markup

von Stefan M. (Gast)


Lesenswert?

Erstmal vielen Dank für deine Antwort.

Zur Senderoutine, das Flag muss nicht von Hand gelöscht werden, laut 
Datenblatt wird das Flag gelöscht, wenn man das S0SPSR Register und 
anschließend das Datenregister S0SPDR ausliest. Dies ist ja bei mir der 
Fall. Ausserdem weis ich ja das Daten gesendet werden und ich auch 
wieder Daten zurück bekomme, da ich das ganze mit einem Oszilloskop 
gemessen habe. Auf den Leitungen ist alles so wie erwartet, mit der 
Ausnahme das ich einfach nicht die richtigen Daten zurück bekomme.

Um den Sensor aus dem Powerdown Zustand zu bekommen sehe ich das genau 
so wie du, die beiden Bits dürfen einfach nicht 00 sein. (Ich hab aber 
auch schon die anderen Varianten 0xC7, 0x47 und 0x87 durchprobiert, 
gleiches Ergebnis...)

Mitlerweile bin ich aber der Meinung das mit dem Beschleunigungssensor 
irgendwas faul ist, da der Pegel der SDO Leitung nicht stimmt. Er müsste 
eigentlich laut Datenblatt mindestens 0,8*VDD sein, also in meinem Fall 
mit VDD = 3,1 V ca 2,5 V. Ich messe aber nur einen Pegel von ca 1,8 V.

Ich werd mal schaun ob sich noch ein weiterer Sensor auftreiben lässt, 
da ich nicht der erste bin der sich an genau diesem Sensor versucht hat 
und ich nicht genau weiß was damit vor mir alles angestellt wurde.

Gruß Stefan

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.