- 12V Akku mit 280 Ah bauen         
Ergebnis 1 bis 8 von 8

Thema: PIC18F SPI über MSSP

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1
    Erfahrener Benutzer Begeisterter Techniker Avatar von Torrentula
    Registriert seit
    10.10.2009
    Ort
    Procyon A
    Beiträge
    355

    PIC18F SPI über MSSP

    Hallo PIC Experten!

    Im Moment bin ich dabei einen 74HC595 mit einem PIC18F2520 anzusteuern, genauer gesagt mit Hilfe des MSSP-Moduls. Ich möchte es im SPI Modus betreiben allerdings bekomme ich keinerlei Clock/Datensignal.

    Leider kann mir hier die wirklich tolle Seite von Sprut auch nicht weiterhelfen, deshalb hier mal mein code:

    Code:
    void spi_init(void){
    
        SSPSTATbits.SMP = 0; // Input data sampled at middle of data output time
        SSPSTATbits.CKE = 0; // Transmit occurs on transition from Idle to active clock state
    
        SSPCON1bits.CKP = 0; // Idle state for clock is a low level
    
        SSPCON1bits.SSPM3 = 0; // F_SPI = F_OSC / 4
        SSPCON1bits.SSPM2 = 0;
        SSPCON1bits.SSPM1 = 0;
        SSPCON1bits.SSPM0 = 0;
    
        // enable MSSP
        SSPCON1bits.SSPEN = 1;
    
        // set SDO (RC5) to output
        TRISCbits.RC5 = 0;
        // set SCK (RC3) to output
        TRISCbits.RC3 = 0;
        // set SS (RA5) to input
        //TRISAbits.RA5 = 1;
    }
    
    void spi_send(unsigned char data){
        // wait until the previous byte has been transmitted
        while( PIR1bits.SSPIF == 0 );
        PIR1bits.SSPIF = 0; // reset SSPIF bit
        SSPBUF = data; // write the data byte to be transmitted to SSPBUF
    }
    Der Teil in der init, bei dem Bits auf low gesetzt werden ist nur testweise und macht keinen Unterschied zu der init ohne diese Sequenz.

    Ich hoffe es gibt hier jemanden der einen möglicherweise simplen Fehler sieht
    MfG Torrentula

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Ich vermute :
    Nach einem Reset (Neustart des Prozessors) ist das Bit SSPIF gelöscht = 0.
    Das wird esvermutlich auch bleiben, solange Du noch nichts raus geschoben hast.
    Du must zumindest erstmal ein Byte rausschieben, damit dieses Bit gesetzt wird.
    Quasi den ganzen Vorgang erstmal starten mit einem Dummy Byte.
    Also direkt in SSPBUF was reinscheiben ohne Beachtung des SSPIF Flags.

  3. #3
    Erfahrener Benutzer Begeisterter Techniker Avatar von Torrentula
    Registriert seit
    10.10.2009
    Ort
    Procyon A
    Beiträge
    355
    Danke für den Input, das Problem war fast wie du sagst:
    Das SSBUF Register muss erst mit dem zu sendenden Byte geladen werden und dann muss man auf das SSPIF Bit warten.

    Ich habe das jetzt so gelöst:
    Code:
    void spi_send(unsigned char data){
        LATCbits.LATC2 = 0; // set CS low
        SSPBUF = data; // write the data byte to be transmitted to SSPBUF
        while(!PIR1bits.SSPIF); // wait for SSPIF bit to be set
        while(!SSPSTATbits.BF); // wait for BF bit to be set --> both bits set = transfer complete (-> double buffered)
        LATCbits.LATC2 = 1; // set CS high
    }
    Bei mir tut sich jetzt eine weitere Frage auf: Wenn ich nicht zusätzlich auf das BF Bit warte, geht CS viel zu früh (ca. ab der hälfte der Übertragung) wieder auf high. Laut Datenblatt wird das SSPIF Bit erst gesetzt, nachdem das Byte vollständig gesendet wurde. Meine Vermutung ist das das Double Buffering durch das SSPBUF Register etwas damit zu tun haben könnte.

    Mit der jetzigen Lösung bin ich allerdings auch nicht recht zufrieden, da CS relativ früh (8 takte vorher) auf high und auch relativ spät (auch ca. 8 takte) wieder auf high, was natürlich die Übertragungsgeschwindigkeit mindert.

    Hat jemand dazu noch eine Idee?
    MfG Torrentula

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Du must das SSPIF Bit auch wieder löschen, sonst ist deine erste while Schleife für die Katz, da das SSPIF-Bit ja noch von der letzen fertigen Übertragung gesetzt ist. Das ist auch der Grund warum dein CS gleich wieder hoch geht.
    Das gleichst Du jetzt quasi aus, indem Du auf das BF-Flag wartest.

    Also lösch mal erst das SSPIF Bit
    dann schreib den neuen Wert ins SSPBUF
    und dann warte auf das IF Bit

    Das BF-Bit ist für deine Anwenung, nur rausschieben, eigentlich irrelevant.

    Das Double Buffering hat damit nichts zu tun.
    Denn das ist nur beim Empfang aktiv. Beim Senden jedoch nicht.

    Ich hoffe, ich liege nicht völlig falsch, hab das auch noch nicht programmiert.

  5. #5
    Erfahrener Benutzer Begeisterter Techniker Avatar von Torrentula
    Registriert seit
    10.10.2009
    Ort
    Procyon A
    Beiträge
    355
    Der folgende code funktioniert leider auch nicht zufriedenstellend, egal ob ich das SSPIF bit vor dem laden von SSPBUF oder nach dem setzen von SSPIF wieder lösche, die CS Leitung ist jetzt gut doppelt so lange low wie sie sein sollte.

    Code:
    void spi_send(unsigned char data){
        LATCbits.LATC2 = 0; // set CS low
        SSPBUF = data; // write the data byte to be transmitted to SSPBUF
        while(!PIR1bits.SSPIF); // wait for SSPIF bit to be set
        PIR1bits.SSPIF = 0; // reset SSPIF bit
        LATCbits.LATC2 = 1; // set CS high
    }
    MfG Torrentula

  6. #6
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    05.11.2007
    Beiträge
    1.076
    Nun müssen wir mal über die Zeiten reden.
    Wieviele Bytes schiebst Du denn raus pro Sekunde, bzw. was hast Du für eine Clockrequenz ?
    und wie lang ist denn dein CS-Signal auf Low.
    Wenn das sooooo Zeitkritisch bei Dir ist, solltest Du Dir mal den Assemblercode ansehen, den der Compiler gemacht hat.
    Im Zweifelsfalle kannst Du mit Assembler noch die eine oder andere Nano/Mikro-sekunde rausholen.
    Kann ich mir kaum vorstellen, dass deine Anwenung dies erfordert.
    Was hast Du denn dran an dem74595 ???

Ähnliche Themen

  1. PIC18F Entwicklungsboard
    Von Torrentula im Forum Suche bestimmtes Bauteil bzw. Empfehlung
    Antworten: 0
    Letzter Beitrag: 09.08.2012, 17:03
  2. PIC18F 32Mhz für Servomotor PWM 50Hz ?
    Von Alan-Lee Perkins im Forum PIC Controller
    Antworten: 1
    Letzter Beitrag: 31.07.2012, 12:07
  3. PIC18F - SDCC-Problem
    Von galdo im Forum PIC Controller
    Antworten: 0
    Letzter Beitrag: 24.03.2007, 11:50
  4. PIC18F mit PICKit2
    Von NF im Forum PIC Controller
    Antworten: 6
    Letzter Beitrag: 07.06.2006, 22:10
  5. Wo PIC18F mit 3936 Ram bestellen??
    Von Pitt1986 im Forum PIC Controller
    Antworten: 3
    Letzter Beitrag: 05.01.2006, 18:58

Berechtigungen

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

fchao-Sinus-Wechselrichter AliExpress