I2C sur PIC18F4553
Répondre à la discussion
Affichage des résultats 1 à 4 sur 4

I2C sur PIC18F4553



  1. #1
    invited3dcf66c

    I2C sur PIC18F4553


    ------

    Bonjour,
    Je suis actuellement sur un projet ou j'ai besoin d'utiliser l'I2C entre deux PIC, le maitre est un 18F4553 et l'esclave un 18F4431 (enfin qu'importe finalement).
    Dans un but entièrement didactique j'ai décidé de le faire entièrement sans bibliothèques de fonctions toutes faites.
    J'utilise le compileur C18 dans l'IDE MPLAB.
    Après de multiples vérifications, mon code me semble correct, mais lorsque je simule sous ISIS (je sais c'est mal, mais j'ai pas d'oscilloscope à mémoire), l'analyseur I2C me donne des résultats moches et ISIS m'insulte (enfin juste des warning mais...).
    Je vous laisse admirer:
    Code:
    #include <p18F4553.h>
    
    #define ADRESSE_ESCLAVE 0b00000111
    
    #define ECRITURE 0
    #define LECTURE 1
    
    #pragma config PLLDIV = 5
    #pragma config FOSC = HS
    #pragma config DEBUG = ON
    
    /**********************************************/
    /*                 Prototypes                 */
    /**********************************************/
    void analog_init(void);
    void I2C_init(void);
    void I2C_attendre_IDLE(void);
    void I2C_generer_start(void);
    void I2C_envoyer_adresse(char adresse, char mode);
    void I2C_attendre_ACK(void);
    void I2C_ecrire_octet(char octet);
    void I2C_generer_repeated_start(void);
    char I2C_lire_octet(void);
    void I2C_generer_noack(void);
    void I2C_generer_stop(void);
    void commande_potentiometres(char* duty_rouge, char* duty_vert, char* duty_bleu, char* duty_blanc);
    void envoi_valeurs(char* duty_rouge, char* duty_vert, char* duty_bleu, char* duty_blanc);
    
    /**********************************************/
    /*                    Main                    */
    /**********************************************/
    void main(void)
    {
    	char duty_rouge, duty_vert, duty_bleu, duty_blanc;
    
    	I2C_init();
    	
    	while(1)
    	{
    		commande_potentiometres(&duty_rouge, &duty_vert, &duty_bleu, &duty_blanc);
    
    		envoi_valeurs(&duty_rouge, &duty_vert, &duty_bleu, &duty_blanc);
    	}
    }
    
    void analog_init()
    {
    	ADCON1 = 0b00001011; // Références VDD VSS, AD3 - AD0 analogiques, autres digital
    	TRISA |= 0b00001111; // Pins analogiques en entrée
    
    	ADCON2 = 0b00010101; // Tacq = 4 Tad / Conversion clock = Tosc/16
    
    	ADCON0bits.ADON = 1; // Démarrage de l'ADC
    }
    
    void commande_potentiometres(char* duty_rouge, char* duty_vert, char* duty_bleu, char* duty_blanc)
    {
    	analog_init(); // Initialisation
    
    	ADCON0 = 0b00000011; // Sélection AN0 + Lancement mesure
    	while(ADCON0bits.GO==1); // Attente de la fin de la mesure
    	*duty_rouge = ADRESH;
    
    	ADCON0 = 0b00000111; // Sélection AN1 + Lancement mesure
    	while(ADCON0bits.GO==1); // Attente de la fin de la mesure
    	*duty_vert = ADRESH;
    
    	ADCON0 = 0b00001011; // Sélection AN0 + Lancement mesure
    	while(ADCON0bits.GO==1); // Attente de la fin de la mesure
    	*duty_bleu = ADRESH;
    
    	ADCON0 = 0b00001111; // Sélection AN0 + Lancement mesure
    	while(ADCON0bits.GO==1); // Attente de la fin de la mesure
    	*duty_blanc = ADRESH;
    	
    	ADCON0bits.ADON = 0; // Arrêt de l'ADC
    }
    
    void envoi_valeurs(char* duty_rouge, char* duty_vert, char* duty_bleu, char* duty_blanc)
    {
    	I2C_generer_start();	
    	I2C_envoyer_adresse(ADRESSE_ESCLAVE, ECRITURE);
    	I2C_attendre_ACK();
    	I2C_ecrire_octet(*duty_rouge);
    	I2C_attendre_ACK();
    	I2C_ecrire_octet(*duty_vert);
    	I2C_attendre_ACK();
    	I2C_ecrire_octet(*duty_bleu);
    	I2C_attendre_ACK();
    	I2C_ecrire_octet(*duty_blanc);
    	I2C_attendre_ACK();
    	I2C_generer_stop();
    }
    
    void I2C_init(void)
    {
    	TRISBbits.TRISB0 = 1; // RB0 et RB1 (SCA et SCL) en entrée
    	TRISBbits.TRISB1 = 1;
    
    	SSPSTATbits.SMP = 0; // Slew-Rate control (pour 400kHz)
    	SSPSTATbits.CKE = 0; // Mode I2C pas SMBus
    
    	SSPADD = 12; // Configuration du Baudrate Generator
    
    	SSPCON1bits.SSPEN = 1; // Activation du module I2C
    	SSPCON1bits.SSPM3 = 1; // Mode Master sans interruption
    	SSPCON1bits.SSPM2 = 0; //
    	SSPCON1bits.SSPM1 = 0; //
    	SSPCON1bits.SSPM0 = 0; //
    }
    
    void I2C_attendre_IDLE(void)
    {
    	while(SSPSTATbits.R_W || SSPCON2bits.SEN || SSPCON2bits.RSEN || SSPCON2bits.PEN || SSPCON2bits.RCEN || SSPCON2bits.ACKEN);
    }
    
    void I2C_generer_start(void)
    {
    	I2C_attendre_IDLE(); // Attendre que le bus soit disponible
    	
    	SSPCON2bits.SEN = 1; // Générer le start
    }
    
    void I2C_envoyer_adresse(char adresse, char mode)
    {
    	I2C_attendre_IDLE(); // Attendre que le bus soit disponible
    
    	if(mode == 0)
    	{
    		SSPBUF = (adresse*2);
    	}
    	else
    	{
    		SSPBUF = (adresse*2 + 1);
    	}
    }
    
    void I2C_attendre_ACK(void)
    {
    	//I2C_attendre_IDLE(); // Attendre que le bus soit disponible
    
    	while(SSPCON2bits.ACKSTAT); // Tant qu'on n'a pas recu l'acknoledge on attend
    }
    
    void I2C_ecrire_octet(char octet)
    {
    	I2C_attendre_IDLE(); // Attendre que le bus soit disponible
    
    	SSPBUF = octet; // On lance le transfert
    
    	while(SSPSTATbits.R_W); // On attend la fin du transfert
    }
    
    void I2C_generer_repeated_start(void)
    {
    	I2C_attendre_IDLE(); // Attendre que le bus soit disponible
    	
    	SSPCON2bits.RSEN = 1; // Envoi du repeated start
    }
    
    char I2C_lire_octet(void)
    {
    	I2C_attendre_IDLE(); // Attendre que le bus soit disponible
    
    	SSPCON2bits.RCEN = 1; // On lance la réception
    
    	while(SSPSTATbits.R_W); // On attend la fin du transfert
    
    	return SSPBUF;
    }
    
    void I2C_generer_noack(void)
    {
    	I2C_attendre_IDLE(); // Attendre que le bus soit disponible
    
    	SSPCON2bits.ACKDT = 1; // Not Acknoledge = 1
    	SSPCON2bits.ACKEN = 1; // Lancer le Not Acknoledge
    }
    
    void I2C_generer_stop(void)
    {
    	I2C_attendre_IDLE(); // Attendre que le bus soit disponible
    
    	SSPCON2bits.PEN = 1; // Génération du stop
    }
    Et en pièces jointes le tas d'insultes ^.^
    Si des plus expérimentés que moi voient ce qui clochent, je les remercie déjà d'avance de leur aide!

    -----
    Images attachées Images attachées  

  2. #2
    invitee05a3fcc

    Re : I2C sur PIC18F4553

    Je n'y connais rien en microcalculateur... donc je n'irais pas vérifier ton code. Par contre, sur le plan hard, il faut que la ligne SCA soit en Collecteur Ouvert (enfin Drain Ouvert !) avec une PullUP

    On peut aussi prendre une sortie normal qui est mise à "0" en permanence et on la pilote avec son troisième état ("Z" pour sortir un "1" , "On" pour sortir un "0")

  3. #3
    invited3dcf66c

    Re : I2C sur PIC18F4553

    Oui j'ai bien mis mes lignes avec une PullUp, et les sorties du PIC que j'ai utilisées sont à collecteur ouvert déjà dans le PIC, j'utilise les sorties du PIC qui sont faites pour le I2C.

  4. #4
    RISC

    Re : I2C sur PIC18F4553

    Salut,

    Jette un oeil sur les exemples de code. Tu trouveras peut-être un exemple d'I2C pour les PIC18.

    Tu peux également voir sur ce site qui propose des cours en français sur les PIC18 avec le C18.

    a+

  5. A voir en vidéo sur Futura

Discussions similaires

  1. Aide sur l' i2c
    Par invitec540ebb9 dans le forum Électronique
    Réponses: 13
    Dernier message: 12/05/2010, 15h05
  2. Aide sur I2C et PIC16F877
    Par invite2472f6cc dans le forum Électronique
    Réponses: 1
    Dernier message: 24/06/2009, 10h28
  3. Gestion I2C sur PC avec Qbasic
    Par Debutant72 dans le forum Électronique
    Réponses: 0
    Dernier message: 11/04/2009, 16h19
  4. Plusieurs LM75 sur un bus I2C
    Par invitec330b05b dans le forum Électronique
    Réponses: 2
    Dernier message: 13/09/2008, 07h48
  5. Besoin d'aide sur I2C
    Par invite74b73858 dans le forum Électronique
    Réponses: 8
    Dernier message: 26/07/2006, 11h20
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...