SPI Clock auf PIC instabil

Ich versuche, das MSSP-Modul eines PIC18F25K22 im SPI-Master-Modus zu konfigurieren. Ich schaue auf das Timing und die Uhr bleibt nicht während der gesamten Übertragung konstant. Ein Bild zeigt es besser als Worte.SPI-Timing-Diagramm

Nachdem ein Bit gesendet wurde, verkürzt sich die Uhr, und zwar nicht jedes Mal um denselben Betrag. Ich habe noch nie mit SPI gearbeitet, aber die Diagramme, die ich auf Wikipedia und anderen Ressourcen gefunden habe, zeigen dies nie. Ich habe auch einen Arduino angeschlossen und dieses Verhalten nicht gesehen. Mein Code ist:

    #pragma config FOSC = INTIO67   // Oscillator Selection bits (Internal oscillator block)
#pragma config PLLCFG = OFF     // 4X PLL Enable (Oscillator used directly)
#pragma config BOREN = OFF      // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config WDTEN = OFF      // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
#pragma config MCLRE = EXTMCLR  // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled)
#pragma config LVP = OFF        // Single-Supply ICSP Enable bit (Single-Supply ICSP disabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

void main(void)
{
    OSCCON = 0b11100110;
    spi_setup();
    __delay_ms(10);
    byte temp;
    while (TRUE)
    {
        temp = spi_transfer(0x00);
        temp = spi_transfer(0x01);
        temp = spi_transfer(0x02);
        temp = spi_transfer(0x03);
        temp = spi_transfer(0x04);
        temp = spi_transfer(0x05);
        __delay_us(1);
    }
}

void spi_setup(void)
{
    SSP1STAT = 0b00000000;
    SSP1STATbits.CKE = HIGH; // data transmitted on rising edge
    SSP1CON1 = 0b00000000; // enable Master SPI mode
    SSP1CON1bits.CKP1 = LOW; //clock idle state is low
    //i2c bits, all don't matters for SPI, cleared just in case
    SSP1CON3 = 0;
    // baud rate generation
    SSP1ADD = 0; //FCLOCK = 8Mhz /2 = 2Mhz
    // configure pins for output/input as needed 
    SDI1 = INPUT;
    SDO1 = OUTPUT;
    SCK1 = OUTPUT;
    SS1 = OUTPUT;
    SSP1CON1bits.SSPEN1 = HIGH; // enable pins for serial mode
}

unsigned char spi_transfer(unsigned char data)
{
    SS1_LAT = LOW; // select slave
    PIR1bits.SSPIF = LOW;
    SSP1BUF = data;
    //while (!SSP1STATbits.BF); //wait for receive to complete
    while( !PIR1bits.SSPIF );
    SS1_LAT = HIGH; // deselect slave
    PIR1bits.SSPIF = LOW;   // clear interrupt
    return SSP1BUF; //return data from the slave
}

(auch https://gist.github.com/stumpylog/5095250 )

Ist das jemandem schon mal aufgefallen oder hat eine Idee zur Ursache?

Was ich getan habe

Am Ende konnte ich das MSSP1-Modul nicht zum Laufen bringen. Das Ändern in das MSSP2-Modul, genau derselbe Code, zeigte dieses Verhalten jedoch nicht. Ich kann es nicht erklären, aber das hat das Problem gelöst.

Können Sie Ihren Code für die Verwendung des SPI zeigen?
Im Allgemeinen würde SPI (und auch I2C) mit ungleichmäßigem Takt arbeiten. SPI ist synchron. Gleichzeitig erscheint es merkwürdig, dass ein Hardware-MSSP einen ungleichmäßigen Takt erzeugt. Wenn die Datenleitung (grün) niedrig ist, sind Ihre Uhren einheitlich. Wenn die Datenleitung hoch ist, sind Ihre Uhren kürzer. Überprüfen Sie für alle Fälle die Errata für Ihren PIC.
@GustavoLitovsky Ich habe den Code jetzt direkt zur Frage hinzugefügt.
@NickAlexeev Danke, ich habe es mir angesehen. Nichts erwähnt über das MSSP-Modul. Ich muss prüfen, ob mein Sklave mit dem Timing so klarkommt.
Wahrscheinlich nichts mit Ihrem Problem zu tun, aber ich sehe keinen Code zum Löschen der ANSEL-Bits für Ihre Ports. Microchip hat die lästige Wahl getroffen, dass die Pins standardmäßig analoge statt digitale Eingänge sind.
Wie hast du deinen Code in der Frage so gepostet? Ich habe versucht, mit meiner eigenen Frage eine ähnliche Ausgabe zu erzielen?
@OsagieIgbeare: Sie fügen Ihren Code in Ihre Frage ein, markieren das Ganze und drücken dann Strg-K, wodurch vier Leerzeichen vor jede Zeile gesetzt werden, wodurch der Codeblock-Formatierer aufgerufen wird. Oder Sie können einfach selbst vier Leerzeichen vor jede Zeile setzen, bevor Sie sie einfügen.

Antworten (2)

Dies ist eine Vermutung, aber Sie setzen wahrscheinlich etwas zurück, das Sie nicht jedes Byte sein sollten. Dinge wie der Bitratengenerator und die allgemeine Peripheriekonfiguration sollten nur einmal eingestellt werden.

Hinzugefügt:

Sie sagen jetzt, dass Sie MSSP1 nicht zum Laufen bringen konnten, aber MSSP2 zum Laufen gebracht haben. Das deutet darauf hin, dass Sie an anderer Stelle im Code einen Fehler haben, der unbeabsichtigte Schreibvorgänge ausführt. Es trifft zufällig einen MSSP1-Zustand, weshalb es sich seltsam verhält und warum MSSP2 funktioniert.

Lass das nicht einfach so. Der Wechsel zu MSSP2 scheint das Problem behoben zu haben, aber bestenfalls haben Sie es umgangen, wahrscheinlich vorübergehend. Wenn Sie das nächste Mal mit Dingen an verschiedenen Orten verknüpfen, werden möglicherweise andere Erinnerungen darauf gekritzelt. Wenn Sie dies nicht finden und wirklich beheben, wird diese Firmware für immer flockig sein. Der schlimmste Fall ist, wenn es keine offensichtlichen Symptome gibt, die Ihnen den Gefallen tun, um deutlich zu machen, dass ein Problem vorliegt. Das Problem tritt dann ein Jahr später auf, wenn genau die richtigen Daten angetroffen werden, nur ein Kundenstandort, nachdem 1000 im Feld sind. BEHEBEN SIE DIES JETZT RICHTIG.

Es sieht so aus, als hätten Sie Probleme mit der Signalintegrität - auf der LA-Aufnahme scheint es, als ob die Taktleitung Störungen hat, wenn die Datenleitung abfällt. Stellen Sie sicher, dass die beiden gut isoliert sind und die Spur oder Verdrahtung nicht zu lang ist. Sie versuchen auch, die Taktrate zu verlangsamen oder einen kleinen RC-Filter in die Leitungen einzufügen (bei langen Leitungen kann nur ein Vorwiderstand von beispielsweise 220 Ω helfen).

Wenn Sie ein Oszilloskop haben, überprüfen Sie die Leitungen damit, um sicherzustellen, dass die Signalintegrität gut ist. Wenn dies nicht der Fall ist, versuchen Sie die obigen Vorschläge und passen Sie die Dinge an, bis Sie Signale von guter Qualität haben.