Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Lib I2C PIC16F
robotic
Membre
Membre
Messages : 3
Enregistré en : octobre 2017

#1 Message par robotic » ven. 20 oct. 2017 12:02 lien vers la Data-Sheet : Cliquez ici

Bonjour,

Je souhaiterais réaliser un projet de communication I2C avec des PIC16F1703 mais en cherchant sur internet j'ai trouvé pas mal d'informations différentes avec des librairies différentes ( I2C.h , PLIB.h) je suis novice dans la programmation de pic et ouvert à travailler avec different compilateur sous MPLAB.
Pourriez vous guidiez mes premières recherche sur l'I2C.
Qu'elle compilateur utiliser ?
Qu'elle sont les registres à configurer pour un Slave ?
Sur qu'elle registre est stocké la valeur de la trame ?

Merci à vous et bonne journée.

Lib I2C PIC16F
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 1135
Âge : 68
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#2 Message par paulfjujo » ven. 20 oct. 2017 19:57 lien vers la Data-Sheet : Cliquez ici

bonsoir Robotic,

jette un oeil sur ce post ..
viewtopic.php?f=10&t=243

peut etre cela t'aidera ..
Aides toi, le ciel ou Fantastpic t'aideras

Lib I2C PIC16F
robotic
Membre
Membre
Messages : 3
Enregistré en : octobre 2017

#3 Message par robotic » lun. 30 oct. 2017 15:26 lien vers la Data-Sheet : Cliquez ici

Bonjour,

J'ai regardé le lien, je suis tombé sur le configurateur MCC qui fonctionne à merveille et qui génère le code suivant pour mon pic. Je souhaite faire dialoguer un arduino en master et le pic en Slave.

code arduino:

Code : Tout sélectionner



#include <Wire.h>

void setup() {
  Wire.begin(); // join i2c bus (address optional for master)
}

byte x = 1;

void loop() {
  Wire.beginTransmission(8); // transmit to device #8
  Wire.write(x);              // sends one byte
  Wire.endTransmission();    // stop transmitting

  delay(500);


code pic I2C:

Code : Tout sélectionner

#include "i2c.h"

#define I2C_SLAVE_ADDRESS 0x08 
#define I2C_SLAVE_MASK    0x7F

typedef enum
{
    SLAVE_NORMAL_DATA,
    SLAVE_DATA_ADDRESS,
}
 SLAVE_WRITE_DATA_TYPE;

/**
 Section: Global Variables
*/

volatile uint8_t    I2C_slaveWriteData      = 0x55;

/**
 Section: Local Functions
*/
void I2C_StatusCallback(I2C_SLAVE_DRIVER_STATUS i2c_bus_state);



/**
  Prototype:        void I2C_Initialize(void)
  Input:            none
  Output:           none
  Description:      I2C_Initialize is an
                    initialization routine that takes inputs from the GUI.
  Comment:          
  Usage:            I2C_Initialize();

*/
void I2C_Initialize(void)
{
    // initialize the hardware
    // R_nW write_noTX; P stopbit_notdetected; S startbit_notdetected; BF RCinprocess_TXcomplete; SMP Standard Speed; UA dontupdate; CKE disabled; D_nA lastbyte_address; 
    SSP1STAT = 0x80;
    // SSPEN enabled; WCOL no_collision; CKP disabled; SSPM 7 Bit Polling; SSPOV no_overflow; 
    SSP1CON1 = 0x26;
    // ACKEN disabled; GCEN disabled; PEN disabled; ACKDT acknowledge; RSEN disabled; RCEN disabled; ACKSTAT received; SEN disabled; 
    SSP1CON2 = 0x00;
    // ACKTIM ackseq; SBCDE disabled; BOEN disabled; SCIE disabled; PCIE disabled; DHEN disabled; SDAHT 100ns; AHEN disabled; 
    SSP1CON3 = 0x00;
    // SSP1MSK 127; 
    SSP1MSK = (I2C_SLAVE_MASK << 1);  // adjust UI mask for R/nW bit            
    // SSP1ADD 8; 
    SSP1ADD = (I2C_SLAVE_ADDRESS << 1);  // adjust UI address for R/nW bit

    // clear the slave interrupt flag
    PIR1bits.SSP1IF = 0;
    // enable the master interrupt
    PIE1bits.SSP1IE = 1;

}

void I2C_ISR ( void )
{
    uint8_t     i2c_data                = 0x55;


    // NOTE: The slave driver will always acknowledge
    //       any address match.

    PIR1bits.SSP1IF = 0;        // clear the slave interrupt flag
    i2c_data        = SSP1BUF;  // read SSPBUF to clear BF
    if(== SSP1STATbits.R_nW)
    {
        if((== SSP1STATbits.D_nA) && (== SSP1CON2bits.ACKSTAT))
        {
            // callback routine can perform any post-read processing
            I2C_StatusCallback(I2C_SLAVE_READ_COMPLETED);
        }
        else
        
{
            // callback routine should write data into SSPBUF
            I2C_StatusCallback(I2C_SLAVE_READ_REQUEST);
        }
    }
    else if(== SSP1STATbits.D_nA)
    {
        // this is an I2C address

        // callback routine should prepare to receive data from the master
        I2C_StatusCallback(I2C_SLAVE_WRITE_REQUEST);
    }
    else
    
{
        I2C_slaveWriteData   = i2c_data;

        // callback routine should process I2C_slaveWriteData from the master
        I2C_StatusCallback(I2C_SLAVE_WRITE_COMPLETED);
    }

    SSP1CON1bits.CKP    = 1;    // release SCL

} // end I2C_ISR()



/**

    Example implementation of the callback

    This slave driver emulates an EEPROM Device.
    Sequential reads from the EEPROM will return data at the next
    EEPROM address.

    Random access reads can be performed by writing a single byte
    EEPROM address, followed by 1 or more reads.

    Random access writes can be performed by writing a single byte
    EEPROM address, followed by 1 or more writes.

    Every read or write will increment the internal EEPROM address.

    When the end of the EEPROM is reached, the EEPROM address will
    continue from the start of the EEPROM.
*/

void I2C_StatusCallback(I2C_SLAVE_DRIVER_STATUS i2c_bus_state)
{

    static uint8_t EEPROM_Buffer[] =
    {
        0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f,
        0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,
        0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,
        0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f,
        0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47,0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f,
        0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57,0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f,
        0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f,
        0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f,
    };

    static uint8_t eepromAddress    = 0;
    static uint8_t slaveWriteType   = SLAVE_NORMAL_DATA;


    switch (i2c_bus_state)
    {
        case I2C_SLAVE_WRITE_REQUEST:
            // the master will be sending the eeprom address next
            slaveWriteType  = SLAVE_DATA_ADDRESS;
            break;


        case I2C_SLAVE_WRITE_COMPLETED:

            switch(slaveWriteType)
            {
                case SLAVE_DATA_ADDRESS:
                    eepromAddress   = I2C_slaveWriteData;
                    break;


                case SLAVE_NORMAL_DATA:
                default:
                    // the master has written data to store in the eeprom
                    EEPROM_Buffer[eepromAddress++]    = I2C_slaveWriteData;
                    if(sizeof(EEPROM_Buffer) <= eepromAddress)
                    {
                        eepromAddress = 0;    // wrap to start of eeprom page
                    }
                    break;

            } // end switch(slaveWriteType)

            slaveWriteType  = SLAVE_NORMAL_DATA;
            break;

        case I2C_SLAVE_READ_REQUEST:
            SSP1BUF = EEPROM_Buffer[eepromAddress++];
            if(sizeof(EEPROM_Buffer) <= eepromAddress)
            {
                eepromAddress = 0;    // wrap to start of eeprom page
            }
            break;

        case I2C_SLAVE_READ_COMPLETED:
        default:;

    } // end switch(i2c_bus_state)

}



code main:

Code : Tout sélectionner

#include "mcc_generated_files/mcc.h"

/*
                         Main application
 */
void main(void)
{
int i;
    // initialize the device
    SYSTEM_Initialize();

    // When using interrupts, you need to set the Global and Peripheral Interrupt Enable bits
    // Use the following macros to:

    // Enable the Global Interrupts
    //INTERRUPT_GlobalInterruptEnable();

    // Enable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptEnable();

    // Disable the Global Interrupts
    //INTERRUPT_GlobalInterruptDisable();

    // Disable the Peripheral Interrupts
    //INTERRUPT_PeripheralInterruptDisable();

    while (1)
    {

        if(//test de la data recu = data envoyé par arduino){
            PORTCbits.RC3=0;
            for(i=0; i<2000; i++){
                PORTCbits.RC4=1;
                __delay_us(100);
                PORTCbits.RC4=0;
                __delay_us(100);    
            
}
        
            PORTCbits
.RC3=1;
            for(i=0; i<2000; i++){
                PORTCbits.RC4=1;
                __delay_us(1000);
                PORTCbits.RC4=0;
                __delay_us(1000);    
            
}
        
        
}
        
    
}
}
/**
 End of File
*/ 


Comment s'assurer que le pic reçoit bien la trame et comment le lire la valeur du buffer ?
ps: les ports RC3 et RC4 pilote un moteur.

Lib I2C PIC16F
francknvs
Débutant
Débutant
Messages : 26
Enregistré en : septembre 2017
Localisation : Paca-toulon

#4 Message par francknvs » lun. 30 oct. 2017 17:18 lien vers la Data-Sheet : Cliquez ici

salut robotic,

Tout d'abord, il te faut savoir ce que tu veux réaliser en I2c:
qui sera le maitre
qui sera l'esclave
te doter de chaque datasheet, car celui de l'esclave te permettra d'avoir l'adresse du module concerné ainsi que les adresses des registres avec lesquelles tu veux communiquer.

Concernant les compilateurs, je travaille avec hi-tech, il te faudra peut etre modifier qqs lignes de code non reconnus dans ce compilateur (rien de bien sorcier).
Pour la version de Mplab: j'utilise la 8.92
Pour la programmation du pic et son debug: ICD3
je travaille avec:
- un pic configuré en MAITRE qui gere le protocole I2c à savoir les ligne SCL & SDA
16f876a.pdf

- un afficheur lcd oem et son pilote I2c clcd420c en ESCLAVE
Datasheet du lcd I²c-CLCD.pdf


Je viens tout juste de terminer ce projet ce WE, à présent, sur ce même projet je rajoute un RTC DS3231 comme esclave pour transférer le groupe date/heure du RTC sur l'afficheur.
(A l'issue, je mettrai en ligne un tuto complet en C avec les fichiers Sources et Header)

Effectivement le module MCC de mplabx permet de générer automatiquement du code, mais je ne l'utilise pas car je préfère coder moi-même mes fonctions et mes variables pour mieux comprendre et savoir-faire( c'est un choix perso....).

robotic a écrit :Source du message Comment s'assurer que le pic reçoit bien la trame et comment le lire la valeur du buffer ?
ps: les ports RC3 et RC4 pilote un moteur.


pour cela, tu peux utiliser la fenetre "watch" de mplab en mode simu
mais il te faudra remettre manuellement à 0 le bit d’envoyé du registre concerné (cf au datasheet du maitre concerné)

Cordialement,
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.

Lib I2C PIC16F
robotic
Membre
Membre
Messages : 3
Enregistré en : octobre 2017

#5 Message par robotic » ven. 3 nov. 2017 09:45 lien vers la Data-Sheet : Cliquez ici

Le programme mis ci-dessus fonctionne presque le pic détecte bien qu'il reçoit une adresse I2C mais n'arrive pas a effectuer l'acquittement après réception de l'adresse. Avez vous une piste pour trouver d'où viendrait le soucis ?

PS j'ai activé les intérrupts global et peripheral

Lib I2C PIC16F
francknvs
Débutant
Débutant
Messages : 26
Enregistré en : septembre 2017
Localisation : Paca-toulon

#6 Message par francknvs » ven. 3 nov. 2017 09:51 lien vers la Data-Sheet : Cliquez ici

Bjr
Dans un 1er tps,essaye de les desactiver ainsi que le watchdog


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité