-         

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 11

Thema: SPI-Kommunikation, mir fehlt der Ansatz...

  1. #1
    Erfahrener Benutzer Robotik Einstein Avatar von Geistesblitz
    Registriert seit
    16.03.2011
    Ort
    Dresden
    Alter
    30
    Beiträge
    1.937

    SPI-Kommunikation, mir fehlt der Ansatz...

    Anzeige

    Ich versuche gerade, mittels SPI mit einem AS5048A zu kommunizieren, allerdings bin ich gerade ein wenig überfordert. Wie konfiguriert man den SPI-Bus richtig? Und wie läuft das eigentlich genau mit der Kommunikation ab?
    Ich dachte jetzt eigentlich, dass ich ein Byte sende und dann ein Byte zurück bekomme, oder sind das immer zwei Bytes (wegen 16-Bit?). Irgendwie steh ich da noch total auf dem Schlauch.
    Hier mal mein kleines Testprogramm:

    Code:
    $regfile = "m32def.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 16000000
    $baud = 9600
    
    Config Spi = Hard , Interrupt = On , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 0 , Clockrate = 16
    
    Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , _
       Db7 = Porta.0 , E = Porta.4 , Rs = Porta.5
    Config Lcd = 20 * 4
    Cursor Off
    Cls
    
    Spiinit
    
    Dim Angle As Integer
    
    Do
    Angle = Spimove(&h3fff , 2)
    Locate 1 , 1
    Lcd Angle
    Waitms 100
    Loop
    Beim Kompilieren bekomm ich dann drei Fehler: Invalid Datatype, Variable not dimensioned und Loop expected
    Keine Ahnung, wie ich da rangehen soll...

    Edit: 0x3fff ist natürlich schwachsinn, &h3fff muss es heißen, aber irgendwie bekomm ich trotzdem nix gescheites...
    Geändert von Geistesblitz (16.02.2014 um 15:22 Uhr)

  2. #2
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    705
    Alle SPI-Befehle können meines Wissens nach nur Byte-Variablen verarbeiten, ganz gleich in welche Richtung. Deswegen meckert Bascom sowohl die Integer-Variable Angle als auch den Wert &h3fff an. Der Rest (Loop expected) ist glaube ich nur so´n Nachmaulen, das der Compiler manchmal macht, wenn ihm was sauer aufstößt.

    Du müsstest also &h3FFF erstmal in ein Array aus 2 Bytes zerlegen:

    A(1) = &h3F
    A(2) = &hFF

    Und für Angle legst Du ebenfalls ein Array aus 2 Bytes an:

    Dim Angle as Byte(2)


    Diese Zeile

    Angle(1) = Spimove (A(1),2)

    sendet dann &h3F und &hFF nacheinander raus, und das zurückkommende Ergebnis wird in Angle(1) und Angle(2) abgelegt. Daraus müsstest Du dann nur noch einen Integer machen.

    Steht übrigens auch sehr schön in der Bascom-Hilfe erklärt

  3. #3
    Erfahrener Benutzer Robotik Einstein Avatar von Geistesblitz
    Registriert seit
    16.03.2011
    Ort
    Dresden
    Alter
    30
    Beiträge
    1.937
    Die hab ich mittlerweile auch schon gefunden, muss ich mal ausprobieren.
    Kann man eigentlich bei Soft-SPI die Einstellungen genauso vornehmen wie bei Hard-SPI, also zB. die Frequenz etc? Die Hard-SPI blockiert mir sonst den Programmieranschluss (oder da ist irgendwo auch noch ein Fehler in der Verdrahtung).

    - - - Aktualisiert - - -

    Ich musste feststellen, dass ich die Leitungen nicht richtig verdrahtet hatte
    Mein Code sieht nun folgendermaßen aus:

    Code:
    $regfile = "m32def.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 16000000
    $baud = 9600
    
    Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 1 , Clockrate = 16
    
    Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , _
       Db7 = Porta.0 , E = Porta.4 , Rs = Porta.5
    Config Lcd = 20 * 4
    Cursor Off
    Cls
    
    Spiinit
    
    Dim Angle(2) As Byte
    
    Wait 1
    
    Angle(1) = Spimove(&H4001 , 2)
    
    Do
    Angle(1) = Spimove(&Hffff , 2)
    Cls
    Locate 1 , 1
    Lcd Angle(1)
    Locate 1 , 5
    Lcd Angle(2)
    Waitms 10
    Loop
    Auf dem Display erhalte ich nur
    192 0
    Entspricht also der Bitfolge
    1100 0000 0000 0000
    wie es also wohl aussieht, bekomm ich nur ein Errorflag, vielleicht durch das flashen des Controllers noch. Nun hab ich aber schon einen Error-Reset eingefügt, das Problem geht aber nicht weg. Weiß jemand Rat?
    Ich bin mir auch nicht ganz sicher, ob ich die Daten richtig sende. Der Sensor will ja immer 16 Bit auf einmal haben...

  4. #4
    Erfahrener Benutzer Robotik Einstein Avatar von Geistesblitz
    Registriert seit
    16.03.2011
    Ort
    Dresden
    Alter
    30
    Beiträge
    1.937
    Hmm, einfach so die Beiträge zusammenführen...kein Wunder, dass dann keiner antwortet.
    Weiß einer, wo das Problem liegt?

  5. #5
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    15.01.2007
    Ort
    Göttingen
    Beiträge
    705
    Ich habe mir gerade das Datenblatt von diesem Magnetsensor angeschaut - ein interessantes Teilchen
    Was ich nicht ganz verstehe: Welches Kommando steckt hinter &hFFFF?

    Und hast Du schon mal versucht, die 16 Bits in Form von zwei hintereinander gesendeten Bytes zu verpacken?
    Ich habe mal ´ne Menge mit RFM01 und RFM02-Bausteinen gemacht (kleine 70cm-Sender und -Empfänger), die auch immer 16 Bits in Folge sehen wollen. Das ging mit einem Array aus zwei Bytes ganz hervorragend...

  6. #6
    Erfahrener Benutzer Begeisterter Techniker Avatar von .:Sebastian:.
    Registriert seit
    07.01.2006
    Ort
    Arkon I
    Beiträge
    203
    Moin,

    ich kenne das Problem, der AS5048 macht nur fast SPI.
    Stattdessen kommt da SSI zum Einsatz.
    Das ist fast kompatibel zu SPI in Modus 2 (Ruhepegel ist High, Bits werden bei fallender Flanke gelesen) nur wird das erste Bit eine Flanke zu spät raus-geschoben. (Vergleich mal Diagramme im Datasheet vom Mega mit denen vom AS5048.)

    Ich hab das ganze mal hier recht ausführlich auf englisch erläutert.
    Fall die Sprache ein Problem ist kann ich das ganze auch nochmal auf Deutsch hier posten. Fehlt nur gerade die Zeit.

    Kurzfassung fürs auslesen ist die:
    1. CS-Pin am AS5048 low ziehen und für beide Bytes low halten (als nicht das SS-Signal vom Hardware SPI benutzen, das wird nach jedem Byte kurz high, sondern den Pin selber schalten).
    2. Einmal ein Byte irgendwas senden, was ist egal du willst nur 8 Taktzyklen auf deiner Clockleitung.
    3. Empfangsregister auslesen
    4. Wert um 9 Bit links schieben. (Es ist dein höherwertiges Byte und dein erstes Bit ist immer 0, siehe mein Link).
    5. Einmal ein Byte irgendwas senden, was ist wieder egal du willst nur 8 Taktzyklen auf deiner Clockleitung.
    6. Empfangsregister auslesen
    7. Wert um 1 Bit links schieben und an das Highbyte dran verodern.
    8. Manuell den Datenpin lesen für das letzte Bit
    9. Das letzte Bit im Ergebnis entsprechend setzen.
    10. CS auf high setzen

    Ich habe leider keine Ahnung wie man das genau in Bascom tut.
    Ich kann nur C und Assembler.

    Fall C-Code was hilft: http://sindri.sebastians-site.de/hg/...e/AS5043.c#l26
    Das ist getestet und von mehren Leuten validiert.

    Gruß
    Sebastian

  7. #7
    Erfahrener Benutzer Robotik Einstein Avatar von Geistesblitz
    Registriert seit
    16.03.2011
    Ort
    Dresden
    Alter
    30
    Beiträge
    1.937
    Vielen Dank für deine Erklärung, nur glaube ich, dass wir von verschiedenen ICs reden. Ich hab einen AS5048A, in deinem Link schreibst du aber von einem AS5043.
    Wahrscheinlich hast du dich da verlesen, kann ja mal passieren.
    Bei meinem IC soll man nämlich auch etwas senden können, nicht nur auslesen.
    Das mit dem manuellen SS über zwei Bytes werd ich mal ausprobieren, das war ein guter Tipp.

    Edit: das &hffff sollte eigentlich heißen: ich will auf das register &h3fff (angle-register) zugreifen, zusätzlich aber eben noch bit 14 (read) und bit 15 (parity) gesetzt -> wird zu &hffff

    Edit²:
    Hab das jetzt mal ausprobiert, hab die Adressen in Byte-Arrays geschrieben und die SS-Leitung auf einen anderen Pin gesetzt. Ergebnis ist immernoch das Gleiche wie vorher. Hier der Code:
    Code:
    $regfile = "m32def.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 16000000
    $baud = 9600
    
    Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 1 , Clockrate = 128
    
    Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , _
       Db7 = Porta.0 , E = Porta.4 , Rs = Porta.5
    Config Lcd = 20 * 4
    Cursor Off
    Cls
    Config Portb.3 = Output
    Portb.3 = 1
    
    Spiinit
    
    Dim Anglereg(2) As Byte
    Dim Errorreg(2) As Byte
    Anglereg(1) = &HFF
    Anglereg(2) = &HFF
    Errorreg(1) = &H40
    Errorreg(2) = &H01
    
    Dim Angle(2) As Byte
    
    Wait 1
    
    Portb.3 = 0
    Angle(1) = Spimove(errorreg(1) , 2)
    Portb.3 = 1
    
    Do
    Portb.3 = 0
    Angle(1) = Spimove(anglereg(1) , 2)
    Portb.3 = 1
    Cls
    Locate 1 , 1
    Lcd Angle(1)
    Locate 1 , 5
    Lcd Angle(2)
    Waitms 10
    Loop
    Edit³:
    Ich glaub, ich habs jetzt:
    Code:
    $regfile = "m32def.dat"
    $framesize = 32
    $swstack = 32
    $hwstack = 32
    $crystal = 16000000
    $baud = 9600
    
    Config Spi = Hard , Interrupt = Off , Data Order = Msb , Master = Yes , Polarity = Low , Phase = 1 , Clockrate = 128
    
    Config Lcdpin = Pin , Db4 = Porta.3 , Db5 = Porta.2 , Db6 = Porta.1 , _
       Db7 = Porta.0 , E = Porta.4 , Rs = Porta.5
    Config Lcd = 20 * 4
    Cursor Off
    Cls
    Config Portb.3 = Output
    Portb.3 = 1
    
    Spiinit
    
    Dim Anglereg(2) As Byte
    Dim Errorreg(2) As Byte
    Anglereg(1) = &HFF
    Anglereg(2) = &HFF
    Errorreg(1) = &H40
    Errorreg(2) = &H01
    
    Dim Angle(2) As Byte
    
    Wait 1
    
    Portb.3 = 0
    waitus 10
    Angle(1) = Spimove(errorreg(1) , 1)
    Angle(2) = Spimove(errorreg(2) , 1)
    waitus 10
    Portb.3 = 1
    
    Do
    Portb.3 = 0
    waitus 10
    Angle(1) = Spimove(anglereg(1) , 1)
    Angle(2) = Spimove(anglereg(2) , 1)
    waitus 10
    Portb.3 = 1
    angle(1)=angle(1) and &b00111111
    Cls
    Locate 1 , 1
    Lcd Angle(1)
    Locate 1 , 5
    Lcd Angle(2)
    Waitms 10
    Loop
    Sende die Bytes jetzt wirklich einzeln. Dachte eigentlich, wenn ich angle(1)=SPIMOVE(anglereg(1),2) angebe, dass er dann automatisch das Byte an der nächsten Stelle als nächstes sendet und auch ins Folgende schreibt, aber anscheinend hab ich das missverstanden. Nun lese ich ab 6 12x (ein bisschen verrauscht, letzte Stelle springt schön, muss ich wohl noch ein wenig filtern) und wenn ich den Magneten drehe 6 3x
    Geändert von Geistesblitz (17.02.2014 um 23:12 Uhr)

  8. #8
    Erfahrener Benutzer Begeisterter Techniker Avatar von .:Sebastian:.
    Registriert seit
    07.01.2006
    Ort
    Arkon I
    Beiträge
    203
    Moin,

    ja da fehlt ein Satz in meinem ersten Posting und zwar: "Ich habe grade kein Datasheet da, aber ich glaube mich zu erinnern, dass der AS5048 die 14bit Version vom AS5043 ist."
    Muss das Posting-Formular wohl gefressen haben.
    Stimmt nicht ganz, der 48er hat echtes SPI, nicht nur SSI und ist etwas neuer als der AS4043.

    Aber CS über beide Bytes low halten kann schon mal nicht schaden.
    Siehe figure 4.2.2 im Datasheet vom AS5048

    Ansonsten würde ich nochmal Prüfen ob die Reihenfolge der Bits stimmt.
    Also erst das Highbyte dann das Lowbyte, jeweils mit dem MSB zuerst.

    Gruß
    Sebastian

  9. #9
    Erfahrener Benutzer Robotik Einstein Avatar von Geistesblitz
    Registriert seit
    16.03.2011
    Ort
    Dresden
    Alter
    30
    Beiträge
    1.937
    Da die LSBs am ehesten vom Messrauschen betroffen sind, denke ich mal, dass es so herum richtig sein muss. Das Datasheet zum AS5048A und -B hab ich doch im Eingangspost verlinkt, wie schwer kann das dann zu finden sein? Hab jetzt noch ein wenig mit Hilfe von Overlay gearbeitet, um alles in einem Integerwert zu verstauen, jetzt kann ich endlich mit dem nächsten Schritt in meinem Programm weitermachen

  10. #10
    Erfahrener Benutzer Begeisterter Techniker Avatar von .:Sebastian:.
    Registriert seit
    07.01.2006
    Ort
    Arkon I
    Beiträge
    203
    Das Datasheet zum AS5048A und -B hab ich doch im Eingangspost verlinkt, wie schwer kann das dann zu finden sein?
    Das ist alles ganz leicht wenn man über einen Internetzugang verfügt.
    Ich sitze hier aber Moment gerade bei lauschigen 368kbit/s die ich mir mit 4 anderen Leuten teilen muss.
    Da kann man hat mal so seine 10-20min auf das Datasheet warten und da ich mir ziemlich sicher war das der 48er auch nur SSI hat, hab ich halt mal schnell was geschrieben.

    Außerdem vergiss die Bit-Order die passt bei dir, ich hatte dein letztes Posting, so missverstanden das die Werte immer noch nicht passen

    Aber kein Problem, das nächste spare ich mir den Aufwand einfach, wenn es dich stört dass ich halt mal daneben lag.

    Gruß
    Sebastian

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. [ERLEDIGT] Verständnisfrage zur SPI Kommunikation ..
    Von Ritchie im Forum C - Programmierung (GCC u.a.)
    Antworten: 6
    Letzter Beitrag: 30.03.2013, 19:44
  2. Mir fehlt M8Def.dat Atmega8
    Von Bra!ny im Forum Microcontroller allgemeine Fragen/Andere Microcontroller
    Antworten: 3
    Letzter Beitrag: 05.08.2011, 22:46
  3. Ausführungsgeschw. I2C vs SPI Kommunikation
    Von malthy im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 4
    Letzter Beitrag: 05.08.2010, 12:33
  4. SPI Kommunikation zwischen 2 AVR's
    Von Ruppi im Forum Basic-Programmierung (Bascom-Compiler)
    Antworten: 7
    Letzter Beitrag: 05.07.2007, 10:34
  5. Ich habe das Grundwissen, allerdings fehlt es mir an Ideen!
    Von parrot_12 im Forum AVR Hardwarethemen
    Antworten: 43
    Letzter Beitrag: 17.12.2005, 10:14

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •