Horloge SPI sur PIC instable


8

J'essaie de configurer le module MSSP d'un PIC18F25K22 en mode maître SPI. Je regarde le timing et l'horloge ne reste pas stable pendant toute la transmission. Une image le montre mieux que des mots. Diagramme de synchronisation SPI

Après l'envoi d'un bit, l'horloge se raccourcit, et pas du même montant à chaque fois. Je n'ai jamais travaillé avec SPI auparavant, mais les diagrammes que j'ai trouvés sur Wikipédia et d'autres ressources ne le montrent jamais. J'ai également branché un Arduino et je n'ai pas vu ce comportement. Mon code est:

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

(également https://gist.github.com/stumpylog/5095250 )

Quelqu'un l'a-t-il rencontré ou a-t-il des suggestions sur la cause?

Ce que j'ai fait

Au final, je n'ai pas réussi à faire fonctionner le module MSSP1. Toutefois, la modification du module MSSP2, exactement le même code, n'a pas présenté ce comportement. Je ne peux pas l'expliquer, mais cela a résolu le problème.


Pouvez-vous montrer votre code pour utiliser le SPI?
Gustavo Litovsky

1
Généralement, SPI (et I2C aussi) fonctionnerait avec une horloge non uniforme. SPI est synchrone. Dans le même temps, il semble étrange qu'un MSSP matériel génère une horloge non uniforme. Lorsque la ligne de données (verte) est basse, vos horloges sont uniformes. Lorsque la ligne de données est élevée, vos horloges sont plus courtes. Au cas où, vérifiez les errata de votre PIC.
Nick Alexeev

@GustavoLitovsky J'ai ajouté le code directement à la question maintenant.
Trenton Holmes

@NickAlexeev Merci, je l'ai regardé. Rien de mentionné sur le module MSSP. Je vais devoir vérifier si mon esclave peut gérer le timing tel quel.
Trenton Holmes

Probablement sans rapport avec votre problème, mais je ne vois pas de code pour effacer les bits ANSEL pour vos ports. Microchip a fait le choix ennuyeux d'avoir les broches comme entrées analogiques par défaut au lieu de numériques.
apalopohapa

Réponses:


3

C'est une supposition, mais vous réinitialisez probablement quelque chose que vous ne devriez pas être chaque octet. Des choses comme le générateur de débit binaire et la configuration périphérique générale ne doivent être définies qu'une seule fois.

Ajoutée:

Vous dites maintenant que vous ne pouviez pas faire fonctionner MSSP1 mais que MSSP2 fonctionnait. Cela indique que vous avez un bogue ailleurs dans le code qui effectue des écritures involontaires. Il se trouve qu'il atteint un état MSSP1, c'est pourquoi il agit étrangement et pourquoi MSSP2 fonctionne.

Ne laissez pas cela passer. Le passage à MSSP2 peut sembler avoir résolu le problème, mais au mieux, vous y avez travaillé, probablement temporairement. La prochaine fois que vous établissez un lien avec des objets à différents endroits, une mémoire différente peut être griffonnée. Si vous ne trouvez pas et ne résolvez pas vraiment cela, ce firmware sera à jamais floconneux. Le pire des cas, c'est quand il n'y a pas de symptômes évidents vous faisant la faveur de faire comprendre qu'il y a un problème. Le problème apparaîtra alors un an plus tard lorsque seules les bonnes données seront rencontrées, seuls les sites clients, après 1000 sont sur le terrain. CORRECTEZ LA BONNE FAÇON MAINTENANT.


2

Il semble que vous puissiez avoir des problèmes d'intégrité du signal - sur la photo de LA, il semble que la ligne d'horloge pépine lorsque la ligne de données tombe. Essayez de vous assurer que les deux sont bien isolés et que la trace ou le câblage n'est pas trop long. Vous essayez également de ralentir la fréquence d'horloge ou d'ajouter un petit filtre RC sur les lignes (si les lignes sont longues, juste une résistance série de 220 Ω par exemple peut aider)

Si vous avez un oscilloscope, vérifiez les lignes avec celui-ci pour vous assurer que l'intégrité du signal est bonne. Si ce n'est pas le cas, essayez les suggestions ci-dessus et ajustez les choses jusqu'à ce que vous ayez des signaux de bonne qualité.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.