Forum: Mikrocontroller und Digitale Elektronik MMA7455 über SPI an AVR


von Thomas L. (zengaja)


Lesenswert?

Hallo,
ich versuch ein Freescale MMA4755 Accelerometer an meinem ATMEGA32 zu 
betreiben, leider ohne Erfolg.

Habe alles gemäß Datenblatt verbunden:
ATMEGA32-------MMA7455
  SS(PB4) ->   CS
 SCK(PB7) ->   SPC
MOSI(PB5) ->   SDI
MISO(PB6) ->   SDA

DVDD und AVDD werden mit etwa 2.5 V versorgt.
Die Initialisierungsprozedur aus der Freescale Appnote 
http://www.freescale.com/files/sensors/doc/app_note/AN3468.pdf
hab ich für AVR, meiner Meinung nach korrekt, angepasst.
1
uint8_t Xdata, Ydata,Zdata,CTLReg;
2
3
void spi_master_init(void)
4
{
5
    // MOSI and SCK output, Rest Input
6
    DDRB = (1<<PB5)|(1<<PB7);
7
    // Enable SPI, Master, set clock rate 16MHz/128 = 125 KHz
8
     SPCR = (1<<SPIE)|(1<<SPE)|(1<<SPR1) | (1<<SPR0)|(1<<MSTR);
9
    SPCR &= ~((1<<SPR1) | (1<<SPR0));
10
    SPSR |= (1<<SPI2X);
11
}    
12
13
void spi_write(uint8_t reg, uint8_t data)
14
{
15
  
16
  uint8_t x;
17
  PORTB &= ~(1 << PB4);  // SS auf LOW während der Übertragung
18
  SPDR = (((reg & 0x3F)<<1)|0x80); //Write Befehl an Register Senden
19
  while((!SPSR & (1<<SPIF)));//Warten bis Transfer abgeschlossen ist
20
  x = SPDR;//dummy read
21
  SPDR = data;
22
  while((!SPSR & (1<<SPIF)));
23
  x = SPDR;//dummy read
24
  PORTB |= (1 << PB4);  // SS auf HIGH zum Beenden der Übertragung
25
}
26
27
uint8_t spi_read(uint8_t reg)
28
{
29
  uint8_t x;
30
  PORTB &= ~(1 << PB4);
31
  x = SPSR;         // clear SPIF
32
  x = SPDR;
33
  while((SPSR & (1<<SPIF)));//Warten bis SPIF gelöscht ist
34
  SPDR = ((reg & 0x3F)<<1); //Read Befehl an Register Senden
35
  while((!SPSR & (1<<SPIF)));//Warten bis Transfer abgeschlossen ist
36
  x = SPDR;
37
  SPDR = 0x00;//Daten werden mit dem Nächsten Transfer gesendet
38
  while((!SPSR & (1<<SPIF)));//Warten bis Transfer abgeschlossen ist
39
  x = SPDR; //Empfangene Daten Auslesen
40
  PORTB |= (1 << PB4);
41
  return x;
42
  
43
}
44
45
46
int main (void)
47
{
48
 init();
49
 spi_master_init();
50
 Xdata=Ydata=Zdata=0;
51
 CTLReg=0;
52
 spi_write(0x16,0x05);//set spi 4-wire mode in MMA7455
53
 CTLReg=spi_read(0x16);
54
55
 while(1)
56
  {  
57
   Xdata = spi_read(0x6);
58
  }
59
60
}

Als Antwort bekomme ich auf allen Registern aber immer nur 0xFF.
Weder an der Clock noch an der Data-Leitung tut sich laut Oszi was. SS 
bewegt sich ein bisschen.

Wenn ich den Sensor aus der Schaltung rausnehme gibts nen Anständigen 
Takt und auf der Datenleitung passiert auch was. SS sieht genau so aus 
wie vorher.
Das Heißt von AVR-Seite mache ich schonmal irgendwas richtig.

Nun bin ich etwas Ratlos, wo genau das Problem liegt. Sensor kann 
natürlich kaputt sein, hab aber noch nen zweiten getestet, da das 
gleiche Verhalten.
Initialisierung kann falsch sein. Hier bin ich mit der SPI Clock Rate 
nicht so sicher. Im Datenblatt steht was von SPI Frequency die bei DVDD 
größer 2.4 V = 8Mhz sein soll. Das wär aber bissl viel. Dann gibts noch 
ne "internal Clock Frequency" die zwischen 140 und 160 KHz sein soll, da 
komm ich aber mit meinen Teilern nicht hin. In der Appnote steht "The 
clock speed is set by adjustin the baud rate", davon finde ich im 
AVR-Datenblatt wieder nichts.

Was mich etwas stutzig macht, ist, dass auf der Clock-Leitung nichts 
passiert. Wenn das am Sensor nur ein Eingang ist sollte das doch keinen 
Einfluss aufs Signal haben, oder?

Bin für jeden Hinweis Dankbar,
Thomas

von Thomas L. (zengaja)


Lesenswert?

Hilfe?

von t.d (Gast)


Lesenswert?

ich sehe foolgendes problem:
laut dem datenblatt 
http://www.freescale.com/files/sensors/doc/data_sheet/MMA7455L.pdf 
(seite 20) muss der iaddr-pin bei spi auf masse gesetzt werden, nicht 
auf vcc wie es in der anleitung steht die du gepostet hast.

probiere das mal zu ändern und poste bitte dein ergebnis.ich hab grad 
auch probleme mit dem teil!!

mfg t.d

von Seb (Gast)


Lesenswert?

Ich habe momentan auch Probleme mit diesem Sensor. Alles nach Datenblatt 
für SPI angeschlossen.

Takt und SIMO sehen korrekt aus. Auf der SOMI-Leitung ist nichts zu 
sehen. Habe da meinen CS im Verdacht. Der rührt sich nur ganz wenig 
(100mV).
Vom Data-Ready-Pin auf MMA-Seite bekomme ich ich auch keinen High-Pegel.

Sensor wurde schon ausgetauscht und noch behutsamer aufgelötet.

Bin da momentan etwas ratlos woran es liegen könnte.


Grüße

Seb

von George (Gast)


Lesenswert?

Hallo Leute,

Ich versuche auch mit diesn teil daten zu beckomen aber kein erfolg!

Laut datenblatt muss IAddr0 auf Vcc gelegt werden und nicht auf GND wie 
t.d postet! Ist jemand 100% sicher wo IAddr0 gelegt werden muss (GND 
oder Vcc)? Irgend einer der erfolg hatte?

Danke,
George

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Angehängte Dateien:

Lesenswert?

>Irgend einer der erfolg hatte?

Ja. Siehe obige Schaltung. IADDR0 muss an Vcc.

von George (Gast)


Lesenswert?

Hallo Knut,

Habe alles so gemacht wie in die zeichnung nur den pull up wiederstand 
habe ich nicht.

Ich versuche es mit der routine von Thomas L. (ganz oben) aber 
funktiuniert nicht! Kanst du vieleicht deine routine fur schreiben-lesen 
hir posten?

Mfg,
George

von Knut B. (Firma: TravelRec.) (travelrec) Benutzerseite


Lesenswert?

Der PullUp ist nötig, um andere Devices am SPI zu bedienen, während CS 
des MMA inaktiv ist. Vorsichtsmassnahme, wenn der Controller im Reset 
ist. Die Schreib-Leseroutine ist aber in ASM ;-)
1
;---------------------------------------------------------- 
2
ACC_ReadXYZ:
3
 sbis  Status0, _ReadAcc
4
 ret
5
 
6
 cbi  Status0, _ReadAcc
7
8
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
9
 ldi  Temp, $06            ;read X-Value 8bit
10
 lsl  Temp
11
 rcall  SPID_TXRX
12
 clr  Temp
13
 rcall  SPID_TXRX
14
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
15
 ldi  TempH, $80
16
 add  Temp, TempH
17
 sts  X_Axis, Temp
18
 
19
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
20
 ldi  Temp, $07            ;read Y-Value 8bit
21
 lsl  Temp
22
 rcall  SPID_TXRX
23
 clr  Temp
24
 rcall  SPID_TXRX
25
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
26
 ldi  TempH, $80
27
 add  Temp, TempH
28
 sts  Y_Axis, Temp
29
 
30
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
31
 ldi  Temp, $08            ;read Z-Value 8bit
32
 lsl  Temp
33
 rcall  SPID_TXRX
34
 clr  Temp
35
 rcall  SPID_TXRX
36
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
37
 ldi  TempH, $80
38
 add  Temp, TempH
39
 sts  Z_Axis, Temp
40
 
41
 rcall  AccToFlags
42
43
_Acc_R_E:
44
 ret
45
46
47
48
49
;---------------------------------------------------------- 
50
Init_ACC:
51
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
52
 ldi  Temp, $0D
53
 lsl  Temp
54
 sbr  Temp, (1<<7)
55
 rcall  SPID_TXRX
56
 ldi  Temp, 0b10000000        ;disable I2C
57
 rcall  SPID_TXRX
58
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
59
 
60
61
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
62
 ldi  Temp, $10            ;x_drift lsb
63
 lsl  Temp
64
 sbr  Temp, (1<<7)
65
 rcall  SPID_TXRX
66
 lds  Di0, X_ADJUST
67
 clr  Di1
68
 bst  Di0, 7
69
 bld  Di1, 2
70
 bld  Di1, 1
71
 bld  Di1, 0
72
 mov  Temp, Di0
73
 rcall  SPID_TXRX
74
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
75
76
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
77
 ldi  Temp, $11            ;x_drift msb
78
 lsl  Temp
79
 sbr  Temp, (1<<7)
80
 rcall  SPID_TXRX
81
 mov  Temp, Di1        ;
82
 rcall  SPID_TXRX
83
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
84
85
86
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
87
 ldi  Temp, $12            ;y_drift lsb
88
 lsl  Temp
89
 sbr  Temp, (1<<7)
90
 rcall  SPID_TXRX
91
 lds  Di0, Y_ADJUST
92
 clr  Di1
93
 bst  Di0, 7
94
 bld  Di1, 2
95
 bld  Di1, 1
96
 bld  Di1, 0
97
 mov  Temp, Di0        ;
98
 rcall  SPID_TXRX
99
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
100
101
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
102
 ldi  Temp, $13            ;y_drift msb
103
 lsl  Temp
104
 sbr  Temp, (1<<7)
105
 rcall  SPID_TXRX
106
 mov  Temp, Di1        ;
107
 rcall  SPID_TXRX
108
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
109
110
111
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
112
 ldi  Temp, $14            ;z_drift lsb
113
 lsl  Temp
114
 sbr  Temp, (1<<7)
115
 rcall  SPID_TXRX
116
 lds  Di0, Z_ADJUST
117
 clr  Di1
118
 bst  Di0, 7
119
 bld  Di1, 2
120
 bld  Di1, 1
121
 bld  Di1, 0
122
 mov  Temp, Di0        ;
123
 rcall  SPID_TXRX
124
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
125
126
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
127
 ldi  Temp, $15            ;z_drift msb
128
 lsl  Temp
129
 sbr  Temp, (1<<7)
130
 rcall  SPID_TXRX
131
 mov  Temp, Di1        ;
132
 rcall  SPID_TXRX
133
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
134
 
135
 ret
136
137
138
139
;---------------------------------------------------------- 
140
ACC_Measure:
141
 sbis  Status0, _MeasureAcc
142
 ret
143
144
 cbi  Status0, _MeasureAcc
145
146
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
147
 ldi  Temp, $16
148
 lsl  Temp
149
 sbr  Temp, (1<<7)
150
 rcall  SPID_TXRX
151
 ldi  Temp, 0b00000101        ;2g sensitivity, measuring mode
152
 rcall  SPID_TXRX
153
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
154
 ret
155
156
157
;---------------------------------------------------------- 
158
ACC_Standby:
159
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
160
 ldi  Temp, $16
161
 lsl  Temp
162
 sbr  Temp, (1<<7)
163
 rcall  SPID_TXRX
164
 ldi  Temp, 0b00000100        ;2g sensitivity, standby
165
 rcall  SPID_TXRX
166
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
167
 ret


Und die SPI-ROUTINE:

1
;-------------------------------------
2
;writes and reads one byte over SPI from slave (Acceleration sensor // Display)
3
SPID_TXRX:
4
 sts  SPID_DATA, Temp
5
 
6
_WaitSPIDRcv:
7
 lds  Temp, SPID_STATUS        ;loop until InterruptFlag is set
8
 sbrs  Temp, 7
9
 rjmp  _WaitSPIDRcv
10
 lds   Temp, SPID_DATA
11
 ret

Die Routinen sind für einen XMega geschrieben, sollten aber nach den 
notwendigen Registerportierungen auch auf einem Mega laufen.

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.