Orologio SPI su PIC instabile


8

Sto cercando di configurare il modulo MSSP di un PIC18F25K22 in modalità master SPI. Sto guardando i tempi e l'orologio non rimane stabile per tutta la trasmissione. Un'immagine lo mostra meglio delle parole. Diagramma dei tempi SPI

Dopo l'invio di un bit, l'orologio si accorcia e non sempre dello stesso importo. Non ho mai lavorato con SPI prima, ma i diagrammi che ho trovato su Wikipedia e altre risorse non lo mostrano mai. Ho anche collegato un Arduino e non ho visto questo comportamento. Il mio codice è:

    #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
}

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

Qualcuno ha riscontrato questo o hai suggerimenti sulla causa?

Cosa ho fatto

Alla fine, non sono riuscito a far funzionare il modulo MSSP1. Tuttavia, modificandolo nel modulo MSSP2, esattamente lo stesso codice, non è stato riscontrato questo comportamento. Non posso spiegarlo, ma questo ha risolto il problema.


Puoi mostrare il tuo codice per l'utilizzo della SPI?
Gustavo Litovsky,

1
In generale, SPI (e anche I2C) funzionerebbe con un clock non uniforme. SPI è sincrono. Allo stesso tempo, sembra strano che un MSSP hardware generi un clock non uniforme. Quando la linea dati (verde) è bassa, i tuoi orologi sono uniformi. Quando la linea dati è alta, i tuoi orologi sono più brevi. Per ogni evenienza, controlla gli errata per il tuo PIC.
Nick Alexeev

@GustavoLitovsky Ho aggiunto il codice direttamente alla domanda ora.
Trenton Holmes,

@NickAlexeev Grazie, l'ho visto. Nulla di menzionato sul modulo MSSP. Dovrò verificare se il mio slave è in grado di gestire i tempi così come sono.
Trenton Holmes,

Probabilmente non correlato al tuo problema, ma non vedo codice per cancellare i bit ANSEL per le tue porte. Microchip ha fatto la fastidiosa scelta di avere i pin come ingressi analogici di default anziché digitali.
apalopohapa,

Risposte:


3

Questa è un'ipotesi, ma probabilmente stai reimpostando qualcosa che non dovresti essere ogni byte. Cose come il generatore di bit rate e la configurazione periferica generale dovrebbero essere impostate una sola volta.

Inserito il:

Ora dici che non puoi far funzionare MSSP1 ma MSSP2 funziona. Ciò suggerisce che hai un bug altrove nel codice che sta eseguendo scritture non intenzionali. Capita di colpire alcuni stati di MSSP1, motivo per cui agisce in modo strano e perché MSSP2 funziona.

Non lasciarlo andare. Il passaggio a MSSP2 potrebbe sembrare aver risolto il problema, ma nella migliore delle ipotesi hai risolto il problema, probabilmente temporaneamente. La prossima volta che ti colleghi a cose in luoghi diversi, memoria diversa può essere scarabocchiata. Se non lo trovi e lo risolvi davvero, questo firmware sarà sempre traballante. Il caso peggiore è quando non ci sono sintomi evidenti che ti fanno il favore di chiarire che c'è un problema. Il problema apparirà quindi un anno dopo quando si incontrano solo i dati giusti, solo i siti di un cliente, dopo 1000 sono sul campo. FISSA QUESTO IL MODO GIUSTO ORA.


2

Sembra che potresti avere problemi di integrità del segnale: sullo scatto di Los Angeles, sembra che la linea dell'orologio non funzioni quando la linea dati cade. Prova ad assicurarti che i due siano ben isolati e che la traccia o il cablaggio non siano troppo lunghi. Prova anche a rallentare la frequenza di clock o ad aggiungere un piccolo filtro RC sulle linee (se le linee sono lunghe, potrebbe essere utile solo un resistore in serie di 220Ω)

Se si dispone di un oscilloscopio, controllare le linee con questo per assicurarsi che l'integrità del segnale sia buona. In caso contrario, prova i suggerimenti sopra riportati e regola le cose fino a ottenere segnali di buona qualità.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.