Répondre à la discussion
Affichage des résultats 1 à 2 sur 2

liaison SPI 18f4550 && 30f3014



  1. #1
    Emra

    liaison SPI 18f4550 && 30f3014


    ------

    Bonjour,

    Le SPI à l'air en vogue en ce moment ^^.

    Je réalise une liaison SPI entre les deux pics, le 18f est en maitre et le 30f en esclave.

    J'ai des problèmes d'envoie de message du coté de l'esclave.
    Je me retrouve face au problème suivant. lorsque j'active la liaison (lorsque j'appuie sur le bouton), SCK, SS et SDO du 18f sont correctement envoyées (je les lis à l'oscilloscope). J'arrive aussi à allumer une led : RD9, ce qui semble vouloir dire d'après mon test que le 30f interprète correctement la valeur envoyé par le maitre (18f).

    Lorsque je lis la valeur envoyé par l'esclave (dspic30f), je ne reçois soit rien, soit un signal créneaux, sauf que je ne comprends pas ( certain retour se fond en dessous de la valeur de 0, certain entre 0 et 1).

    J'ai essayé de mettre un dspic30f4013, puisque les broches sont identiques, et la je lis la valeur 5 volt (donc bits à 1 ) en permanence. Même lorsque je n'active pas la liaison ( lorsque je n'appuie pas sur le bouton).

    j'ai parfois d'autre souci, comme lorsque je rajoute de l'allumage de led, certaine fonction ne fonction plus correctement, mais je ne comprends pas ces problèmes de synchronisation puisque je travaille avec des interruptions et que lorsque les interruptions sont activées ( comme BF, IF etc... ) c'est logiquement que j'ai obtenu ce que je veux.


    Je joins mon code, si je pouvais avoir des conseils, je ne vois pas trop ce que je n'ai pas compris. (mes readspi et write spi sont inspiré ou la copie de spi.h, je les rajoute pour que vous puissiez les voir).


    Code du maitre
    [code]

    ****************************** ****************************** ****************************** ****************************** ************/


    // déclaration :

    #include <p18f4550.h>
    short dataRecuSPI = 0;

    unsigned char WriteSPI( unsigned char data_out );
    // short dataEnvoiSPI = 0;

    /*
    void initclk(void) // Fosc = Fin*M/(N1*N2), Fcy=Fosc/2
    {

    // ici Fosc = 20Mhz*10/( )
    CONFIG1L = 0b00000101;

    }*/

    void initSPI18f(void) // initialise SPI sur pic18f4550
    {

    PIR1bits.SSPIF = 0; // flag d'interruption à 0.
    PIE1bits.SSPIE = 0; // désactiver le module d'interruption.

    SSPSTAT = 0; // reset module SPI.
    SSPBUF = 0; // Clear SPI buffer.

    /* Mode Maître, FOSC 1:64. */

    SSPCON1bits.SSPM3 = 0;
    SSPCON1bits.SSPM2 = 0;
    SSPCON1bits.SSPM1 = 1;
    SSPCON1bits.SSPM0 = 0;

    SSPCON1bits.WCOL = 0; // Pas de gestion des collisions.
    SSPSTATbits.SMP = 0; // Input data sampled at end of data output time
    SSPSTATbits.CKE = 0; // Serial output data changes on transition from Idle clock state to active clock state
    SSPCON1bits.CKP = 0; // Idle state for clock is a high level; active state is a low level
    SSPCON1bits.SSPEN = 1; // activer SS, SDO, SDI, SCK
    PIR1bits.SSPIF = 0; // flag d'interruption à 0.
    PIE1bits.SSPIE = 1; // active le module d'interruption.

    }

    int reception_SPI ()
    {



    // Flag de fin de transmission :
    PORTAbits.RA5 = 0; // SS à 0.

    //while(SSPSTATbits.BF != 1) {}
    //dataRecuSPI = SSPBUF; //Lecture du buffer.

    if (SSPSTATbits.BF)
    {

    SSPCON1bits.SSPOV = 0;
    return (SSPBUF); /* return byte read */

    }
    else return -1;

    }

    int envoi_SPI(char dataEnvoiSPI)
    {

    PORTAbits.RA5 = 0; // SS à 0

    //while(SSPSTATbits.BF!=1){} // Flag de fin de transmission.
    WriteSPI(dataEnvoiSPI);

    PORTAbits.RA5 = 1; // SS à 1 : esclave sélectionné : envoie.

    }


    void interruptionSPI(void);

    #pragma code high_vector=0x08

    void interrupt_at_high_vector(void)
    {

    _asm GOTO interruptionSPI _endasm

    }

    #pragma code

    void interruptionSPI(void)
    {
    short val = 0;
    if (PIR1bits.SSPIF)
    val = (short)reception_SPI();

    PIR1bits.SSPIF = 0; // Clear Flag SPI

    return val;
    }

    void main (void)
    {

    int led = 0;

    TRISBbits.TRISB0 = 1; // SDI en entrée
    TRISBbits.TRISB1 = 0; // SCK en sortie
    TRISCbits.TRISC7 = 0; // SDO en sortie
    TRISCbits.TRISC2 = 1; // bouton en entrée
    TRISAbits.TRISA5 = 0; // SS en sortie

    initSPI18f();

    while(1)
    {
    // PORTCbits.RC2 = 0;
    short val = 0;
    if(PORTCbits.RC2 == 1)
    {
    envoi_SPI(0x0e);
    // val = (short)reception_SPI();
    }
    // if(PORTAbits.RA0)
    // envoi_SPI(0x0f);
    // else if(PORTAbits.RA2)
    // envoi_SPI(0x01);
    }

    }




    [\code]

    liaison esclave

    [code]

    /* liaison spi pour un dsPic30f3014. A part l'init, la plupart des fonctions sont inspirées de la librairies spi fournit par microC */




    #include <p30f4013.h>
    #include <spi.h>
    /* initialisation de l'SPI en mode esclave :
    1 en paramètre pour activer les interruptions, 0 sinon. */


    void initSpi_S()
    {

    /*
    TRISFbits.TRISF2 = 1; // SDI en entrée.
    TRISFbits.TRISF3 = 0; // SDO en sortie.
    TRISFbits.TRISF6 = 1; // SCK en entrée.
    TRISBbits.TRISB2 = 1; // SS en entrée.
    SPI1BUF = 0;

    if(interrupt != 0)
    {

    IFS0bits.SPI1IF = 0; // désactive le flag d'interruption.
    IEC0bits.SPI1IE = 1; // active l'interruption du mode SPI.
    IPC2bits.SPI1IP = 5; // priorité de niveau 5 ( les priorités s'échelonnant de 0 à 7, 7 étant la plus élevée).

    }

    SPI1CONbits.MSTEN = 0; // passage en mode esclave.
    SPI1CONbits.SMP = 0; // clear en mode esclave.
    SPI1CONbits.CKE = 0; // comme pour le pic18f4550.
    SPI1STATbits.SPIROV = 0; // Pas d'overflow.

    SPI1CONbits.MODE16 = 0; // mode 8 bits.
    SPI1CONbits.SPRE = 8; // prescaler secondaire à 1.
    SPI1CONbits.PPRE = 0; // prescaler primaire à 64:1.

    SPI1STATbits.SPIEN = 1; // active le module SPI.

    */

    SPI1STATbits.SPIEN = 0; // active le module SPI.
    SPI1STATbits.SPISIDL = 0; // opération du module continue en Idle mode

    IFS0bits.SPI1IF = 0; // Clear the Interrupt Flag
    IEC0bits.SPI1IE = 0; // Disable the Interrupt

    SPI1STAT = 0; // reset module SPI
    SPI1BUF = 0; // Clear SPI buffer

    SPI1CONbits.DISSDO=0; // SDO1 pin is controlled by the module
    SPI1CONbits.MODE16 = 0; // mode 8 bits.
    SPI1CONbits.MSTEN = 0; // passage en mode esclave.
    SPI1CONbits.SMP = 0; // clear en mode esclave.
    SPI1CONbits.CKE = 0; // Serial output data changes on transition from Idle clock state to active clock state
    SPI1CONbits.CKP = 0; // Idle state for clock is a high level; active state is a low level
    // SPI1CONbits.SPRE = 0b111; // Secondary prescale 1:1
    // SPI1CONbits.PPRE = 0b00; // Primary prescale 64:1
    SPI1CONbits.SSEN = 1; // SSx pin is used for Slave mode
    // SPI1CONbits.FRMEN = 0;
    SPI1STATbits.SPIROV = 0;

    IFS0bits.SPI1IF = 0; // Clear the Interrupt Flag
    IEC0bits.SPI1IE = 1; // Enable the Interrupt
    // IPC2bits.SPI1IP = 5; // priorité de niveau 5 ( les priorités s'échelonnant de 0 à 7, 7 étant la plus élevée).

    SPI1STATbits.SPIEN=1; // active le module SPI.

    }

    /* retourne */
    char DataRdySPI1()
    {
    return SPI1STATbits.SPIRBF; /* retourne la valeur du bit RBF */
    }

    void finSPI1()
    {

    IEC0bits.SPI1IE = 0;

    SPI1STATbits.SPIEN = 0;

    IFS0bits.SPI1IF = 0;

    }

    unsigned int ReadSPI1()
    {
    /* Check for Receive buffer full status bit of status register*/
    if (SPI1STATbits.SPIRBF)
    {
    SPI1STATbits.SPIROV = 0;

    if (SPI1CONbits.MODE16)
    return (SPI1BUF); /* return word read */
    else
    return (SPI1BUF & 0xff); /* return byte read */
    }
    return -1; /* RBF bit is not set return error*/
    }


    /* écrit une donnée sur le bus SPI, fonction prévue pour les deux cas 8 bits ou 16 bits */

    void writeSPI1(unsigned int data_envoie)
    {


    if (SPI1CONbits.MODE16) /* word write */
    SPI1BUF = data_envoie;
    else
    SPI1BUF = data_envoie & 0xff; /* byte write */

    }




    void __attribute__((__interrupt__,n o_auto_psv)) _SPI1Interrupt(void)
    {
    PORTDbits.RD0 = 0;
    int dataRecu = 0;
    writeSPI1(0xfe);
    if (IFS0bits.SPI1IF) {
    // if(SPI1STATbits.SPIRBF)

    dataRecu = ReadSPI1();
    if(dataRecu==0x0e) PORTDbits.RD9 = ~PORTDbits.RD9;




    }
    IFS0bits.SPI1IF = 0;
    PORTDbits.RD0 = 1;

    }

    void main(void)
    {

    TRISD = 0;
    TRISFbits.TRISF2 = 1; // SDI en entrée.
    TRISFbits.TRISF3 = 0; // SDO en sortie.
    TRISFbits.TRISF6 = 1; // SCK en entrée.
    TRISBbits.TRISB2 = 1; // SS en entrée.

    initSpi_S();

    while(1)
    {


    // PORTDbits.RD9 = 0;
    }



    }



    [\code]

    Merci

    -----

  2. #2
    cretin

    Re : liaison SPI 18f4550 && 30f3014

    Bonjour, peut être pourrait tu commencer par lire les exemples disponible sur le site de microchip. visiblement tu ne l'a pas fait....
    http://www.microchip.com/CodeExamplesByFunc.aspx
    Une fois que ce sera fait revient nous voire.
    Amicalement

Discussions similaires

  1. CC2430DB de texas instrument & packet Sniffer & Tableur
    Par Choucks dans le forum Électronique
    Réponses: 0
    Dernier message: 13/10/2009, 09h35
  2. SPI & EEPROM : read status en continu
    Par Philou67 dans le forum Électronique
    Réponses: 5
    Dernier message: 01/05/2009, 21h42
  3. Liaison Usb -> Spi avec un pic 18f4550
    Par chang-tout-puissant dans le forum Électronique
    Réponses: 3
    Dernier message: 28/08/2008, 21h12
  4. Liaison mur de soubassement - ossature bois & paille
    Par tannoz dans le forum Habitat bioclimatique, isolation et chauffage
    Réponses: 2
    Dernier message: 30/05/2008, 01h26
Découvrez nos comparatifs produits sur l'informatique et les technologies.