mikrocontroller.net

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


Autor: Thomas L. (zengaja)
Datum:

Bewertung
0 lesenswert
nicht 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_not...
hab ich für AVR, meiner Meinung nach korrekt, angepasst.
uint8_t Xdata, Ydata,Zdata,CTLReg;

void spi_master_init(void)
{
    // MOSI and SCK output, Rest Input
    DDRB = (1<<PB5)|(1<<PB7);
    // Enable SPI, Master, set clock rate 16MHz/128 = 125 KHz
     SPCR = (1<<SPIE)|(1<<SPE)|(1<<SPR1) | (1<<SPR0)|(1<<MSTR);
    SPCR &= ~((1<<SPR1) | (1<<SPR0));
    SPSR |= (1<<SPI2X);
}    

void spi_write(uint8_t reg, uint8_t data)
{
  
  uint8_t x;
  PORTB &= ~(1 << PB4);  // SS auf LOW während der Übertragung
  SPDR = (((reg & 0x3F)<<1)|0x80); //Write Befehl an Register Senden
  while((!SPSR & (1<<SPIF)));//Warten bis Transfer abgeschlossen ist
  x = SPDR;//dummy read
  SPDR = data;
  while((!SPSR & (1<<SPIF)));
  x = SPDR;//dummy read
  PORTB |= (1 << PB4);  // SS auf HIGH zum Beenden der Übertragung
}

uint8_t spi_read(uint8_t reg)
{
  uint8_t x;
  PORTB &= ~(1 << PB4);
  x = SPSR;         // clear SPIF
  x = SPDR;
  while((SPSR & (1<<SPIF)));//Warten bis SPIF gelöscht ist
  SPDR = ((reg & 0x3F)<<1); //Read Befehl an Register Senden
  while((!SPSR & (1<<SPIF)));//Warten bis Transfer abgeschlossen ist
  x = SPDR;
  SPDR = 0x00;//Daten werden mit dem Nächsten Transfer gesendet
  while((!SPSR & (1<<SPIF)));//Warten bis Transfer abgeschlossen ist
  x = SPDR; //Empfangene Daten Auslesen
  PORTB |= (1 << PB4);
  return x;
  
}


int main (void)
{
 init();
 spi_master_init();
 Xdata=Ydata=Zdata=0;
 CTLReg=0;
 spi_write(0x16,0x05);//set spi 4-wire mode in MMA7455
 CTLReg=spi_read(0x16);

 while(1)
  {  
   Xdata = spi_read(0x6);
  }

}

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

Autor: Thomas L. (zengaja)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hilfe?

Autor: t.d (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich sehe foolgendes problem:
laut dem datenblatt 
http://www.freescale.com/files/sensors/doc/data_sh... 
(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

Autor: Seb (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: George (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
>Irgend einer der erfolg hatte?

Ja. Siehe obige Schaltung. IADDR0 muss an Vcc.

Autor: George (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Knut Ballhause (Firma: TravelRec.) (travelrec) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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 ;-)
;---------------------------------------------------------- 
ACC_ReadXYZ:
 sbis  Status0, _ReadAcc
 ret
 
 cbi  Status0, _ReadAcc

 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
 ldi  Temp, $06            ;read X-Value 8bit
 lsl  Temp
 rcall  SPID_TXRX
 clr  Temp
 rcall  SPID_TXRX
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
 ldi  TempH, $80
 add  Temp, TempH
 sts  X_Axis, Temp
 
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
 ldi  Temp, $07            ;read Y-Value 8bit
 lsl  Temp
 rcall  SPID_TXRX
 clr  Temp
 rcall  SPID_TXRX
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
 ldi  TempH, $80
 add  Temp, TempH
 sts  Y_Axis, Temp
 
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
 ldi  Temp, $08            ;read Z-Value 8bit
 lsl  Temp
 rcall  SPID_TXRX
 clr  Temp
 rcall  SPID_TXRX
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
 ldi  TempH, $80
 add  Temp, TempH
 sts  Z_Axis, Temp
 
 rcall  AccToFlags

_Acc_R_E:
 ret




;---------------------------------------------------------- 
Init_ACC:
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
 ldi  Temp, $0D
 lsl  Temp
 sbr  Temp, (1<<7)
 rcall  SPID_TXRX
 ldi  Temp, 0b10000000        ;disable I2C
 rcall  SPID_TXRX
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
 

 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
 ldi  Temp, $10            ;x_drift lsb
 lsl  Temp
 sbr  Temp, (1<<7)
 rcall  SPID_TXRX
 lds  Di0, X_ADJUST
 clr  Di1
 bst  Di0, 7
 bld  Di1, 2
 bld  Di1, 1
 bld  Di1, 0
 mov  Temp, Di0
 rcall  SPID_TXRX
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor

 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
 ldi  Temp, $11            ;x_drift msb
 lsl  Temp
 sbr  Temp, (1<<7)
 rcall  SPID_TXRX
 mov  Temp, Di1        ;
 rcall  SPID_TXRX
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor


 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
 ldi  Temp, $12            ;y_drift lsb
 lsl  Temp
 sbr  Temp, (1<<7)
 rcall  SPID_TXRX
 lds  Di0, Y_ADJUST
 clr  Di1
 bst  Di0, 7
 bld  Di1, 2
 bld  Di1, 1
 bld  Di1, 0
 mov  Temp, Di0        ;
 rcall  SPID_TXRX
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor

 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
 ldi  Temp, $13            ;y_drift msb
 lsl  Temp
 sbr  Temp, (1<<7)
 rcall  SPID_TXRX
 mov  Temp, Di1        ;
 rcall  SPID_TXRX
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor


 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
 ldi  Temp, $14            ;z_drift lsb
 lsl  Temp
 sbr  Temp, (1<<7)
 rcall  SPID_TXRX
 lds  Di0, Z_ADJUST
 clr  Di1
 bst  Di0, 7
 bld  Di1, 2
 bld  Di1, 1
 bld  Di1, 0
 mov  Temp, Di0        ;
 rcall  SPID_TXRX
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor

 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
 ldi  Temp, $15            ;z_drift msb
 lsl  Temp
 sbr  Temp, (1<<7)
 rcall  SPID_TXRX
 mov  Temp, Di1        ;
 rcall  SPID_TXRX
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
 
 ret



;---------------------------------------------------------- 
ACC_Measure:
 sbis  Status0, _MeasureAcc
 ret

 cbi  Status0, _MeasureAcc

 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
 ldi  Temp, $16
 lsl  Temp
 sbr  Temp, (1<<7)
 rcall  SPID_TXRX
 ldi  Temp, 0b00000101        ;2g sensitivity, measuring mode
 rcall  SPID_TXRX
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
 ret


;---------------------------------------------------------- 
ACC_Standby:
 cbi  ACC_CPORTOut, ACC_CS      ;select Acceleration sensor
 ldi  Temp, $16
 lsl  Temp
 sbr  Temp, (1<<7)
 rcall  SPID_TXRX
 ldi  Temp, 0b00000100        ;2g sensitivity, standby
 rcall  SPID_TXRX
 sbi  ACC_CPORTOut, ACC_CS      ;deselect Acceleration sensor
 ret



Und die SPI-ROUTINE:

;-------------------------------------
;writes and reads one byte over SPI from slave (Acceleration sensor // Display)
SPID_TXRX:
 sts  SPID_DATA, Temp
 
_WaitSPIDRcv:
 lds  Temp, SPID_STATUS        ;loop until InterruptFlag is set
 sbrs  Temp, 7
 rjmp  _WaitSPIDRcv
 lds   Temp, SPID_DATA
 ret


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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.