Beschleunigungssensor ADXL345 Probleme bei der SPI Kommunikation

Gast #3918205
Lesenswert?

Hallo,

ich versuche seit Tagen, die Kommunikation mit einem ADXL345 
Beschleunigungssensor herzustellen. Leider ohne Erfolg.

Mitlerweile beschränke ich mich auf den Versuch, einfach nur die Device 
ID auszulesen. Aber selbst das gelingt nicht.

Zuerst habe ich versucht, die AVR interne USI Schnittstelle zu 
verwenden, als ich nach zwei Tagen immer noch keine Daten vom ADXL345 
erhielt, habe ich die Kommunikation vollständig in Software umgesetzt, 
um auszuschließen, dass ich bei der Verwendung der USI einen Fehler 
mache.

Leider bietet sich mir exakt das gleiche Bild wie mit der USI.


Habe Euch im Anhang mal die Timing Diagramme angehängt:
1. Timing Diagramm aus dem Datenblatt
2. Timing Diagramm meines Programms 1
3. Timing Diagramm meines Programms 2

Die Zustände in Diagramm 2 und 3 wechseln sich in regelmäßigen Abständen 
ab.

Der Sensor ist per 4 Wire SPI angeschlossen.

Die Zeiten(s. Datenblatt S. 17):
insbesondere:
-tDELAY (CS falling edge to SCLK falling edge)
-tQUIET (SCLK rising edge to CS rising edge)
-tSETUP (SDI valid before SCLK rising edge)

werden eingehalten(delays im Programm).

Link zum Datenblatt des ADXL345:
http://www.analog.com/static/imported-files/data_sheets/ADXL345.pdf
Ab Seite 15 geht die Beschreibung der SPI Kommunikation los.


Viele Grüße und für jeden hilfreichen Beitrag Danke im Vorraus!
Stefan
Angehängte Dateien:
Gast #3918232
Lesenswert?

>Leider ohne Erfolg.

Geht's auch genauer?

>als ich nach zwei Tagen immer noch keine Daten vom ADXL345
>erhielt,

Deine Oszillogramme zeigen das Gegenteil...

Was steht nach der Übertragung eines Bytes im
SPI RX Datenregister?
Gast #3918244
Lesenswert?

Gartenzwergleiche schrieb:
> Was steht nach der Übertragung eines Bytes im
> SPI RX Datenregister?

Lese ich mitlerweile gar nicht mehr aus, da die Oszillogramme ja schon 
Murks zeigen!?

Ich sende ja immer nur: Befehl lesen (R = 1, Bit 7), einfache 
Übertragung(MB = 0, Bit 6) und Adresse 0x00 (Bits 5:0), so dass ja 
eigentlich nur die Device ID ausgegeben werden muss.

Diese lautet 11100101

Danke unf Gruß
Stefan
Gast #3919071
Lesenswert?

Nabend,

im Bildanhang mal die Zeichenfolge die ich erhalte. Der wechsel zwischen 
0x00 und 0xE6 ist mir nicht ganz klar, wie dieser Zustande kommt. Genau 
so wenig aber auch, warum 0xE6 und nicht 0xE5 (Device ID)


Hier der Code
1
#include <avr/io.h>
2
 
3
//#define F_CPU 8000000UL
4
#define F_CPU 3686400UL
5

6
#include <util/delay.h>
7
#include "usi_isp.c"
8

9
void uart_init(void)   
10
{
11
   #define BAUD 9600
12
   #include <util/setbaud.h>
13
  /* Set baud rate */
14
  UBRRH = UBRRH_VALUE;
15
  UBRRL = UBRRL_VALUE;
16
     #if USE_2X
17
   UCSRA |= (1 << U2X);
18
   #else
19
   UCSRA &= ~(1 << U2X);
20
   #endif
21
  //  Enable receiver and transmitter 
22
  UCSRB = (1<<RXEN)|(1<<TXEN);
23
  // Set frame format: 8data, 
24
  UCSRC = (3<<UCSZ0);
25

26
}  
27

28
 
29
int main (void)
30
{
31

32
  uart_init();
33
  spi_init();
34
   
35
  while (1)
36
  {                         
37
    UDR = spi_read_byte(0x00);
38
    _delay_ms(100);
39
  }
40

41
return 0;
42
}

Datei usi_isp.c
1
#include <avr/io.h>
2
#include <util/delay.h>
3

4
//#define SPI_CLK 12500   // spi clock 
5

6
#define CS_PIN PB4    // chip select pin
7
#define CS_REG PORTB  // chip select register
8
#define SPI_DEVICE_T_DELAY 1
9

10
// SPI port and pin definitions.
11

12
#define SPI_PORT  PORTB  //!< SPI port output register.
13
#define SPI_PIN_REG  PINB  //!< SPI port input register.
14
#define SPI_DIR_REG  DDRB  //!< SPI port direction register.
15
#define SPI_CLOCK_PIN  PB7  //!< SPI clock I/O pin.
16
#define SPI_DATAIN_PIN  PB5  //!< SPI data input pin.
17
#define SPI_DATAOUT_PIN  PB6  //!< SPI data output pin.
18
#define SPI_CS_PIN  PB4    //!< SPI Cock Select pin.
19

20

21
void spi_init(){
22
  // outputs
23
  SPI_DIR_REG |= ( 1<< SPI_CLOCK_PIN | 1<< SPI_CS_PIN );
24
  // inputs
25
  // when 4  wire mode is choosen, define DI- and DO- pin mode here
26
}
27

28

29
void spi_chip_enable()
30
{
31
  CS_REG &= ~(1<<CS_PIN); // ~CS = 0 -> enable slave device;
32
  _delay_us(10);  //später durch _delay_cycles ersetzen
33
}
34

35
void spi_chip_disable()
36
{
37
   // _delay_us(SPI_DEVICE_T_DELAY);  // see ADXL345 Data Sheet Figure 37 to 39
38
  _delay_us(10);  //später durch _delay_cycles ersetzen!
39
  CS_REG |= (1<<CS_PIN); // ~CS = 1 -> disable slave device;
40
}
41

42

43
//**************************************************************
44
//***********[ READ BYTE FROM SPI without USI ]*****************
45
//**************************************************************
46

47
unsigned char spi_read_byte( unsigned char address ){
48

49
  unsigned char cnt, data; 
50

51
 //******************** transmitt byte *********************************
52

53
  // configure IO pin functions (not nessesary for 4-wire spi but for 3 wire mode)
54
  SPI_DIR_REG |= ( 1<< SPI_DATAOUT_PIN);  //!< USI port direction register
55
 
56
  // 0x80: read(single byte) mode
57
  data = ( 0x80 | (address & 0x3F) );
58
  cnt = 0;
59

60
  spi_chip_enable();
61

62
  if( ( (data << cnt) & 0x80 ) )    
63
    SPI_PORT |= (1<< SPI_DATAOUT_PIN);  //  
64
  else
65
    SPI_PORT &= ~(1<< SPI_DATAOUT_PIN);  // 
66

67
  _delay_ms(1); // t_delay (ADXL345)
68

69
  //  generate SLK
70
  SPI_PORT &= ~(1<< SPI_CLOCK_PIN);  //  
71
  _delay_ms(20); //  _delay_us(1000000/(2*SPI_CLK));
72
  SPI_PORT |= (1<< SPI_CLOCK_PIN);  //
73
  _delay_ms(20); //  _delay_us(1000000/(2*SPI_CLK));
74
  cnt++;
75

76
  do{
77
    // transmitt data
78
    if( ( (data << cnt) & 0x80 ) )    
79
      SPI_PORT |= (1<< SPI_DATAOUT_PIN);  //  
80
    else
81
      SPI_PORT &= ~(1<< SPI_DATAOUT_PIN);  // 
82
    
83
    //  generate SLK
84
    SPI_PORT &= ~(1<< SPI_CLOCK_PIN);  //  
85
    _delay_ms(20); //  _delay_us(1000000/(2*SPI_CLK));
86
    SPI_PORT |= (1<< SPI_CLOCK_PIN);  //
87
    _delay_ms(20); //  _delay_us(1000000/(2*SPI_CLK));
88

89
    cnt++;
90

91
  }while ( cnt < 8 ); // stop when 8bits are transmitted
92

93
  //******************** receive byte *******************************
94

95
  // configure IO pin functions (not nessesary for 4-wire spi but for 3 wire mode)
96
  SPI_DIR_REG &= ~( 1<< SPI_DATAIN_PIN);  // 
97
  SPI_PORT |= ( 1<< SPI_DATAIN_PIN);
98
  cnt = 0;
99
  data = 0;
100

101
  do{   
102
    //  generate SLK
103
    SPI_PORT &= ~(1<< SPI_CLOCK_PIN);
104
    _delay_ms(20); //  _delay_us(1000000/(2*SPI_CLK));
105
    SPI_PORT |= (1<< SPI_CLOCK_PIN);  //
106
    
107
     // read data from pin DI (sample on rising edge)
108
    if( SPI_PIN_REG & ( 1<< SPI_DATAIN_PIN) ) 
109
     data |= ( 1 << cnt );
110

111
    _delay_ms(20); //  _delay_us(1000000/(2*SPI_CLK));
112

113
     cnt++;
114
   }while ( cnt < 8 ); // stop when 8 bits are transmitted
115
 
116

117
  spi_chip_disable();
118

119
return data;
120
}


Einen Schaltplan müsste ich noch erstellen, ist ein fertiges Modul aus 
dem Netz 
http://hobbycomponents.com/other/431-gy-291-adxl345-triple-axis-accelerometer

SDI, SDA, SCL, CS liegen jedenfalls über Pullups an Vcc

Grüße
Stefan
Gast #3920819
Lesenswert?

Guten Abend,

durch Zufall habe ich die Schaltung zum Laufen bekommen. Der Zufall 
sieht so aus, dass ich dem ADXL345 die GND leitung durchtrennt habe. Er 
verfügt jetzt also nicht mehr über GND, sondern nur SDA,SDO, SLC, und 
CS.

Habe gerade nochmal alle Spannungspegel überprüft und die Qualität mit 
dem Oszilloskop untersucht. Ergebnis, alles einwandfrei.

Da breche ich mir seit jetzt bald einer Woche einen ab und verstehe die 
Welt nicht mehr und jetzt entferne ich durch zufall GND und alles 
geht???

Kann sich das jemand logisch erklären oder hat schonmal ein Ähnliches 
Problem gehabt?

Viele Grüße
Stefan
#3920836
Lesenswert?

Stefan schrieb:
> durch Zufall habe ich die Schaltung zum Laufen bekommen. Der Zufall
> sieht so aus, dass ich dem ADXL345 die GND leitung durchtrennt habe. Er
> verfügt jetzt also nicht mehr über GND, sondern nur SDA,SDO, SLC, und
> CS.

Klingt nicht gut.
Das Ding hat ja 3 GND-Pins.
Schaltplan (original!) wäre interessant. Besonders die Verschaltung von 
Pin 3 und 11.
Gast #3920847
Lesenswert?

Wie gesagt, ist ein fertiges Modul gewesen.
http://hobbycomponents.com/other/431-gy-291-adxl345-triple-axis-accelerometer

Werde mich morgen in Ruhe mal dran setzen und das Modul untersuchen und 
einen Schaltplan erstellen. Wobei die Dinger ja in Tausenden verkauft 
werden. Würde daher einen schwerwiegenden Fehler im Schaltplan 
ausschließen.

Es kann ja eigentlich nur ein Bauteil- oder Lötstellendefekt sein.

Gruß
Stefan
Gast #3921078
Lesenswert?

Detlef Kunz schrieb:
> Wie erzeugst Du die Beriebsspannung für den AVR und wie hoch ist die?
> Abblockkondensatoren drin? Der Schaltplan wäre auch sehr
> aufschlussreich.

Der Avr steckt in einem STK500 und die Bertriebsspannung erzeuge ich 
über den boardeigenen VTarget Generator. Habs zwischendrin aber auch 
über externe Spannung versucht, hat auch nicht geholfen.

Gru0
Stefan
Gast #3921141
Lesenswert?

Stefan schrieb:
> Detlef Kunz schrieb:
>> Wie erzeugst Du die Beriebsspannung für den AVR und wie hoch ist die?
>> Abblockkondensatoren drin? Der Schaltplan wäre auch sehr
>> aufschlussreich.
>
> Der Avr steckt in einem STK500 und die Bertriebsspannung erzeuge ich
> über den boardeigenen VTarget Generator. Habs zwischendrin aber auch
> über externe Spannung versucht, hat auch nicht geholfen.
>
> Gru0
> Stefan

Nagut, aber wie hoch ist die Betriebsspannung, weil mit 5V wäre das ganz 
schlecht.
Du musst den AVR mit 3.3v betreiben, weil der ADXL auch mit 3.3v 
arbeitet (die kleine Platine hat einen eigenen Spannungsregler).

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