mikrocontroller.net

Forum: Compiler & IDEs Problem mit SPI und Beschleunigungsensor


Autor: Gerald F. (schwedenpils)
Datum:

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

Autor: Simon (Gast)
Datum:

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

Autor: Gerald F. (schwedenpils)
Datum:

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

Autor: Gerald F. (schwedenpils)
Datum:

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

Autor: Gerald F. (schwedenpils)
Datum:

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

Autor: Floh (Gast)
Datum:

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

Autor: Gerald F. (schwedenpils)
Datum:

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

Autor: Floh (Gast)
Datum:

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

Autor: Gerald F. (schwedenpils)
Datum:

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

Autor: Floh (Gast)
Datum:

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

Autor: Gerald F. (schwedenpils)
Datum:

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

Autor: Gerald F. (schwedenpils)
Datum:

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

Autor: Simon (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
PORTB |= _BV(PB0); // auf high ziehen
und
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.

Autor: Simon (Gast)
Datum:

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

http://www.vti.fi/midcom-serveattachmentguid-1e012...

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

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.