-         

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

Thema: Probleme mit SPI-Schnittstelle

  1. #1
    Neuer Benutzer Öfters hier
    Registriert seit
    11.03.2008
    Beiträge
    7

    Probleme mit SPI-Schnittstelle

    Anzeige

    Hi und hallo,

    ich versuche mich gerade daran einen Sensor per SPI anzusprechen. Leider funktioniert es bis jetzt noch
    nicht.

    Der Chip-Select Pin funktioniert. Das habe ich messen können.

    Das Ganze läuft zwar durch, aber es steht hinterher nur Müll in der Variable "daten". Ich habe das Gefühl, dass die Kommunikation erst gar nicht anspringt.
    Ich habe es zwar nicht richtig messen können, aber anscheinend läuft die Clock des SPI nicht an.

    Wäre klasse, wenn mir da jemand weiter helfen könnte. Vielleicht gibt es ja schon einen fehler bei der Initialisierung des SPI.

    Vielen Dank schon einmal!



    Hier einmal die Teile meines Codes:

    Code:
    #define SPI_PIN        PINB
    #define SPI_DDR        DDRB
    #define SPI_PORT     PORTB    
     
    #define MISO        3    
    #define MOSI        2    
    #define Clock         1    
    #define SS        0
    
    CS_PIN            PINE
    
    void SPI(void)                
    {
        SPI_PORT_DDR &=~(1<<MISO);        // miso auf input
        SPI_PORT_DDR |= (1<<Clock);          // clock auf output
        SPI_PORT_DDR |= (1<<MOSI);        // mosi auf output
        SPI_PORT_DDR |= (1<<SS);        // wird nicht gebraucht, ss auf output
        CS_PIN |= (1<<PE2);            // chip selet auf high    
        SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);
    }
    Die Kommunikation mit dem Sensor soll dann wie folgt laufen:

    Code:
    #include   <avr\io.h>          
    #include   <stdlib.h>          
    #include   <avr/interrupt.h>      
    
          
    int main(void)
    {   
        cli();
        Ports();                   
        SPI();
        sei();
      
        CS_PIN &= ~(1<<CS_TEMP); // CS auf LOW
        _delay_us(10);           // kurz warten
        SPDR= 0x10;             // Daten senden
        while(!(SPSR & (1<<SPIF)));  
        daten= (SPDR<<8) & 0x3FFF;        // Ersten 8 Bit als MSBs ablegen
        SPDR= 0x01;
        while(!(SPSR & (1<<SPIF)));
        daten+= SPDR;                    // Letzten 8 Bit dazu addieren
        CS_PIN |= (1<<PE2);     // cs High
    
        while(1)
        {
            .....
        }
    }/* main */

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    20.08.2008
    Ort
    Kandel
    Alter
    29
    Beiträge
    1.220
    Testen kannst du die SPI-Kommunikation indem du MISO mit MOSI direkt verbindest. Stimmt der SPI-Modus (Polarität + Phase)?

    mfG
    Markus
    Tiny ASURO Library: Thread und sf.net Seite

  3. #3
    Neuer Benutzer Öfters hier
    Registriert seit
    11.03.2008
    Beiträge
    7
    Hallo,

    Stimmt der SPI-Modus (Polarität + Phase)?
    Ich denke doch. ich habe die SPI INitialisierung mal ein wenig überarbeitet:
    Code:
    void initSPI(void)                // Initialisierung der SPI Schnittstelle
    {
        SPI_PORT_DDR &=~(1<<SPI_MISO);            // miso auf input
        SPI_PORT_DDR |= (1<<SPI_Clock);          // clock auf output
        SPI_PORT_DDR |= (1<<SPI_MOSI);            // mosi auf output
        SPI_PORT_DDR |= (1<<SPI_SS);            
        Disable();                               
                                               
                                               
        SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPI2X)|(1<<SPR0)|(1<<SPR1)|(1<<CPOL)|(1<<CPHA);    // SPI Enable
                                                                    // Master Select
                                                                    // f_clkio/64
                                                                    // Leading Edge -> Falling
                                                                    // Trailing Edge -> Rising
    Mein Aufruf sieht nun so aus:

    Code:
    volatile uint16_t data= 0;
    
    Enable();                        
    _delay_us(10);                        
    
    SPDR= 0x10;
    while(!(SPSR & (1<<SPIF)));            
    
    data= (SPDR<<8) & 0x3FFF;        
                                        
    SPDR= 0x10;                            
    while(!(SPSR & (1<<SPIF)));              
            
    data+= SPDR;                    
    
    _delay_us(10);
    Disable();
    Was ich sagen kann, ist, dass das CS funktioniert. Geht am Anfang auf High, zum Auslesen wird es dann eben LOW gesetzt und danach wieder High. Anscheinen läuft die Clock nicht.
    Der Code läuft aber so durch. Danach habe ich einfach noch Kontrollausgaben per LED auf meinem Board. Daher sehe ich, dass der komplette Code durchlaufen wird.
    In der Variable data steht aber am Ende nur eine Null drin, wird der Variable am Anfang ja auch zugewiesen. Also ändert sich da nichts, d.h. der Sensor sendet keine Daten. Wie oben schon geschreiben, anscheinend läuft die Clock nicht, somit kann ja auch nichts empfangen werden.

    Wie es scheint, läuft die Clock auch nicht, wenn ich MISO und MOSI direkt verbinde.

    Hat jemand noch eine Idee, woran es liegen könnte?

  4. #4
    Erfahrener Benutzer Roboter Experte Avatar von sternst
    Registriert seit
    07.07.2008
    Beiträge
    672
    Zitat Zitat von Sven_77 Beitrag anzeigen
    Was ich sagen kann, ist, dass das CS funktioniert. Geht am Anfang auf High, zum Auslesen wird es dann eben LOW gesetzt und danach wieder High. Anscheinen läuft die Clock nicht.
    Ich habe da große Zweifel.
    Aber wirklich eindeutig kann ich das nicht sagen, denn das, was du in deinem ersten Post an Code gepostet hast, ist schon einigermaßen ärgerlich. Das sind offenbar nicht sonderlich sorgfältig zusammen kopierte Fragmente. Anscheinend gehören diese Fragmente noch nicht mal zum selben Code, denn es gibt die Defines "SPI_DDR" und "SPI_PORT", benutzt wird dann aber "SPI_PORT_DDR".
    Code:
    CS_PIN         PINE
    Was ist das für eine Zeile? [1]


    Code:
        CS_PIN &= ~(1<<CS_TEMP); // CS auf LOW
    ...
        CS_PIN |= (1<<PE2);     // cs High
    Wieso wird der CS-Pin einmal als "PE2" angesprochen, und einmal als "CS_TEMP"? Was ist "CS_TEMP"?


    Jedenfalls wenn ich die Ungereimtheiten per Raten interpoliere ([1] um "#define" ergänzt, und CS_TEMP=PE2), dann funktioniert dein CS sicher nicht.
    MfG
    Stefan

  5. #5
    Neuer Benutzer Öfters hier
    Registriert seit
    11.03.2008
    Beiträge
    7
    Hallo,

    dass der Code ein wenig durcheinander ist, liegt nicht daran, dass es wild zusammenkopiert ist, sondern daran, dass ich das eine Menge rumprobiert habe und dabei die Ordnung habe schleifen lassen.

    Ich habe das Ganze einmal aufgeräumt, siehe unten.

    Das CS funktioniert sicher. erst ist der Pin HIGH, dann setze ich ihn auf LOW und dann wieder auf HIGH. Das habe ich mir mit dem Oszi angeschaut.
    Ich habe einfach mal den SPI-Kram auskommentiert, ein delay zwischen Sensor-aktivieren und Sensor-deaktivieren eingefügt, CS am Oszi angeschaut und das springt eben wie gewünscht HIGH - LOW - HIGH.

    Bei der Clock sehe ich aber leider nichts.

    Ich habe das Gefühl, dass ich vor lauter Bäumen den Wald nicht mehr sehe.
    SPI - Init:
    Code:
    #define SPI_PIN                PINB
    #define SPI_DDR               DDRB
    #define SPI_PORT             PORTB
    
    #define SPI_MISO        PB3    
    #define SPI_MOSI        PB2    
    #define SPI_Clock        PB1
    #define SPI_SS           PB0
    
    SPI_DDR &=~(1<<SPI_MISO);         // miso auf input
    SPI_DDR |= (1<<SPI_Clock);          // clock auf output
    SPI_DDR |= (1<<SPI_MOSI);          // mosi auf output
    SPI_DDR |= (1<<SPI_SS);             // ss auf output
    PORTE |= (1<<PE2);                   // Sensor deaktivieren
    
    SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPI2X)|(1<<SPR0)|(1<<SPR1)|(1<<CPOL)|(1<<CPHA);    
                                                                    // SPI Enable
                                                                    // Master Select
                                                                    // f_clkio/64
                                                                    // Leading Edge -> Falling
                                                                    // Trailing Edge -> Rising
    Code aus der main:
    Code:
    PORTE &= ~(1<<PE2);                // Sensor aktivieren, CS -> LOW
    _delay_us(10);                          // wait
    SPDR= 0x10;
    while(!(SPSR & (1<<SPIF)));            
    data= (SPDR<<8) & 0x3FFF;        // 8 Bit auslesen
                                    
                                        
    SPDR= 0x01;                            
    while(!(SPSR & (1<<SPIF)));            
    data+= SPDR;                           // Weitere 8 Bit auslesen
    _delay_us(10);                          // wait
    PORTE |= (1<<PE2);                   // Sensor deaktivieren

  6. #6
    Erfahrener Benutzer Robotik Einstein Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    29
    Beiträge
    4.544
    Was ist das für ein µC?

    MfG Hannes

  7. #7
    Neuer Benutzer Öfters hier
    Registriert seit
    11.03.2008
    Beiträge
    7
    Hallo,

    das ist ein AT90CAN128. Der Sensor ist ein Temperatursensor ADT 7301.

  8. #8
    Erfahrener Benutzer Robotik Einstein Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    29
    Beiträge
    4.544
    SPI2X befindet sich im Register SPSR (DORD wäre noch im SPCR Register).

    Versuche es einmal zu ändern.

    MfG Hannes

  9. #9
    Neuer Benutzer Öfters hier
    Registriert seit
    11.03.2008
    Beiträge
    7
    Hallo,

    das mit dem SPI2X ist mir voll durchgegangen. Ich habe es jetzt mal rausgenommen und lasse das Ganze einfach auf f_clkio/64 laufen nur mit SPR1 gesetzt.

    Leider bringt das noch nicht den erwünschten Erfolg. Auch die Einstellung DORD bringt erst einmal scheinbar keine sichtbare Änderung.

    Ich habe so langsam das Gefühl, dass es irgendwie an dem Sensor liegt oder eben am Zusammenspiel. Wenn ich den Sensor abnehme und das Programm laufen lasse, habe ich in "data" immer eine "Null" stehen. Wenn ich ihn anschließe, scheinen Daten empfangen zu werden, allerdings nur Müll wie es scheint.

  10. #10
    Erfahrener Benutzer Robotik Einstein Avatar von 021aet04
    Registriert seit
    17.01.2005
    Ort
    Niklasdorf
    Alter
    29
    Beiträge
    4.544
    Laut Datenblatt muss das 3te Bit eine 1 sein (Shutdown Bit). Die restlichen 15Bit müssen 0 sein. Bei einem 8Bit Register (wie bei deinem µC) musst du einmal 0x20 senden und dann 0x00.

    MfG Hannes

Seite 1 von 2 12 LetzteLetzte

Ähnliche Themen

  1. Probleme mit Asuro IR Schnittstelle
    Von The_Pit im Forum Asuro
    Antworten: 10
    Letzter Beitrag: 09.07.2011, 11:05
  2. probleme mit der RS232 Schnittstelle
    Von FJK im Forum Software, Algorithmen und KI
    Antworten: 1
    Letzter Beitrag: 01.05.2011, 16:36
  3. SPI- Schnittstelle
    Von spa4fe im Forum AVR Hardwarethemen
    Antworten: 7
    Letzter Beitrag: 09.01.2009, 14:29
  4. Probleme mit 4..20mA Schnittstelle
    Von SteffenJ im Forum PIC Controller
    Antworten: 6
    Letzter Beitrag: 01.08.2007, 17:46
  5. Probleme mit V24 Schnittstelle am PDA
    Von albireo im Forum Elektronik
    Antworten: 4
    Letzter Beitrag: 01.08.2006, 00:25

Berechtigungen

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