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

Comm. I2C : PIC16F - MAG3110



  1. #1
    Pilpilou

    Comm. I2C : PIC16F - MAG3110


    ------

    Bonjour,

    Je suis nouveau sur le forum, je suis étudiant à Polytech Marseille j'en suis à BAC+4, j'étudie principalement l'électronique et les télécommunications.


    J'essaire depuis plusieurs jours de récupérer via mon pic16f1825 les données mesurées par le magnétomètre de chez freescale : MAG3110. La communication entre les deux composants se fait via le protocole I2C. J'ai paramétré mon pic puis j'essaie de paramétré les registres de mon magnétomètre via la comm. I2c, puis pour vérifier que cela marche, lorsque j'essaie de lire les deux registres de configuration du magnétomètre, IMPOSSIBLE. Je reçois soit 0000000 soit 11111111.... Je ne comprend pas d'où vient le problème !!
    J'utilise MPLABX un debogueur ICD3 et le DEV KIT ADC244043 pour simuler le pic 16F1825. Mon magnétomètre est branché sur le LFSTBEB3110 sensor board.

    Merci pour votre aide,

    Mon code est le suivant :

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <stdint.h>
    #include <xc.h>
    #include "fonctions.h"
    #include "pic16f1825.h"
    
    #define _XTAL_FREQ 8000000
    
    
    #ifndef CONFIG_BITS_H
    #define	CONFIG_BITS_H
    
    // CONFIG1
    #pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
    #pragma config WDTE = OFF       // Watchdog Timer Enable (WDT enabled)
    #pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
    #pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
    #pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
    #pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
    #pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset enabled)
    #pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
    #pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
    #pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
    
    // CONFIG2
    #pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
    #pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
    #pragma config STVREN = OFF     // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
    #pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
    #pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
    
    #endif	/* CONFIG_BITS_H */
    
    #define CTRL_REG1  0x10
    #define CTRL_REG2  0x11
    
    #define INIT_REG1  0b01100001
    #define INIT_REG2  0b10000000
    
        int8_t x_mesure;
        int8_t y_mesure;
        int8_t z_mesure;
    
    
    int main(int argc, char** argv)
    {
    
    //-----------------------------Variable locale----------------------------------
    
        uint8_t x_flag;
        uint8_t y_flag;
        uint8_t z_flag;
        uint8_t reg1=0;
        uint8_t reg2=0;
    
    //*********************************************************************
    //-------------------------Initialisation-PIC--------------------------
    
    
        OPTION_REGbits.nWPUEN =0b0 ;   //Weak pull-ups are enabled by individual WPUx latch values
        OPTION_REGbits.TMR0CS =0b0 ;   //Internal instruction cycle clock (FOSC/4)
        OPTION_REGbits.INTEDG =0b0 ;   //Interrupt on rising edge of RB0/INT pin
    
        PCON = 0b00000000;             //Flags à 0
    
    
    //--------------------------INTERRUPTIONS-----------------------------
    
        INTCONbits.TMR0IF =0b0;     //TMR0 register did not overflow
        INTCONbits.TMR0IE =0b0;     //Disables the Timer0 interrupt
        INTCONbits.INTE =0b0;       //Enables the INT external interrupt
        INTCONbits.INTF =0b0;       //The INT external interrupt did not occur
        INTCONbits.IOCIE =0b0;      //Enables the interrupt-on-change
        INTCONbits.IOCIF =0b0;      //None of the interrupt-on-change pins have changed state
        INTCONbits.PEIE =0b0;       //Enables all active peripheral interrupts
    
        PIE1bits.SSP1IE =0b1;       //Enables the MSSP interrupt
        PIE2bits.BCL1IE =0b1;       //Enables the MSSP Bus Collision Interrupt
    
    
        PIR1 = 0b00000000;          // Initiate low every interrupts flag
        PIR2 = 0b00000000;          // Initiate low every interrupts flag
        PIR3 = 0b00000000;          // Initiate low every interrupts flag
    
        INTCONbits.GIE = 0b1;       //Enables all active interrupts
    
    
        //------------------------OSCILLATEUR-------------------------------
    
        OSCCONbits.IRCF = 0b1110;   //Frequence d'oscylateur à 8Mhz
        OSCCONbits.SCS = 0b10;      // INT. OSC.
        OSCCONbits.SPLLEN = 0b0;    // PLL disabled
    
    
         //-------------------------I/O----------------------------------
        ANSELA=0b00000000;          // TOUTE LES IO en DIGITAL
        ANSELC=0b00000000;          // TOUTE LES IO en DIGITAL
        WPUA=0b00000000;            // PAS de PULL-UP sur le PORT A
        WPUC=0b00000011;            // PAS de PULL-UP sur le PORT C excepté pour SCA et SCL qui sont sur RC0 et RC1
    
        LATA = 0b00000000;          // Initialisation des registres port A à 0
        LATC = 0b00000011;          // Initialisation des registres port C à 0 excepté pour SCA et SCL qui sont sur RC0 et RC1
        PORTA =0b00000000;          // Initialisation des registres port A à 0
        PORTC =0b00000011;          // Initialisation des registres port C à 0 excepté pour SCA et SCL qui sont sur RC0 et RC1
    
        TRISCbits.TRISC5 = INPUT;   // RX Input
        TRISCbits.TRISC4 = OUTPUT;  // TX Output
        TRISCbits.TRISC0 = INPUT;   // SCL Input (CF datasheet)
        TRISCbits.TRISC1 = INPUT;   // SDA Input (CF datasheet)
    
    
    
        //------------------------BAUD RATE-------------------------------
    
        BAUDCONbits.SCKP=0b1;     // Niveau 0 sur CLK au repos (Transmit non-inverted data to the TX/CK pin)
        BAUDCONbits.BRG16=0b0;    // 8 bits baud rate generator
        BAUDCONbits.WUE=0b0;      // Normal mode
    
    
    
        //------------------------------I2C-----------------------------------
    
        SSP1STATbits.SMP =0b0  ;    //Slew rate control disabled for standard speed mode (100 kHz and 1 MHz)
        SSP1STATbits.CKE= 0b1;      //Enable input logic so that thresholds are compliant with SMbus specification
    
    
        SSP1CON1bits.SSPEN=0b1;     // Enables the serial port and configures the SDAx and SCLx pins as the source of the serial port pins(
        SSP1CON1bits.SSPM = 0b1000; //I2C Master mode, clock = FOSC / (4 * (SSPxADD+1))
    
        SSP1CON2 =0x80;
    
        SSP1CON3bits.SDAHT =0b1;    //Minimum of 300 ns hold time on SDAx after the falling edge of SCLx (100ns if = 0)
        SSP1CON3bits.PCIE =0b1;     // Enable interrupt on detection of Start or Restart conditions
        SSP1CON3bits.SCIE =0b1;     // Enable interrupt on detection of Stop conditions
        SSP1CON3bits.SBCDE =0b1;    // Eable interupt on detection of bu collision
    
    
        SSP1BUF = 0b00000000;       // I2C buffer initialized
    
        TXSTAbits.CSRC =0b1;        // Master mode (clock generated internally from BRG)
        TXSTAbits.TX9 =0b0;         // Selects 8-bit transmission
        RCSTAbits.SPEN =0b0;        // Serial port disabled (held in Reset)
    
        SSP1ADD = 0b00010011;                // set Baud rate clock divider
    
        // **************************************************************************************
        // The SSPADD register value  is used to determine the clock rate for I2C communication.
        // Equation for I2C clock rate:   Fclock = Fosc/[(SSPADD +1)*4]
        // For this example we want the the standard 100Khz I2C clock rate and our
        // internal Fosc is 8Mhz so we get:  100000 = 8000000/[(SSPADD+1)*4]
        // or solving for SSPADD = [(8000000/100000)-4]/4
        // and we get SSPADD = 19
    
    
    
    
    //*****************************************************************************
    //-----------------------------Initialisation-MAG------------------------------
    
        I2C_StartBit();                     // send start bit
        I2C_ControlByte_Sending();          // send control byte with writing option
        Select_Register (CTRL_REG1);        // Select the right register
        Send_I2C_Data(INIT_REG1);            // send data byte
        I2C_StopBit();                      // send stop bit
    
        Wait_Idle ();
    
        I2C_StartBit();                     // send start bit
        I2C_ControlByte_Sending();          // send control byte with writing option
        Select_Register (CTRL_REG2);        // Select the right register
        Send_I2C_Data(INIT_REG2);            // send data byte
        I2C_StopBit();                  // send stop bit
    
        Wait_Idle ();
    
    //*********************************************************
    //-----------------------------PROGRAMME------------------------------
    
        Wait(3);
    
        I2C_StartBit();                     // send start bit
        I2C_ControlByte_Sending();          // send control byte with writing option
        Select_Register (CTRL_REG1);        // Select the right register
        I2C_RestartBit();                   // Restart
        I2C_ControlByte_Reading();          // Send control byte with reading option
        reg1 = Read_I2C_Data();             // Lecture de reg1
        Send_I2C_NAK();                     // Send NAK
        I2C_StopBit();                      // Send stop bit
    
        Wait_Idle ();
    
        I2C_StartBit();                     // send start bit
        I2C_ControlByte_Sending();          // send control byte with writing option
        Select_Register (CTRL_REG2);        // Select the right register
        I2C_RestartBit();                   // Restart
        I2C_ControlByte_Reading();          // Send control byte with reading option
        reg2 = Read_I2C_Data();             // Lecture de reg1
        Send_I2C_NAK();                     // Send NAK
        I2C_StopBit();                      // Send stop bit
    
    }
    
    
    
    
    
    void Wait (uint16_t i)
    {
        uint8_t j=0;
        while (i!=0) {
           for (j=0; j<255; j++){
           }
           i--;
        }
    }
    
    
    void I2C_StartBit(void)
    {
        PIR1bits.SSP1IF=0;                      // Set low the I2C Flag
        SSP1CON2bits.SEN=0b1;                   // send start bit
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    void I2C_RestartBit (void)
    {
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
        SSP1CON2bits.RSEN=0b1;                   // send start bit
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    
    }
    
    
    void I2C_StopBit(void)
    {
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
        SSP1CON2bits.PEN=0b1;                   // send stop bit
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    
    void I2C_ControlByte_Sending(void)
    {
        do{
        SSPCON1bits.WCOL =0;                    // Clear bus collision flag
        SSP1BUF = 0b00011100;                   // send the control byte WITH SLAVE ADRESS & R_nW
        } while (SSPCON1bits.WCOL);            // WAIT THE WRITING OPERATION BEEN DONE WITHOUT COLLISION
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    void I2C_ControlByte_Reading(void)
    {
        do{
        SSPCON1bits.WCOL =0;                    // Clear bus collision flag
        SSP1BUF = 0b00011101;                   // send the control byte WITH SLAVE ADRESS & R_nW
        } while (SSPCON1bits.WCOL);            // WAIT THE WRITING OPERATION BEEN DONE WITHOUT COLLISION
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    void Select_Register (uint8_t RegisterAdress)
    {
        do{
        SSPCON1bits.WCOL =0;                    // Clear bus collision flag
        SSP1BUF = RegisterAdress;                   // send the control byte WITH register adress
        } while (SSPCON1bits.WCOL);            // WAIT THE WRITING OPERATION BEEN ONE WITHOUT COLLISION
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    void Send_I2C_Data(uint8_t DataByte)
    {
        do{
        SSPCON1bits.WCOL =0;                    // Clear bus collision flag
        SSP1BUF = DataByte;                   // send the control byte WITH register adress
        } while (SSPCON1bits.WCOL);            // WAIT THE WRITING OPERATION BEEN ONE WITHOUT COLLISION
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    
    
    
    uint8_t Read_I2C_Data(void)
    {
        PIR1bits.SSP1IF=0b0;            // clear SSP interrupt bit
        SSP1CON2bits.RCEN=0b1;          // set the receive enable bit to initiate a read of 8 bits from the serial eeprom
        while (!PIR1bits.SSP1IF);
        while (SSP1STATbits.BF);
        return (SSP1BUF);            // Data from eeprom is now in the SSPBUF so return that value
    }
    
    
    
    void Send_I2C_ACK(void)
    {
       PIR1bits.SSP1IF=0b0;          // clear SSP interrupt bit
       SSP1CON2bits.ACKDT=0b0;        // clear the Acknowledge Data Bit - this means we are sending an Acknowledge or 'ACK'
       SSP1CON2bits.ACKEN=0b1;        // set the ACK enable bit to initiate transmission of the ACK bit to the serial eeprom
       while(SSP1CON2bits.ACKEN);    // Wait for interrupt flag to go high indicating transmission is complete
    }
    
    
    
    void Send_I2C_NAK(void)
    {
        PIR1bits.SSP1IF=0b0;           // clear SSP interrupt bit
        SSP1CON2bits.ACKDT=0b1;        // set the Acknowledge Data Bit- this means we are sending a No-Ack or 'NAK'
        SSP1CON2bits.ACKEN=0b1;        // set the ACK enable bit to initiate transmission of the ACK bit to the serial eeprom
        while(SSP1CON2bits.ACKEN);     // Wait for interrupt flag to go high indicating transmission is complete
    }
    
    void Wait_Idle (void)
    {
        while ((SSPCON2 & 0x1F) | (SSPSTATbits.R_nW));      // Wait for idle
    }

    -----

  2. Publicité
  3. #2
    invite03481543

    Re : Comm. I2C : PIC16F - MAG3110

    Bonsoir,

    Qu'avez-vous mis en pull-up sur SCL et SDA?
    Avez-vous branché un oscilloscope pour regarder ce qui se passe sur le bus?

  4. #3
    RISC

    Re : Comm. I2C : PIC16F - MAG3110

    Salut,

    Avant de regarder ton logiciel, il faut vérifier la partie hardware.
    Peux-tu poster le schéma électronique à jour de ton système ?
    Quel programmateur/debogueur utilises-tu (Pickit3, ICD3) ?
    L'adaptateur AC244043 ne peut fonctionner qu'avec un Pickit3, ou ICD3 mais il est uniquement Optionnel si tu veux liberer des broches (PGC, PGD).
    Pour verifier si ton ICSP fonctionne, tu peux utiliser simplement le Pickit3.
    La documentaton du AC244043 se trouve ici : http://ww1.microchip.com/downloads/e...Doc/51292U.pdf

    Pour initialiser le PIC18F1825, je te recommande d'utiliser le configurateur graphique de MPLAB X.
    Tu charges le plugin MCC (Microchip Code Composer) à partir de MPLAB X et tu pourras générer automatiquement le code ;=)
    Tout est expliqué ici sur Code Composer : http://www.microchip.com/MCC.

    a+
    Dernière modification par RISC ; 06/07/2014 à 11h55.
    Ma marotte ? les microcontrôleurs ;=)

  5. #4
    Pilpilou

    Re : Comm. I2C : PIC16F - MAG3110

    Bonjour,

    Merci pour vos réponses rapide.

    @HULK28, Je n'ai branché en Pull-Up que les pins que j'utilise pour SCL et SDA. J'ai essayé de regarder mes signaux à l'aide d'un oscillo, mais je n'arrive pas bien à m'en servir, je ne vois aucun signal clair... Peut-être que comme le suggère RISC j'ai un problème de hardware.

    @RISC j'utilise le débogueur ICD3. Que veulent dire PGC et PGD ?
    Concernant mon montage, j'ai relié les broches Vdd / Vss et SDA / SCL uniquement, en respectant les schémas du pic16f1825 et du LFSTBEB3110 http://cache.freescale.com/files/sen...EB3110_sch.pdf

    cf Page 5 : http://ww1.microchip.com/downloads/e...Doc/41440A.pdf

    Sur la photo, en blanc c'est Vdd en noir Vss en Jaune SDA et en rouge SCL
    Images attachées Images attachées
    Dernière modification par Pilpilou ; 07/07/2014 à 09h12.

  6. A voir en vidéo sur Futura
  7. Comparatifs

    Gagnez du temps et de l'argent grâce à nos comparatifs de produits. Parmi nos sujets :
  8. #5
    RISC

    Re : Comm. I2C : PIC16F - MAG3110

    Salut,

    Je pense que tu utilises l'adaptateur AC244043 de manière limite...
    Le PIC sur cet adaptateur est un PIC "spécial" pour le debug du PIC16F1825.
    Je te recommande de commander, si tu n'en as pas, de commander des échantillons gratuits du PIC16F1825.
    Il faut cabler ta plaque à trous comme si c'était le PIC16F1825 :
    * une résistance de pull-up de 10K sur MLCR
    Ensuite, vérifie que tu as bien sélectionné l'adaptateur AC244043 dans ton projet MPLAB X.
    Je pense que cela devrait être visible dans la fenêtre dashboard

    Comment alimentes-tu ta carte ? (Apparemment tu utilises l'ICD3 ?)
    Si c'est le cas, dans ton projet, dans le gestionnaire de configuration, tu dois mettre en focus l'ICD3 > menu déroulant "Option categories" > Power > Power target circuit from ICD3 (vérifies que le niveau d'alimentation choisi est compatible avec le circuit MAG3110).

    Arrives-tu à te connecter à ta plaqua à trous en mode Debug. Quel message as-tu ?

    Quelle version de MPLAB X utilises-tu ?
    As-tu mis des résistances de pull-up sur SCL et SDA ? existent-elles déjà sur ton module MAG3110 ?

    a+
    Dernière modification par RISC ; 07/07/2014 à 12h06.
    Ma marotte ? les microcontrôleurs ;=)

  9. #6
    Pilpilou

    Re : Comm. I2C : PIC16F - MAG3110

    J'ai câblé mon adaptateur comme si c'était un pic16f1825 justement, sur ma carte à trou. (CF photo)
    J'ai configuré mon projet tel que ma carte soit alimenté par le débogueur ICD3 (j'ai vérifié les niveaux d'alimentation, = 3,625V), j'ai déclaré l'adaptateur AC244043.

    J'utilise MPLABX IDE V2.10.

    Quand je lance le mode débug, j'arrive à faire tourner le programme, et quand j'observe mes variables je m’aperçois que la configuration des registres à fonctionné, en revanche lorsque j'essaie de lire des donnes, SSPBUF (le buffer d'échange de donnée I2C) ne me renvoie que des 1. Aussi, lorsque j'essaie de fixer un port à 1 pendant un dt puis 0, l'état du port reste inchangé dans mes variables... !! J'ai du mal à comprendre cela.
    Je n'ai mis aucune résistance de pull-up sur SCL et SDA sur ma carte à trou. Sur le module du MAG3110, il y a les emplacements pour les résistances, mais elles n'y sont pas soudées.

    J'ai essayé de lancer le "Debugueur/Programmeur self test", il me renvoie les messages suivants :

    Test interface PGC clock line write failure. Please ensure that the tester is properly connected.

    Test interface PGD data line write not tested.

    Test interface PGC clock line read not tested.

    Test interface PGD data line read not tested.

    Test interface LVP control line not tested.

    Test interface MCLR level not tested.

    Interface test could not be completed. Please contact your local FAE/CAE to SAR the unit.





    Merci pour votre aide.

  10. Publicité
  11. #7
    RISC

    Re : Comm. I2C : PIC16F - MAG3110

    Salut,
    Bon, si tu entres en debug tout va bien coté ICD3 et adaptateur AC244043.
    L'auto-test doit se faire avec un bouchon qui se met au bout du cable RJ11 sinon MPLAB X ne peut rien tester.
    De toute façon au vu de ce que tu décris tout fonctionne correctement.

    Par contre il FAUT absolument mettre 2 resistances de pull up de 10K, soit sur ta plaque à trous soit sur le module MAG3110.

    Ensuite, je te recommande de charger le plugin Microchip Code Configurator et de l'utiliser pour générer le code de l'I2C ou alors tu cherches des exemples I2C pour les PIC16F1xxx sur internet.

    Tu as apparemment un oscilloscope. Regardes si tu vois les transitions sur SDA et SCL. Tant que tu ne verras rien c'est que l'initialisaiton de l'I2C n'est pas correcte

    a+
    Dernière modification par RISC ; 07/07/2014 à 14h11.
    Ma marotte ? les microcontrôleurs ;=)

  12. #8
    Pilpilou

    Re : Comm. I2C : PIC16F - MAG3110

    Je vais alors placé ces résistances, 10K vous êtes sur ? Car sur la datasheet du MAG3110 on parle de 4,7K.... J'ai du mal à comprendre que mon initialisation ne fonctionne pas, j'ai testé de nombreuses combinaisons, et surtout j'ai chargé le code example de microchip... :S

    Bref, je vais essayé cette fois avec les résistances, et en utilisant le plugin code configurator.

    Merci,

  13. #9
    RISC

    Re : Comm. I2C : PIC16F - MAG3110

    Salut,
    Les resistances ce n'est pas une option. Si tu ne les mets pas cela ne marchera jamais car les drain ouverts flotteront...
    Si le MAG3110 recommande des resistances des 4,7k utilise des 4,7k. La valeur de 10K dont j'ai parlé est uen valeur pifométrique. La vraie valeur doit être calculée à partir du protocole I2C qui donne la formule qui dépend de l'impédance d'entrée de chacun des circuits connectés au bus I2C.
    Ensuite, regarde si tu vois des signaux avec l'oscilloscope. Tant que rien ne bouge c'est que l'initialisation des broches n'est pas correcte.
    a+
    Ma marotte ? les microcontrôleurs ;=)

  14. #10
    Pilpilou

    Re : Comm. I2C : PIC16F - MAG3110

    Salut,

    J'arrive à présent à voir mes signaux à l'oscillo, en revanche, mon code ne marche toujours pas.... :S
    Lorsque je passe en debug et que je fais du step by step je m’aperçois que régulièrement le Program Counter revient au début de mon algo... dans la phase d'init, alors qu'il n'est pas censé retourner là bas, du coup mon programme recommence à 0 !! Je comprends pas d'où cela peut venir.

  15. #11
    Pilpilou

    Re : Comm. I2C : PIC16F - MAG3110

    EDIT :

    C'est bon mon programme se déroule normalement, il ne retourne plus à son état initial de manière intempestive. Aussi, j'observe les signaux à l'oscillo, en revanche, je ne parviens toujours pas à lire de données... Je récupère dans mes variables reg1 et reg2 la valeur précédente prise par SSP1BUF (le buffer d'échange I2C), et non pas la nouvelle valeur, celle que j'essaie de lire. Enfait, SSP1BUF ne se met pas à jour comme il le devrait dans la fonction Read_I2C_Data !!


    Je me suis servis de Code Configurator pour corriger mon initialisation I/O et ainsi paramétrer les broches comme il le faut, par contre ensuite j'ai rebasculé sur mon code, car les fonctions proposées par code configurator pour l'I2C me sont incompréhensibles.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <stdint.h>
    #include <xc.h>
    #include "fonctions_yyy.h"
    #include "pic16f1825.h"
    
    #define _XTAL_FREQ 8000000
    
    
    #ifndef CONFIG_BITS_H
    #define	CONFIG_BITS_H
    
    // CONFIG1
    #pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
    #pragma config WDTE = OFF       // Watchdog Timer Enable (WDT enabled)
    #pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
    #pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
    #pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
    #pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
    #pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset enabled)
    #pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
    #pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
    #pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
    
    // CONFIG2
    #pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
    #pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
    #pragma config STVREN = OFF     // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
    #pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
    #pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
    
    #endif	/* CONFIG_BITS_H */
    
    
    #define CTRL_REG1  0x10
    #define CTRL_REG2  0x11
    #define INIT_REG1  0b01100001
    #define INIT_REG2  0b10000000
    
    
    int main(int argc, char** argv)
    {
    
    //-----------------------------Variable locale----------------------------------
    
        uint8_t reg1=0;
        uint8_t reg2=0;
    
    //*****************************************************
    //-------------------------Initialisation-PIC--------------------------
    
        OPTION_REG = 0x00;
        
        PCON = 0b00000000;             //Flags à 0
    
    
    //--------------------------INTERRUPTIONS-----------------------------
        INTCONbits.TMR0IF =0b0;     //TMR0 register did not overflow
        INTCONbits.TMR0IE =0b0;     //Disables the Timer0 interrupt
        INTCONbits.INTE =0b1;       //Enables the INT external interrupt
        INTCONbits.INTF =0b0;       //The INT external interrupt did not occur
        INTCONbits.IOCIE =0b0;      //Enables the interrupt-on-change
        INTCONbits.IOCIF =0b0;      //None of the interrupt-on-change pins have changed state
        INTCONbits.PEIE =0b0;       //Enables all active peripheral interrupts
    
        PIE1bits.SSP1IE =0b1;       //Enables the MSSP interrupt
        PIE2bits.BCL1IE =0b1;       //Enables the MSSP Bus Collision Interrupt
    
    
        PIR1 = 0b00000000;          // Initiate low every interrupts flag
        PIR2 = 0b00000000;          // Initiate low every interrupts flag
        PIR3 = 0b00000000;          // Initiate low every interrupts flag
    
        INTCONbits.GIE = 0b1;       //Enables all active interrupts
    
    
        //------------------------OSCILLATEUR-------------------------------
        OSCCON = 0x72;              // PLL disabled INT. OSC.Frequence d'oscylateur à 8Mhz
    
    
         //-------------------------I/O----------------------------------
        ANSELA=0b00000000;          // TOUTE LES IO en DIGITAL
        ANSELC=0b00000000;          // TOUTE LES IO en DIGITAL
        WPUA=0b00000000;            // PAS de PULL-UP sur le PORT A
        WPUC=0b00000000;            // PAS de PULL-UP sur le PORT C excepté pour SCA et SCL qui sont sur RC0 et RC1
    
        LATA = 0b00000000;          // Initialisation des registres port A à 0
        LATC = 0b00000011;          // Initialisation des registres port C à 0 excepté pour SCA et SCL qui sont sur RC0 et RC1
        PORTA =0b00000000;          // Initialisation des registres port A à 0
        PORTC =0b00000011;          // Initialisation des registres port C à 0 excepté pour SCA et SCL qui sont sur RC0 et RC1
    
        TRISA = 0x3F;
        TRISC = 0x3F;
    
    
        //------------------------BAUD RATE-------------------------------
        BAUDCONbits.SCKP=0b1;     // Niveau 0 sur CLK au repos (Transmit non-inverted data to the TX/CK pin)
        BAUDCONbits.BRG16=0b0;    // 8 bits baud rate generator
        BAUDCONbits.WUE=0b0;      // Normal mode
    
    
    
        //------------------------------I2C-----------------------------------
        SSP1STATbits.SMP =0b0  ;    //Slew rate control disabled for standard speed mode (100 kHz and 1 MHz)
        SSP1STATbits.CKE= 0b1;      //Enable input logic so that thresholds are compliant with SMbus specification
    
    
        SSP1CON1bits.SSPEN=0b1;     // Enables the serial port and configures the SDAx and SCLx pins as the source of the serial port pins(
        SSP1CON1bits.SSPM = 0b1000; //I2C Master mode, clock = FOSC / (4 * (SSPxADD+1))
    
        SSP1CON2 =0x80;
    
        SSP1CON3bits.SDAHT =0b1;    //Minimum of 300 ns hold time on SDAx after the falling edge of SCLx (100ns if = 0)
        SSP1CON3bits.PCIE =0b1;     // Enable interrupt on detection of Start or Restart conditions
        SSP1CON3bits.SCIE =0b1;     // Enable interrupt on detection of Stop conditions
        SSP1CON3bits.SBCDE =0b1;    // Eable interupt on detection of bu collision
    
    
        SSP1BUF = 0b00000000;       // I2C buffer initialized
        SSP1ADD = 0b00010011;      // set Baud rate clock divider
    
     
    //***********************************************************
    //-----------------------------Initialisation-MAG------------------------------
      
        while(1)
        {
            I2C_StartBit();                 // send start bit
            I2C_ControlByte_Sending();      // send control byte with writing option
            Select_Register (CTRL_REG1);    // Select the right register
            Send_I2C_Data(INIT_REG1);            // send data byte
            I2C_StopBit();                      // send stop bit
    
            Wait_Idle ();
    
            I2C_StartBit();                     // send start bit
            I2C_ControlByte_Sending();          // send control byte with writing option
            Select_Register (CTRL_REG2);        // Select the right register
            Send_I2C_Data(INIT_REG2);            // send data byte
            I2C_StopBit();                  // send stop bit
    
            Wait_Idle ();
    
    
    //*********************************************************
    //-----------------------------PROGRAMME------------------------------
    
            Wait(3);
    
            I2C_StartBit();                     // send start bit
            I2C_ControlByte_Sending();          // send control byte with writing option
            Select_Register (CTRL_REG1);        // Select the right register
            I2C_RestartBit();                   // Restart
            I2C_ControlByte_Reading();          // Send control byte with reading option
            reg1 = Read_I2C_Data();             // Lecture de reg1
            Send_I2C_NAK();                     // Send NAK
            I2C_StopBit();                      // Send stop bit
    
            Wait_Idle ();
    
            I2C_StartBit();                     // send start bit
            I2C_ControlByte_Sending();          // send control byte with writing option
            Select_Register (CTRL_REG2);        // Select the right register
            I2C_RestartBit();                   // Restart
            I2C_ControlByte_Reading();          // Send control byte with reading option
            reg2 = Read_I2C_Data();             // Lecture de reg1
            Send_I2C_NAK();                     // Send NAK
            I2C_StopBit();                      // Send stop bit
    
        }
    
    
    
    
    
    void Wait (uint16_t i)
    {
        uint8_t j=0;
        while (i!=0) {
           for (j=0; j<255; j++){
           }
           i--;
        }
    }
    
    
    void I2C_StartBit(void)
    {
        PIR1bits.SSP1IF=0;                      // Set low the I2C Flag
        SSP1CON2bits.SEN=0b1;                   // send start bit
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    void I2C_RestartBit (void)
    {
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
        SSP1CON2bits.RSEN=0b1;                   // send start bit
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    
    }
    
    
    void I2C_StopBit(void)
    {
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
        SSP1CON2bits.PEN=0b1;                   // send stop bit
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    
    void I2C_ControlByte_Sending(void)
    {
        do{
        SSPCON1bits.WCOL =0;                    // Clear bus collision flag
        SSP1BUF = 0b00011100;                   // send the control byte WITH SLAVE ADRESS & R_nW
        } while (SSPCON1bits.WCOL);            // WAIT THE WRITING OPERATION BEEN DONE WITHOUT COLLISION
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    void I2C_ControlByte_Reading(void)
    {
        do{
        SSPCON1bits.WCOL =0;                    // Clear bus collision flag
        SSP1BUF = 0b00011101;                   // send the control byte WITH SLAVE ADRESS & R_nW
        } while (SSPCON1bits.WCOL);            // WAIT THE WRITING OPERATION BEEN DONE WITHOUT COLLISION
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    void Select_Register (uint8_t RegisterAdress)
    {
        do{
        SSPCON1bits.WCOL =0;                    // Clear bus collision flag
        SSP1BUF = RegisterAdress;                   // send the control byte WITH register adress
        } while (SSPCON1bits.WCOL);            // WAIT THE WRITING OPERATION BEEN ONE WITHOUT COLLISION
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    void Send_I2C_Data(uint8_t DataByte)
    {
        do{
        SSPCON1bits.WCOL =0;                    // Clear bus collision flag
        SSP1BUF = DataByte;                   // send the control byte WITH register adress
        } while (SSPCON1bits.WCOL);            // WAIT THE WRITING OPERATION BEEN ONE WITHOUT COLLISION
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    
    
    
    uint8_t Read_I2C_Data(void)
    {
        PIR1bits.SSP1IF=0b0;            // clear SSP interrupt bit
        SSP1CON2bits.RCEN=0b1;          // set the receive enable bit to initiate a read of 8 bits from the serial eeprom
        while (!PIR1bits.SSP1IF);
        while (!SSP1STATbits.BF);
            return (SSP1BUF);               // Data from eeprom is now in the SSPBUF so return that value
    }
    
    
    
    void Send_I2C_ACK(void)
    {
       PIR1bits.SSP1IF=0b0;          // clear SSP interrupt bit
       SSP1CON2bits.ACKDT=0b0;        // clear the Acknowledge Data Bit - this means we are sending an Acknowledge or 'ACK'
       SSP1CON2bits.ACKEN=0b1;        // set the ACK enable bit to initiate transmission of the ACK bit to the serial eeprom
       while(SSP1CON2bits.ACKEN);    // Wait for interrupt flag to go high indicating transmission is complete
    }
    
    
    
    void Send_I2C_NAK(void)
    {
        PIR1bits.SSP1IF=0b0;           // clear SSP interrupt bit
        SSP1CON2bits.ACKDT=0b1;        // set the Acknowledge Data Bit- this means we are sending a No-Ack or 'NAK'
        SSP1CON2bits.ACKEN=0b1;        // set the ACK enable bit to initiate transmission of the ACK bit to the serial eeprom
        while(SSP1CON2bits.ACKEN);     // Wait for interrupt flag to go high indicating transmission is complete
    }
    
    void Wait_Idle (void)
    {
        while ((SSPCON2 & 0x1F) | (SSPSTATbits.R_nW));      // Wait for idle
    }
    Dernière modification par Pilpilou ; 08/07/2014 à 14h11.

  16. #12
    invite03481543

    Re : Comm. I2C : PIC16F - MAG3110

    Ca avance au moins

    Peux-tu faire des photos de tes signaux du scope? Si possible pour 1 pour SDA et 1 pour SCL en indiquant les échelles de temps et d'amplitudes (un seul créneau complet à l'écran serait idéal si ton scope est numérique ça devrait se faire).
    Le code est celui qui tourne actuellement?

  17. Publicité
  18. #13
    Pilpilou

    Re : Comm. I2C : PIC16F - MAG3110

    Ouai ça avance c'est cool ^^

    Et là je viens de réussir à enfin récupérer un signal Ce que je ne comprends pas c'est que parfois j'arrive à faire l'acquisition, et parfois ça ne marche pas :S Aussi mes variables reg1 et reg2 sont toujours en Out Of Scope... Une idée ?

    Pour les photos J'en ai pris 3, sur chaque photos il y à les deux signaux, mais ils sont facilement différentiables. Le jaune correspond à la clock et le bleu à SDA.
    On peut voir les échelles sur les photos. Je suis en 2V sur chaque channel et sur chaques photos. Parcontre De la photo 1 à la photo 2 j'ai dilaté le temps, et pareil pour passer de la photo 2 à la photo 3.

    Juste histoire d'être sur que vous ayez le bon. Je renvoie le code avec lequel j'arrive parfois à lire une data.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <stdint.h>
    #include <xc.h>
    #include "fonctions_yyy.h"
    #include "pic16f1825.h"
    
    #define _XTAL_FREQ 8000000
    
    
    #ifndef CONFIG_BITS_H
    #define	CONFIG_BITS_H
    
    // CONFIG1
    #pragma config FOSC = INTOSC    // Oscillator Selection (INTOSC oscillator: I/O function on CLKIN pin)
    #pragma config WDTE = OFF       // Watchdog Timer Enable (WDT enabled)
    #pragma config PWRTE = OFF      // Power-up Timer Enable (PWRT disabled)
    #pragma config MCLRE = ON       // MCLR Pin Function Select (MCLR/VPP pin function is MCLR)
    #pragma config CP = OFF         // Flash Program Memory Code Protection (Program memory code protection is disabled)
    #pragma config CPD = OFF        // Data Memory Code Protection (Data memory code protection is disabled)
    #pragma config BOREN = OFF      // Brown-out Reset Enable (Brown-out Reset enabled)
    #pragma config CLKOUTEN = OFF   // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
    #pragma config IESO = OFF       // Internal/External Switchover (Internal/External Switchover mode is disabled)
    #pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is enabled)
    
    // CONFIG2
    #pragma config WRT = OFF        // Flash Memory Self-Write Protection (Write protection off)
    #pragma config PLLEN = OFF      // PLL Enable (4x PLL disabled)
    #pragma config STVREN = OFF     // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will not cause a Reset)
    #pragma config BORV = LO        // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
    #pragma config LVP = OFF        // Low-Voltage Programming Enable (High-voltage on MCLR/VPP must be used for programming)
    
    #endif	/* CONFIG_BITS_H */
    
    #define CTRL_REG1  0x10
    #define CTRL_REG2  0x11
    
    
    #define INIT_REG1  0b01100001
    #define INIT_REG2  0b10000000
    
     
    int main(int argc, char** argv)
    {
    
    //-----------------------------Variable locale----------------------------------
    
        uint8_t reg1=0x00;
        uint8_t reg2=0x00;
    
    //*****************************************************
    //-------------------------Initialisation-PIC--------------------------
    
    
        OPTION_REG = 0x00;
        
        PCON = 0b00000000;             //Flags à 0
    
    
    
    //--------------------------INTERRUPTIONS-----------------------------
        INTCONbits.TMR0IF =0b0;     //TMR0 register did not overflow
        INTCONbits.TMR0IE =0b0;     //Disables the Timer0 interrupt
        INTCONbits.INTE =0b1;       //Enables the INT external interrupt
        INTCONbits.INTF =0b0;       //The INT external interrupt did not occur
        INTCONbits.IOCIE =0b0;      //Enables the interrupt-on-change
        INTCONbits.IOCIF =0b0;      //None of the interrupt-on-change pins have changed state
        INTCONbits.PEIE =0b0;       //Enables all active peripheral interrupts
    
        PIE1bits.SSP1IE =0b1;       //Enables the MSSP interrupt
        PIE2bits.BCL1IE =0b1;       //Enables the MSSP Bus Collision Interrupt
    
    
        PIR1 = 0b00000000;          // Initiate low every interrupts flag
        PIR2 = 0b00000000;          // Initiate low every interrupts flag
        PIR3 = 0b00000000;          // Initiate low every interrupts flag
    
        INTCONbits.GIE = 0b1;       //Enables all active interrupts
    
        //------------------------OSCILLATEUR-------------------------------
    
        OSCCON = 0x72;              // PLL disabled INT. OSC.Frequence d'oscylateur à 8Mhz
    
    
         //-------------------------I/O----------------------------------
        ANSELA=0b00000000;          // TOUTE LES IO en DIGITAL
        ANSELC=0b00000000;          // TOUTE LES IO en DIGITAL
        WPUA=0b00000000;            // PAS de PULL-UP sur le PORT A
        WPUC=0b00000000;            // PAS de PULL-UP sur le PORT C excepté pour SCA et SCL qui sont sur RC0 et RC1
    
        LATA = 0b00000000;          // Initialisation des registres port A à 0
        LATC = 0b00000011;          // Initialisation des registres port C à 0 excepté pour SCA et SCL qui sont sur RC0 et RC1
        PORTA =0b00000000;          // Initialisation des registres port A à 0
        PORTC =0b00000011;          // Initialisation des registres port C à 0 excepté pour SCA et SCL qui sont sur RC0 et RC1
    
        TRISA = 0x3F;
        TRISC = 0x3F;
    
    
        //------------------------BAUD RATE-------------------------------
    
        BAUDCONbits.SCKP=0b1;     // Niveau 0 sur CLK au repos (Transmit non-inverted data to the TX/CK pin)
        BAUDCONbits.BRG16=0b0;    // 8 bits baud rate generator
        BAUDCONbits.WUE=0b0;      // Normal mode
    
    
    
        //------------------------------I2C-----------------------------------
    
        SSP1STATbits.SMP =0b0  ;    //Slew rate control disabled for standard speed mode (100 kHz and 1 MHz)
        SSP1STATbits.CKE= 0b1;      //Enable input logic so that thresholds are compliant with SMbus specification
    
    
        SSP1CON1bits.SSPEN=0b1;     // Enables the serial port and configures the SDAx and SCLx pins as the source of the serial port pins(
        SSP1CON1bits.SSPM = 0b1000; //I2C Master mode, clock = FOSC / (4 * (SSPxADD+1))
    
        SSP1CON2 =0x80;
    
        SSP1CON3bits.SDAHT =0b1;    //Minimum of 300 ns hold time on SDAx after the falling edge of SCLx (100ns if = 0)
        SSP1CON3bits.PCIE =0b1;     // Enable interrupt on detection of Start or Restart conditions
        SSP1CON3bits.SCIE =0b1;     // Enable interrupt on detection of Stop conditions
        SSP1CON3bits.SBCDE =0b1;    // Eable interupt on detection of bu collision
    
    
        SSP1BUF = 0b00000000;       // I2C buffer initialized
        SSP1ADD = 0b00010011;                // set Baud rate clock divider
    
    
    
    
    //*************************************************************
    //-----------------------------Initialisation-MAG------------------------------
        while(1)
        {
            I2C_StartBit();                 // send start bit
            I2C_ControlByte_Sending();      // send control byte with writing option
            Select_Register (CTRL_REG1);    // Select the right register
            Send_I2C_Data(INIT_REG1);            // send data byte
            I2C_StopBit();                      // send stop bit
    
            Wait_Idle ();
    
            I2C_StartBit();                     // send start bit
            I2C_ControlByte_Sending();          // send control byte with writing option
            Select_Register (CTRL_REG2);        // Select the right register
            Send_I2C_Data(INIT_REG2);            // send data byte
            I2C_StopBit();                  // send stop bit
    
            Wait_Idle ();
    
    //*********************************************************
    //-----------------------------PROGRAMME------------------------------
    
            Wait(3);
    
            I2C_StartBit();                     // send start bit
            I2C_ControlByte_Sending();          // send control byte with writing option
            Select_Register (CTRL_REG1);        // Select the right register
            I2C_RestartBit();                   // Restart
            I2C_ControlByte_Reading();          // Send control byte with reading option
            reg1 = Read_I2C_Data();             // Lecture de reg1
            Send_I2C_NAK();                     // Send NAK
            I2C_StopBit();                      // Send stop bit
    
            Wait_Idle ();
    
            I2C_StartBit();                     // send start bit
            I2C_ControlByte_Sending();          // send control byte with writing option
            Select_Register (CTRL_REG2);        // Select the right register
            I2C_RestartBit();                   // Restart
            I2C_ControlByte_Reading();          // Send control byte with reading option
            reg2 = Read_I2C_Data();             // Lecture de reg1
            Send_I2C_NAK();                     // Send NAK
            I2C_StopBit();                      // Send stop bit
    
        }
    }
    
    #include <stdio.h>
    #include <stdlib.h>
    #include <stdbool.h>
    #include <stdint.h>
    #include <xc.h>
    #include "pic16lf1825.h"
    
    
    void Wait (uint16_t i)
    {
        uint8_t j=0;
        while (i!=0) {
           for (j=0; j<255; j++){
           }
           i--;
        }
    }
    
    
    void I2C_StartBit(void)
    {
        PIR1bits.SSP1IF=0;                      // Set low the I2C Flag
        SSP1CON2bits.SEN=0b1;                   // send start bit
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    
    }
    
    void I2C_RestartBit (void)
    {
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
        SSP1CON2bits.RSEN=0b1;                   // send start bit
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    
    }
    
    
    void I2C_StopBit(void)
    {
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
        SSP1CON2bits.PEN=0b1;                   // send stop bit
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    
    void I2C_ControlByte_Sending(void)
    {
        do{
        SSP1CON1bits.WCOL =0;                    // Clear bus collision flag
        SSP1BUF = 0b00011100;                   // send the control byte WITH SLAVE ADRESS & R_nW
        } while (SSP1CON1bits.WCOL);            // WAIT THE WRITING OPERATION BEEN DONE WITHOUT COLLISION
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    void I2C_ControlByte_Reading(void)
    {
        do{
        SSP1CON1bits.WCOL =0;                    // Clear bus collision flag
        SSP1BUF = 0b00011101;                   // send the control byte WITH SLAVE ADRESS & R_nW
        } while (SSP1CON1bits.WCOL);            // WAIT THE WRITING OPERATION BEEN DONE WITHOUT COLLISION
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    void Select_Register (uint8_t RegisterAdress)
    {
        do{
        SSP1CON1bits.WCOL =0;                    // Clear bus collision flag
        SSP1BUF = RegisterAdress;                   // send the control byte WITH register adress
        } while (SSP1CON1bits.WCOL);            // WAIT THE WRITING OPERATION BEEN ONE WITHOUT COLLISION
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    void Send_I2C_Data(uint8_t DataByte)
    {
        do{
        SSP1CON1bits.WCOL =0;                    // Clear bus collision flag
        SSP1BUF = DataByte;                   // send the control byte WITH register adress
        } while (SSP1CON1bits.WCOL);            // WAIT THE WRITING OPERATION BEEN ONE WITHOUT COLLISION
        while(!PIR1bits.SSP1IF);                // Wait for the SSPIF bit to go back high before we load the data buffer
        PIR1bits.SSP1IF =0;                     // Clear the I2C Flag
    }
    
    
    uint8_t Read_I2C_Data(void)
    {
        PIR1bits.SSP1IF=0b0;            // clear SSP interrupt bit
        SSP1CON2bits.RCEN=0b1;          // set the receive enable bit to initiate a read of 8 bits from the serial eeprom
        while (!PIR1bits.SSP1IF);
        while (!SSP1STATbits.BF);
        PIR1bits.SSP1IF = 0b0;
        SSP1STATbits.BF = 0b0;
        return (SSP1BUF);               // Data from eeprom is now in the SSPBUF so return that value
    }
    
    
    void Send_I2C_ACK(void)
    {
       PIR1bits.SSP1IF=0b0;          // clear SSP interrupt bit
       SSP1CON2bits.ACKDT=0b0;        // clear the Acknowledge Data Bit - this means we are sending an Acknowledge or 'ACK'
       SSP1CON2bits.ACKEN=0b1;        // set the ACK enable bit to initiate transmission of the ACK bit to the serial eeprom
       while(SSP1CON2bits.ACKEN);    // Wait for interrupt flag to go high indicating transmission is complete
    }
    
    void Send_I2C_NAK(void)
    {
        PIR1bits.SSP1IF=0b0;           // clear SSP interrupt bit
        SSP1CON2bits.ACKDT=0b1;        // set the Acknowledge Data Bit- this means we are sending a No-Ack or 'NAK'
        SSP1CON2bits.ACKEN=0b1;        // set the ACK enable bit to initiate transmission of the ACK bit to the serial eeprom
        while(SSP1CON2bits.ACKEN);     // Wait for interrupt flag to go high indicating transmission is complete
    }
    
    void Wait_Idle (void)
    {
        while ((SSP1CON2 & 0x1F) | (SSPSTATbits.R_nW));      // Wait for idle
    }
    Images attachées Images attachées

  19. #14
    Pilpilou

    Re : Comm. I2C : PIC16F - MAG3110

    EDIT : * Out Of Scope réglé en déclarant mes variables reg1 et reg2 en global.
    * Enfait j'arrive à lire le registre 1 normal et pour le REG2 si je n'avais que des 0 c'ést normal ça vient de la définition intrinsèque du registre (CF datasheet mag3110)

    Merci beaucoup pour votre aide, j'y serai pas arrivé seul !!!
    Dernière modification par Pilpilou ; 08/07/2014 à 16h35.

  20. #15
    RISC

    Re : Comm. I2C : PIC16F - MAG3110

    Salut,

    Le message "out of scope" est tout à fait normal.
    Les variables locales n'existent pas à l'extérieur de la fonction ou elles sont déclarées...Si tu fais un point d'arrêt dans la fonction tu verras que ses variables locales auront une valeur ;=)

    Si ton programme "revient en arrière" c'est tout "simplement" qu'il y a une faute importante et que cela a provoqué un reset...
    C'est un fonctionnement tout à fait normal de MPLAB X...

    Si ton protocole I2C ne fonctionne pas, il faut suivre chaque trame et voir là ou la trame n'est pas correcte.
    Comme je l'ai dit précédemment, tu peux aussi te faire aider de Code Configurator qui génère le code pour toi (je pense qu'il génère le code pour un PIC en mode Master et un esclave I2C.

    a+
    Ma marotte ? les microcontrôleurs ;=)

Discussions similaires

  1. Licence AES / DUT info-comm
    Par Feary dans le forum Orientation après le BAC
    Réponses: 3
    Dernier message: 21/10/2008, 15h31
  2. 1ère Stg Comm.
    Par marymari dans le forum Orientation avant le BAC
    Réponses: 7
    Dernier message: 16/08/2007, 09h27
  3. pers. comm. ??
    Par _Mayou_ dans le forum Biologie
    Réponses: 3
    Dernier message: 06/04/2007, 18h51
  4. Free facture comm
    Par weeman dans le forum Internet - Réseau - Sécurité générale
    Réponses: 0
    Dernier message: 04/02/2005, 12h17
Découvrez nos comparatifs produits sur l'informatique et les technologies.