Forum: Compiler & IDEs Problem mit SPI und Beschleunigungsensor


von Gerald F. (schwedenpils)


Lesenswert?

Hallo,

ich möchte einen SCA3000-D01 Sensor über SPI an meinen ATmega32L 
auslesen.
Ich habe mal folgenden Code geschrieben, ist da irgendwo ein Fehler den 
ich nicht sehe und wie kann ich über den Spare Anschluss am STK500 Board 
mein Programm beobachten um zu sehen wo es sich aufhängt.

Hier der Code

#include <avr/io.h>
#include <util/delay.h>    //Bibliothek für Verzögerung


int read_x_channel();
void SPI_MasterInit(void);

int main(void)
{

  int Wert;
  SPI_MasterInit();
  while(1)
  {
    Wert = read_x_channel();
    _delay_us(20);

  }


  return 0;
}

int read_x_channel()
{
short x1,x2;
int x3, xGes;

 PORTB = (0 << PB0);                   //SS auf low setzen
 SPDR = 0x05;                          //Befehl read X-Channel in SPDR
 while(!(SPSR & (1<<SPIF)));          //Warten bis Empfangsende
 x1 = SPDR;                            //Wert x1 aus DR wird gespeichert
 x3 = x1<<8;                            //x1 wird um 3 verschoben
 SPDR = 0x04;               //Dummybyte
 while(!(SPSR & (1<<SPIF)));           //s.o.
 x2 = SPDR;                 //Wert x2 aus DR wird gespeichert

 xGes = x3 + x2;            //Endwert wird berechnet
 PORTB = (1 << PB0);                   //SS auf highsetzen

 return (xGes);                //Endwert wird zurück gegeben
}

void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
DDRB |= (1<<PB2) | (1<<PB3) | (1<<PB5);

/* Enable SPI, Master, set clock rate fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

Vielen Dank im Voraus
Gruß Gerald

von Simon (Gast)


Lesenswert?

Gerald F. schrieb:
> DDRB |= (1<<PB2) | (1<<PB3) | (1<<PB5);

Sicher PB2, 3 und 5!? Laut Datenblatt sind es PB4, 5 und 7 (SS, MOSI und 
SCK). Ansonsten, SS muss als output geschalten sein, ansonsten geht 
dein SPI in den Slave Modus sobald dieser auf low gezogen wird.

von Gerald F. (schwedenpils)


Lesenswert?

OK danke für die schnelle Antwort,
ja SS ist inzwischen auf Ausgang und die anderen Pins hab ich auch 
angepasst, leider tut sich bei mir trotzdem noch nichts.
Werd noch weiter probieren.

Gruß Gerald

von Gerald F. (schwedenpils)


Lesenswert?

Habe meinen Code nochmal angepasst und möchte das Byte das ich vom Slave 
erhalte direkt über meine LEDs am STK500 ausgeben, das Problem an der 
Sache ist, das alle LEDs durchgehend leuchten, das heisst nur 1 im Byte.

#include <avr/io.h>
#include <util/delay.h>    //Bibliothek für Verzögerung


int read_x_channel();
void SPI_MasterInit(void);

int main(void)
{

  int Wert;
  SPI_MasterInit();
  DDRD = 0xFF;
  while(1)
  {
    Wert = read_x_channel();
    _delay_us(20);

  }


  return 0;
}

int read_x_channel()
{
int x1,x2;
int x3, xGes;

 PORTB = (0 << PB0);                   //SS auf low setzen
 SPDR = 0x05;                          //Befehl read X-Channel in SPDR
 while(!(SPSR & (1<<SPIF)));          //Warten bis Empfangsende
 x1 = SPDR;

 PORTD = ~x1;
 _delay_us(10);

 x3 = x1<<8;                            //x1 wird um 3 verschoben
 SPDR = 0x04;               //Dummybyte
 while(!(SPSR & (1<<SPIF)));           //s.o.
 x2 = SPDR;                 //Wert x2 aus DR wird gespeichert

PORTD = ~x2;
 _delay_us(10);

 xGes = x3 + x2;            //Endwert wird berechnet
 PORTB = (1 << PB0);                   //SS auf high setzen

 return (xGes);                //Endwert wird zurück gegeben
}

void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
DDRB |= (1<<PB5) | (1<<PB7);

/* Enable SPI, Master, set clock rate fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

Gruß Gerald

von Gerald F. (schwedenpils)


Lesenswert?

Hallo,

Ich habe gerade die SPI Leitungen vom Sensor getrennt und festgestellt
das am CSB also am SS des Sensors 3,3Volt anliegen, das sollte doch
nicht sein oder?

Gruß Gerald

von Floh (Gast)


Lesenswert?

Gerald F. schrieb:
> ich möchte einen SCA3000-D01 Sensor über SPI an meinen ATmega32L
> auslesen.
> Ich habe mal folgenden Code geschrieben, ist da irgendwo ein Fehler den
> ich nicht sehe und wie kann ich über den Spare Anschluss am STK500 Board
> mein Programm beobachten um zu sehen wo es sich aufhängt.

Ich hoffe du arbeitest mit maximal 3.6 Volt?
Ansonsten ist dein Sensor tot.

von Gerald F. (schwedenpils)


Lesenswert?

Ja ich arbeite mit 3,3 Volt, habe auch nie Überspannungen gehabt.
Heisst das dann das mein Sensor defekt ist?

von Floh (Gast)


Lesenswert?

Gerald F. schrieb:
> Ja ich arbeite mit 3,3 Volt, habe auch nie Überspannungen gehabt.
> Heisst das dann das mein Sensor defekt ist?

Nein. Den Satz fand ich nur seltsam:

> Ich habe gerade die SPI Leitungen vom Sensor getrennt und festgestellt
> das am CSB also am SS des Sensors 3,3Volt anliegen, das sollte doch
> nicht sein oder?

Sollte eben schon. Er hat ja eine Betriebsspannung von 3.3 Volt, daher 
liegen am SS des Sensors im nichtaktiven Zusatnd auch 3.3 Volt an.
:-)
Am besten machtste einfach mal ein Foto des Aufbaus, vielleicht ists ja 
nur ein KAbelproblem.

von Gerald F. (schwedenpils)


Lesenswert?

Verkabelung hab ich schon mehrfach durchgecheckt, aber hier nochmal wie 
ich alles verbunden habe. Aufbau ist auf Steckbrett daher das Foto vllt. 
nicht so aussagekräftig.

Sensor CSB >> SS (PB4)
Sensor MOSI >> MOSI (PB5)
Sensor MISO >> MISO (PB6)
Sensor SCK >> SCK (PB7)

Muss ich vllt. noch irgendwas im AVR Studio einstellen, arbeite mit 
internem Clock von 1MHz und habe auch ich Code #define F_CPU 1000000UL
eingefügt. Ich muss doch irgendwo was vergessen haben.
Achja wenn ich den Sensor wieder anschließe bringt er am SS(CSB) 
trotzdem 3,3Volt auch wenn er im Code auf 0 gesetzt wird?!

Gruß Gerald

von Floh (Gast)


Lesenswert?

Gerald F. schrieb:
> Achja wenn ich den Sensor wieder anschließe bringt er am SS(CSB)
> trotzdem 3,3Volt auch wenn er im Code auf 0 gesetzt wird?!

SS wirklich als Ausgang definiert?

von Gerald F. (schwedenpils)


Lesenswert?

Ups,
SS war nich als Ausgang definiert!
Vielen Dank Floh du warst mir echt ne große Hilfe, werd mal sehen ob ich 
jetzt zu Potte komm. Ich hoffe ich darf dich mal anschreiben falsch noch 
Probleme auftauchen, wünsch dir guten Rutsch ins neue Jahr.

Gruß Gerald

von Gerald F. (schwedenpils)


Lesenswert?

Mist, leider bekomm ich immer noch keine vernünftigen Werte, wenn ich 
meinen Beschleunigungssensor kippe oder Bewege, bekomm ich an meine 
TestLEDs and PORTD immer dasselbe angezeit.

Hier nochmal mein Code wie er jetzt ist:

#include <avr/io.h>
#include <util/delay.h>    //Bibliothek für Verzögerung

#define F_CPU 1000000UL


int read_x_channel();
void SPI_MasterInit(void);

int main(void)
{

  int Wert;
  SPI_MasterInit();
  DDRD = 0xFF;
  while(1)
  {
    Wert = read_x_channel();
    _delay_us(20);

  }


  return 0;
}

int read_x_channel()
{
uint8_t x1,x2;
int x3, xGes;

 PORTB = (0<<PB4);                   //SS auf low setzen
 SPDR = 0x05;

                          //Befehl read X-Channel in SPDR
 while(!(SPSR & (1<<SPIF)));          //Warten bis Empfangsende

 x1 = SPDR;

    PORTD = x1;
     _delay_ms(3000);

 x3 = x1<<5;                            //x1 wird um 3 verschoben
 SPDR = 0x04;               //Dummybyte
 while(!(SPSR & (1<<SPIF)));           //s.o.
 x2 = SPDR;                 //Wert x2 aus DR wird gespeichert

    PORTD = x2;
     _delay_ms(3000);


 xGes = x3 + x2;            //Endwert wird berechnet
 PORTB = (1<<PB4);                   //SS auf high setzen

 return (xGes);                //Endwert wird zurück gegeben
}

void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
DDRB = (1<<PB5) | (1<<PB7)|(1<<PB4);

/* Enable SPI, Master, set clock rate fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}

An was kann das liegen wenn die Werte immer gleich bleiben?
Hast du ne Idee?

Gruß Gerald

von Simon (Gast)


Lesenswert?

Es gibt ein code-tag, das macht das lesen des Codes um einiges besser ;)

Dann, setzte und lösche PORTB mit einer Maske, das ist die sicherere 
Alternative. Sollte aber mMn kein Fehler darstellen. Also so in der Art:
1
PORTB |= _BV(PB0); // auf high ziehen
und
1
PORTB &= ~_BV(PB0); // auf low ziehen

Sicher, dass 3s zwischen dem auslesen des 1. und des 2. Registers so 
eine gute Idee sind? Könntest mal nur die unteren 8 Byte der erhaltenen 
Daten anzuzeigen.

Was noch sein kann, ist dass du ein falsches SPI Modus verwendest (d.h. 
an der falschen Stelle die Daten samplest). Leider schweigst sich das 
Datenblatt, das ich auf die Schnelle auftreiben konnte über die Waveform 
für die Kommunikation aus. Kannst ja mal versuchen mittels CPOL und CPAH 
in SPCR zu spielen.

Hast du ein Logic Analyzer oder ein Osci zur Hand? Dann könntest du mal 
schauen ob die empfangenen Daten dem entsprechen, was über den Pins 
rüberkommt.

von Simon (Gast)


Lesenswert?

So hab mal ein wenig mehr gegraben ^_^. Ka ob du das schon hast, schaden 
kann es nicht.

http://www.vti.fi/midcom-serveattachmentguid-1e0126c994791f0126c11e09138e559c13fb5afb5af/cma3000-d0x_product_family_specification_8281000a.04.pdf

Ansonsten, versuch mal den Register WHO_AM_I und REVID auszulesen. Dass 
sollte immer einen festen Wert zurückgeben. Wenn du das empfängst & 
ausgibst, dann weißt zumindest, "an der Kommunikation liegt es nicht".

Dann, laut Datenblatt startet der IC im PowerDown Mode hoch. D.h. du 
musst ihn erstmal konfigurieren, bevor du etwas von dem IC lesen kannst. 
Das geht mit CTRL, näheres im Datenblatt ab Seite 12.

gute nacht

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.