IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Embarqué Discussion :

Communication SPI PIC16f


Sujet :

Embarqué

  1. #1
    Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique

    Informations forums :
    Inscription : Décembre 2017
    Messages : 10
    Points : 4
    Points
    4
    Par défaut Communication SPI PIC16f
    Bonjour,

    Je souhaiterais envoyer une trame permettant de régler la fréquence par communication SPI. Le code se compile sans erreurs, toutefois je dois oublier des éléments car le PIC programmé ne génère pas de signaux. Pouvez vous me dire si j'oublie des réglages, ou autre ?

    Fichier SPI.h
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    #define TRIS_SCK1 TRISBbits.TRISB6      
    #define TRIS_SS1 TRISCbits.TRISC6       
    #define TRIS_SDO1 TRISCbits.TRISC7     
     
    void SPI_Config( void );            
    signed char SPI1_Write( unsigned char data_out );
    unsigned char SPI1_DataRdy( void );
     
    void Generation_Freq ( unsigned long Fout_MHz, unsigned long Fref_MHz );
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    #pragma config FEXTOSC = OFF, RSTOSC = HFINT32, CLKOUTEN = OFF, CSWEN = ON, FCMEN = OFF   
    #pragma config MCLRE = ON, PWRTE = OFF, WDTE = OFF, LPBOREN = OFF, BOREN = OFF, BORV = LOW, PPS1WAY = OFF, STVREN = OFF, DEBUG = OFF     
    #pragma config WRT = OFF, LVP = ON        
    #pragma config CP = OFF, CPD = OFF         
     
    #include <xc.h>                             
    #include <pic16f18345.h>
    #include "SPI.h"
     
    void main ()
    {
        OSCFRQbits.HFFRQ = 0b100;               
        // while(!OSCSTAT1bits.HFOR);              
     
        SPI_Config();
        Generation_Freq( 1500,10 );
        while(!SPI1_DataRdy());                       
    }
     
    void Generation_Freq ( unsigned long Fout_MHz, unsigned long Fref_MHz )   
    {
        unsigned long N_Div = 0;         
        if (Fref_MHz != 10)
        {
            N_Div = Fref_MHz * 2;                 
            SPI1_Write('R');
            while(!SPI1_DataRdy());   
            for (int i=0;i<4;i++)
            {
                SPI1_Write(N_Div & 256);
                while(!SPI1_DataRdy());
                N_Div = N_Div >> 8;                   
            }
        }
     
        N_Div = Fout_MHz * 2;
        SPI1_Write('D');
        while(!SPI1_DataRdy());
        for (int i=0;i<4;i++)
        {
            SPI1_Write(N_Div & 256);
            while(!SPI1_DataRdy());
            N_Div = N_Div >> 8;                   
        }
    }
     
    void SPI_Config( void )
    { 
        TRIS_SCK1  = 0;                  
        TRIS_SS1 = 0;
        TRIS_SDO1 = 0;                   
     
        SSP1STATbits.SMP = 1;       
        SSP1STATbits.CKE = 0;       
     
        SSP1CON1bits.CKP = 0;       
        SSP1CON1bits.SSPM = 0b0000; 
     
        SSP1CON1bits.SSPEN = 1;
     
        return;      
    }
     
     signed char SPI1_Write( unsigned char data_out )
    {
        unsigned char TempVar;
        TempVar = SSP1BUF;               
        PIR1bits.SSP1IF = 0;             
        SSP1CON1bits.WCOL = 0;           
        SSP1BUF = data_out;              
        if ( SSP1CON1 & 0x80 )        
            return ( -1 );               
        else
            while( !PIR1bits.SSP1IF );   
        return ( 0 );                
    }
     
    unsigned char SPI1_DataRdy( void )
    {
      if ( SSP1STATbits.BF )               
        return ( +1 );                    
      else
        return ( 0 );                 
    }

    Merci pour vos retours.

  2. #2
    Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique

    Informations forums :
    Inscription : Décembre 2017
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    Bonjour, je viens de tout reprendre en détail, je ne comprends toujours pas mon erreur. Quelqu'un peut il me proposer une fonction pour écrire en communication SPI.

  3. #3
    Membre actif Avatar de cedd70
    Homme Profil pro
    Ingénieur R&D
    Inscrit en
    Mars 2012
    Messages
    154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Doubs (Franche Comté)

    Informations professionnelles :
    Activité : Ingénieur R&D
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Mars 2012
    Messages : 154
    Points : 263
    Points
    263
    Par défaut
    Bonjour,

    Il faudrait déjà savoir sur quel PIC tu travaille, ..
    Tu as des note d'appli ou dans la doc de ton micro pour trouver des exemples en général.

  4. #4
    Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique

    Informations forums :
    Inscription : Décembre 2017
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    Bonjour cedd70,

    Je travailles avec le PIC16f18345. J'ai bien essayé de me débrouiller avec les notes d'application. J'ai essayé de suivre leur logique mais là je ne vois plus quoi faire (de plus les exemples que je trouve sont en assembleur).

    Est ce qu'un oublie dans le code te saute aux yeux ?

  5. #5
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 190
    Points : 11 573
    Points
    11 573
    Par défaut
    Salut,
    De prime abord la fonction SPI_Config est bonne avec SSPEN = 1 et tu es configuré en SPI Master mode, clock = FOSC/4

    Pour nous aider, retire tout ce qui n'est pas nécessaire dans ton programme comme la fonction Generation_Freq.

    Pourquoi je ne vois nul part l'utilisation du registre SSPxBUF ?
    Il conditionne le démarrage de SCK.



    A+
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  6. #6
    Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique

    Informations forums :
    Inscription : Décembre 2017
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    Salut,

    Je ne sais pas si cela peut aider mais voici des remarques, de ce qui j'ai souhaité faire :
    Choix de la fréquence d'horloge SPI :
    - RSTOSC = HFINT1 -> Oscillateur interne à 1MHz
    - OSCFRQbits.HFFRQ = 0b0001; -> Modification de la fréquence d'oscillation à 2MHz
    - SSP1CON1bits.SSPM = 0b0001; -> SPI en mode maitre avec 2MHz / 16 = 125KHz (la vitesse de l'horloge ne doit pas dépasser 200
    Définition des broches SPI :
    - MISO n'est pas défini car non utilisé
    - MOSI pour un Pic16f18345 correspond à une broche general I/O (-> Faut il d'autres instructions pour assigner la broche ?)
    - SS défini en tant que sortie.

    Dans la fonction SPI1_Write(), je vide SSP1BUF puis je viens y charger les données.

    Ci-dessous mon code avec juste les fonctions dédiées au SPI :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    #pragma config FEXTOSC = OFF, RSTOSC = HFINT1, CLKOUTEN = OFF, CSWEN = ON, FCMEN = ON  
    #pragma config MCLRE = OFF, PWRTE = OFF, WDTE = OFF, LPBOREN = OFF, BOREN = OFF, BORV = LOW, PPS1WAY = OFF, STVREN = OFF, DEBUG = OFF     
    #pragma config WRT = OFF, LVP = ON        
    #pragma config CP = OFF, CPD = OFF         
    
    #include <xc.h>
    #include <pic16f18345.h>
    #include "SPI.h"
    
    void main ()
    {      
        OSCFRQbits.HFFRQ = 0b0001;                        // Sélection de la fréquence de l'oscillateur à 2MHz
        while(!OSCSTAT1bits.HFOR);              
       
        SPI_Config();
        
        while (1)
        {
            Generation_Freq( 1700,10 );
        }
                            
    }
    
    void SPI_Config( void )
    { 
        SSPSTAT &= 0x3F;               
        SSPCON1 = 0x00;                 
        SSP1CON1bits.SSPM = 0b0001;       //SPI en mode maitre, fréquence d'horloge = (fréquence oscillateur / 16) = 125kHz  
        SSP1STATbits.SMP = 1;           
        
        SSP1CON1bits.CKP = 0;             
        SSP1STATbits.CKE = 0;       
        
        SSP1CON1bits.SSPEN = 1;
        
        TRIS_SCK1 = 0;                  
        TRIS_SS1 = 0;
        TRIS_SDO1 = 0;      
    }
    
     signed char SPI1_Write( unsigned char data_out )
    {
        unsigned char TempVar;
        TempVar = SSP1BUF;               
        PIR1bits.SSP1IF = 0;             
        SSP1CON1bits.WCOL = 0;           
        SSP1BUF = data_out;              
        if ( SSP1CON1 & 0x80 )        
            return ( -1 );               
        else
            while( !PIR1bits.SSP1IF );              // Attend le passage à 1 du bit SSP1IF indiquant que la transmission est terminée
        return ( 0 );                
    }
    
    unsigned char SPI1_DataRdy( void )
    {
      if ( SSP1STATbits.BF )               
        return ( 1 );                    
      else
        return ( 0 );                 
    }

  7. #7
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 190
    Points : 11 573
    Points
    11 573
    Par défaut
    Salut,
    Je suis désolé, je ne peux pas t'aider. La dernière fois que j'ai programmé sur Microchip c'était il y a plus de 10 ans, depuis je suis passé sur des micros tout autres. De plus je n'ai ni MPLABX ni de PIC récent chez moi, je ne peux donc rien essayer ni même être sur de la syntaxe de ton compilateur.

    Par contre, de ce que je vois, ton programme de débuggage est encore bien trop complexe pour que tu arrives à trouver le problème. Il faut littéralement mettre ton programme à poils car si tu ne trouves pas, c'est simplement parce que tu as codé bien trop de lignes de code avant de t'apercevoir que ça ne fonctionnait pas.

    - Retire toutes ces directives du préprocesseur.
    - Pas de variable.
    - Pas de fonction.
    - Ne touche pas à l'oscillateur, laisse le micro démarrer sur son horloge par défaut (interne.)
    - Vérifie si ton PIC est bien vivant avant de chercher plus en profondeur, est ce que tu peux au moins mettre une broche à 1 ?
    - Pour moi le SPI est bien configuré.
    - Il faut regarder effectivement le registre PPS pour l'assignation des broches (de mon temps aucun PIC n'était équipé de ça et en lisant la datasheet + une recherche sur internet, c'est pas super clair, notamment pour les broches sans affectations par défaut, d'ailleurs c'est étonnant que je n'ai rien trouvé sur ce cas de figure précis...et comme je n'ai pas le compilateur.... peut pas essayer. Vu de loin ça ne m'a pas l'air d'être une réussite ce registre de configuration)

    Bon courage.
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

  8. #8
    Candidat au Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique

    Informations forums :
    Inscription : Décembre 2017
    Messages : 10
    Points : 4
    Points
    4
    Par défaut
    Salut,

    Effectivement, il faut utiliser les registres PPS. J'arrive ainsi à sortir les données SCK et SDO.
    Par contre, j'ai toujours un problème avec les lignes de code ci-dessous :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     unsigned long N_Div = 0; 
    ...
    SPI1_Write(N_Div & 256);
                N_Div = N_Div >> 8;
    N_Div doit être constitué de 4 octets que j'envoie avec le LSB en premier. Sauf que lorsque SPI1_Write est appelé, les données d'entrée sont toujours à 0.
    Ex: N_Div=1200 soit 0x00 00 04 B0 -> Je devrais donc envoyer B0 04 00 00

    Quelqu'un à t'il une idée ?

  9. #9
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 190
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 190
    Points : 11 573
    Points
    11 573
    Par défaut
    Salut,
    Dans l'intérêt des membres du forum et des autres, peux tu poster le code qui a résolu le problème initial (affectation du registre PPS, il me semble) ? Nous te remercions par avance.

    Concernant les lignes qui te pose problème, c'est normal car le masque dans SPI1_Write n'est pas bon, c'est 255 qu'il faut mettre.

    Exemple (LSB en premier)
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    unsigned long N_Div = 0x11AA55CC; 
     
    SPI1_Write(N_Div & 0xFF); //LSB
    N_Div = N_Div >> 8;
     
    SPI1_Write(N_Div & 0xFF);
    N_Div = N_Div >> 8;
     
    SPI1_Write(N_Div & 0xFF);
    N_Div = N_Div >> 8;
     
    SPI1_Write(N_Div & 0xFF); //MSB
    N_Div = N_Div >> 8;

    A+
    Vincent
    La science ne nous apprend rien : c'est l'expérience qui nous apprend quelque chose.
    Richard Feynman

Discussions similaires

  1. Communication SPI avec un écran LCD - eDIPTFT43
    Par Coeur1222 dans le forum C
    Réponses: 2
    Dernier message: 14/03/2013, 00h42
  2. MATLAB communication SPI
    Par UgoFerrari dans le forum MATLAB
    Réponses: 3
    Dernier message: 14/12/2012, 09h44
  3. communication fichier binaire fichier txt
    Par micdie dans le forum C
    Réponses: 3
    Dernier message: 05/12/2002, 00h19
  4. communication corba
    Par joejoe dans le forum CORBA
    Réponses: 5
    Dernier message: 14/07/2002, 20h53
  5. communication entre programmes
    Par jérôme dans le forum C
    Réponses: 12
    Dernier message: 16/04/2002, 08h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo