Hallo Leute, ich habe mal wieder ein Problem :). Ich möchte mit einem Atmega32 einen Beschleunigungssensor(SMB360) von Bosch "auslesen". Das soll per SPI geschehen. In dem Datenblatt des Sensors steht, das er den SPI Mode 3 nutzt und um einen Wert vollständig zu übertragen werden 2 "Cycles" benötigt, da der Wert insgesamt 10 bit groß ist (und 8 werden ja nur auf einmal übertragen). Jetzt habe ich versucht, mit meinem Atmega diesen Sensor auszulesen aber leider klappt das nicht. Ich habe laut Manual des Atmega32 das SPI konfiguriert(also auf Mode 3 gesetzt usw.) und nun kommt mein Problem: Wie sage ich in C, das er nun die Übertragung starten soll und mir dann aus den 2 Bytes meinen richtigen Wert zusammenschreibt. Ich habe mal meinen Code(Mit Fragen und der Problemstellung) angehängt aber da fehlt noch ne ganze Menge und ich weiß nach langem Suchen nicht mehr weiter. Kann mir einer von euch helfen? Falls ihr noch Informationen benötigt um mir helfen zu wollen und zu können, sagt es bitte. Danke schonmal im Voraus!
unsigned char SPI_Transmit(unsigned char cData) { /* Starte Übertragung*/ SPDR = cData; /* Warte bis Übertragung beendet*/ while(!(SPSR & (1<<SPIF))); return(SPDR); } SPI schreibt und liest gleichzeitig! Erst Befehl Schreiben SPI_Transmit(.. ) dann weiter FF schreiben und gleichzeitig Wert(2 Byte einlesen) tmp1=SPI_Transmit(0xFF); tmp2=SPI_Transmit(0xFF);
Danke für deine Antwort! Leider hat sie mir nicht wirklich weiter geholfen...so wie du es gesagt hast, habe ich es auch schon probiert. Aber es klappt irgendwie nicht. Ich müsste eigentlich jeweils einen Wert für jede gemessene Achse bekomen(also 3 das 3-achsiger beschleunigungsmesser). Komischerweise bekomme ich für jeden Zyklus einen Wert aber die Werte können nicht stimmen, da sie immer konstant sind auch wenn ich den BeSe bewege. Ich habe das jetzt so geschrieben für 3 Werte: SPI_Transmit('x'); Highbyte=SPI_Transmit(0xFF); Lowbyte=SPI_Transmit(0xFF); acclx = ((Highbyte & 0x7F) << 3) | (Lowbyte & 0x07); SPI_Transmit('y'); Highbyte=SPI_Transmit(0xFF); Lowbyte=SPI_Transmit(0xFF); accly = ((Highbyte & 0x7F) << 3) | (Lowbyte & 0x07); SPI_Transmit('z'); Highbyte=SPI_Transmit(0xFF); Lowbyte=SPI_Transmit(0xFF); acclz = ((Highbyte & 0x7F) << 3) | (Lowbyte & 0x07); printf("x%i y%i z%i \n\r",acclx,accly,acclz); Habe ich dich denn überhaupt richtig verstanden? Also ich meine, kann ich das so machen? Wie ist das eigentlich mit dem SPI Mode 3? Muss man da nicht den SS irgendwie auf Low ziehen während der Kommunikation? Und bestimmt mein µC den Takt selbst, also wann steigende Flanke und wann die fallende kommt? Und wieso muss ich vor dem abrufen der High und Lowbytes eigentlich vorher nochmal eine einzelne SPI_transmit Funktion ausführen? Ich finde diese angeblich "simple" SPI ganz schön verwirrend... Gruß Marian
Kann es sein das ich mir selbst Werte per SPI schicke? Ich habe jetzt mal anstatt FF ein 55 und ein AA gesendet und nun bekomme ich auch andere Werte ausgegeben. Ich verstehe das nicht!
Hallo, kannst du jetzt Daten von deinem BeSe empfangen? Wenn ja, wie hast du das hinbekommen? gruß christoph
Hallo Christoph, ja mittlerweile bekomme ich Daten von dem BeSe aber leider sind sie sehr komisch. Nach dem umrechnen der 2er Komplementdarstellung in meine dezimale Darstellung, bekomme ich sehr seltsame Werte. Wenn er ruhig auf dem Tisch liegt, dann habe ich diese Werte ca.: X -130 Y 30 Z -140 Hast du es denn mittlerweile auch hinbekommen? Wenn nicht kann ich dir gerne helfen. Gruß, Marian
Leider nicht, wenn ich die Bits (für 10g Range, Normal mode) setzen will, bleibt mein programm schon hängen. wie hast du das denn gemacht. Und das auslesen klapp auch nicht. hast du da eventuell ein beispiel für mich? Schon mal vielen dank. Christoph
hallo, die bits setzen hat funktioniert. nur wie hast du die daten ausgelesen?
kannst du mir weiterhelfen? ich verzweifel völlig. wie hast denn die lese routine geschrieben? ich bekomme das nicht hin. hab so was acu noch nie gemacht. schon mal vielen dank für deine Hilfe!
Die Daten auszulesen ist ganz einfach. Ich schreibe dir mal den Weg auf wie ich es gemacht habe!(Kein exakter C-Syntax) Das ist meine Leseroutine: uint8_t spi_read_register(uint8_t adress1, uint8_t adress2) { //Hier musst du dein SS auf 0 legen um die Kommunikation zu starten spi_putc(adress1) //In adress1 muss die Adresse stehen um das MSB data1=spi_putc(0xFF); //auszulesen + das Readbit(also 0x9A für MSB der spi_putc(adress2); //x_achse). Dann schickst du ein Dummy byte und data2=spi_putc(0xFF); //bekommst den X-Werte geliefert //Dann das gleiche nochmal für die 3 LSB(0x9B //schicken und danach Dummy Byte um den Wert zu bekommen //als letztes SS wieder auf High ziehen um den Lesevorgang zu beenden } So das machst du jetzt 3 mal(mit den entsprechenden Adresse+ das Readbit) und schon hast du die Werte. Alles klar? Gruß, Marian
hallo, danke schon mal. habe isch das so richtig verstanden?
Fast :). Du musst dir ja die Werte, die du von den Adressen geliefert bekommst, noch in die Variablen speichern. Im Moment gibt deine Funktion ja nur das data1(MSB) zurück aber du verwendest diese ja in der Main nicht. Mache besser aus data1 und data2 globale Variablen und füge sie dann sofort zu dem Beschleunigungswert zusammen. Wie das geht weißt du hoffentlich. Also ich meine das so: spi_lese ((0x9A),(0x9B)); Highbyte=data1; Lowbyte=data2; Das machst du für alle 3 Achsen jeweils einmal. OK? Gruß, Marian
Ich verstehe das irgend wie nicht. Wie füge ich denn das MSB und das LSB zusammen? ich möchte den Wert dann im eeprom speichern, da ich kein display habe. ich habe die datei mal angehängt! [Ist das ein scheiß,wenn man keine Ahnung hat, aber es machen muss. ;-)]
Deine Funktionen sollten ein int und kein Char zurückliefern. Sprich: int spi_lese(char adr1, char adr2) { int result; // Adresse schreiben und Daten empfangen... result = ((int) adr1<<8); // keine Gewähr, ob das wirklich so funktioniert... return (result | adr2); }
hallo nochmal, die nervensäge ist wieder da. ich hab maal das programm angehängt. ich bekomme immer nur eine 0 gespeichert. egal wie ich es mache. vielleicht habe ich ja schon vorher was falsch gemacht. vielen dank für eure bemühungen mir zu helfen! gruß christoph
Du kannst immer nur ein "return" angeben. Vielleicht solltest du dir mal die C-Bibel (Kernighan und Ritchie "Programmieren in C") antun. Dir fehlen nämlich eine Menge C-Grundlagen. Da wird es dir auch kaum helfen, dauernd vorzubringenden, dass du dich um dieses Problem kümmmern musst. Um die Lösung Probleme anderer wirst du im Leben nicht herumkommen. Ich spreche da aus Erfahrung...
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.