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

PIC : Du retard sur les interruptions I2C



  1. #1
    Julien1138

    PIC : Du retard sur les interruptions I2C


    ------

    Bonjour,

    Je suis en train de mettre en place une liaison I2C entre 2 Pics et j'ai quelques problème avec l'esclave. J'utilise un PIC 18F4431. Ce dernier ne permet pas l'utilisation des fonction de la bibliothèque MCC18.

    Mon problème est que l'esclave ne déclenche pas l'interruption de réception d'une trame I2C aussi rapidement que prévus.
    Je joint une photo de l'oscillo. Sur la voie 1 on visualise la broche RD1 du pic qui change d'état à chaque passage dans la routine d'interruption I2C. Sur la voie 2 on visualise le SCL de l'I2C. Il n'y a que 2 trames car un NACK est émis sur le seconde trame. On voit que le passage dans la routine d'interruption à lieu pratiquement un trame trop tard (soit environ 800 cycles machine après la fin de la première trame). Le buffer est lu trop tard donc l'esclave envoi un NACK sur la ligne lorsqu'il reçoit la deuxième trame. Le second changement d'état est encore plus en retard.


    Voici le code C de gestion de l'interruption :

    - Initialisation des interruptions :
    Code:
    void Interrupt_Init(void)
    {
    	RCONbits.IPEN = 1;		// On autorise les niveaux de priorité
    	INTCONbits.GIEH = 1;		// On autorise toutes les interruptions
    	INTCONbits.GIEL = 1;	// """"""""""""""""""""""""""""""""""""
    
    // I2C
    	PIE1bits.SSPIE = 1;		// autorisation de l'interruption de l'i2c
    	IPR1bits.SSPIP = 0;		// Interruption de l'I2C en basse proirité
    }
    - Initialisation de l'I2C :
    Code:
    void I2C_Init(void)
    {
    	TRIS_SDA = 1;	// SDA en entrée
    	TRIS_SCL = 1;	// SCL en entrée
    	SSPCON = 0x36;	// I2C Slave mode, 7-bit address
    	SSPADD = ADRESSE<<1;	// Adresse de la carte moteur
    
    	SSPCONbits.CKP = 1;	// Libère la ligne d'horloge
    }
    - Routine d'interruption :
    Code:
    void Low_Interrupt(void);
    
    #pragma code low_vector=0x18
    void Interrupt_at_low_vector(void)
    {
    _asm goto Low_Interrupt _endasm
    }
    
    #pragma code
    
    #pragma interrupt Low_Interrupt
    void Low_Interrupt(void)
    {
    	if (PIR1bits.SSPIF)
    	{
    		I2C_Interrupt();
    	}
    }
    void I2C_Interrupt(void)
    {
    	PIR1bits.SSPIF = 0;
    	PORTDbits.RD1 = ~PORTDbits.RD1;     // Change l'état de RD1
    	if (SSPSTATbits.D_A == 1)	// Donnée
    	{
    		if (SSPSTATbits.R_W == 0)	// Maitre en écriture -> Esclave en lecture
    		{
    			I2C_Data = SSPBUF;
    			I2C_Read(); // Méthode d'interprétation de l'octet reçu
    		}
    		else
    		{
    			I2C_Write(); // Méthode de chargement de l'octet à envoyer
    			SSPBUF = I2C_Data;
    			SSPCONbits.CKP = 1;	// Libère la ligne d'horloge
    		}
    		I2C_Octets_Restants--;
    	}
    	else						// Adresse
    	{
    		I2C_Data = SSPBUF;
    	}
    }
    - Main :
    Code:
    void main(void)
    {
    	ANSEL0 = 0x00;			// Entrées analogiques désctivées
    
    	Interrupt_Init();
    
    	I2C_Init();
    
    PORTDbits.RD1 = 0;
    
    	while (1)
    	{
    	}
    }
    Voila, Je suis bloqué parce que je pense avoir tout fait comme il faut et j'ai aucune idée d'où peut venir l'erreur.

    Si quelqu'un voit quelque chose que je ne vois pas, je serai très reconnaissant.

    Merci d'avance pour votre aide.

    A bientôt.

    Julien

    -----
    Images attachées Images attachées
    Le SBAM c'est la bible en quatre mots ; Sourire, Bonjour, Au revoir, Merci.(Les Wriggles)

  2. #2
    RISC

    Re : PIC : Du retard sur les interruptions I2C

    Bonjour,

    Citation Envoyé par Julien1138 Voir le message
    Bonjour,

    Je suis en train de mettre en place une liaison I2C entre 2 Pics et j'ai quelques problème avec l'esclave. J'utilise un PIC 18F4431. Ce dernier ne permet pas l'utilisation des fonction de la bibliothèque MCC18.
    Que veux-tu dire exactement concernant le MCC18 ?
    Qu'il n'existe pas de bibliothèque pour les périphériques de ton micro PIC18F4431 ?

    Dans la version 3.16 du compilateur C18, le document "release notes" précise les micros pour lesquels certains périphériques ne sont pas supportés :
    http://ww1.microchip.com/downloads/e...E.html#Devices

    Le tien n'est pas dedans ;=) et semble supporté totalement.

    Si tu n'utilises pas cette dernière version (3.16), tu peux la charger gratuitement ici : www.microchip.com/C18.

    Tu peux trouver des exemples de code pour les PIC18 ici :
    * www.microchip.com/codeexamples
    * http://www.aix-mrs.iufm.fr/formation...indexPIC_C.htm

    et aussi plein de notes d'application sur l'I2C :
    http://www.microchip.com/stellent/id...rects=appnotes

    a+

  3. #3
    Julien1138

    Re : PIC : Du retard sur les interruptions I2C

    Bonjour,

    J'utilise bien sur le compilateur MCC18, et il fonctionne parfaitement. Ce que je ne peut pas utiliser, ce sont les fonctions I2C (et I2C seulement) de la bibliothèque fournie avec la compilateur. Ces fonctions contiennent les routines pour écrire et recevoir des chaines de caractères, initialiser le bus, vérifier s'il est libre, etc... Je ne peut pas utiliser ces fonctions car le module I2C de mon PIC ne permet pas de se configurer en maitre (à moins de créer les routines en soft).
    Le problème n'est pas là ; il me suffit juste d'utiliser les registres du PIC au lieu de fonctions toutes faites, et cela ne me pose aucun problème.
    Mon problème est lié à l'interruption, que je traiterai exactement de la même façon si j'utilisais la bibliothèque du compilateur.

    Merci quand même pour ta réponse.

    A+
    Le SBAM c'est la bible en quatre mots ; Sourire, Bonjour, Au revoir, Merci.(Les Wriggles)

  4. #4
    Tartopommes

    Re : PIC : Du retard sur les interruptions I2C

    Hello!

    Voici une routine d'INT haute priorité que j'utilise en ce moment, sans problème, sur un 18F2331.

    Code:
    //Interuptions haut niveau => Pour I2C
    #pragma code highVector=0x08	// on déclare que lors d'une interruption
    void atInterrupthigh(void)
    {
    _asm GOTO Interrupt_High _endasm       // on doit éxecuter le code de la fonction MyHighInterrupt
    }
    #pragma code // retour à la zone de code
    
    
    #pragma interrupt Interrupt_High
    void Interrupt_High(void)
    {
            unsigned char sauv1;
            unsigned char sauv2;
    
            sauv1 = PRODL; // on sauvegarde le contenu des registres de calcul
            sauv2 = PRODH;       
    
    		if (PIR1bits.SSPIF) 
    		{
    				//Allume la DEL
    				IRO1 = 0;
    
    				if(SSPCONbits.SSPOV = 1)
    					SSPCONbits.SSPOV = 0;	//Clear overflow
    
    				if(SSPSTATbits.D_A == 0) 	//DA = 0 => last was address DA = 1 => last was data
    				{
    					//On vient de recevoir l'adresse: c'est donc le début d'une transmission
    					i2c_add = SSPBUF;	//On vide le buffer
    					i2c_flag = 0;	
    				}	
    				else if(SSPSTATbits.D_A == 1)
    				{
    					i2c_data = SSPBUF;
    					++i2c_flag;
    				//	putcUSART(i2c_data);
    				}
    
    				switch(i2c_flag)
    				{
    [...]
    						SSPCONbits.CKP=1;
    				}				
                    PIR1bits.SSPIF = 0; // on va réautoriser l'interruption				
    		}
    		
    		//Éteint la DEL
    		IRO1 = 1;
    				
    	    PRODL = sauv1;        // on restaure les registres de calcul
            PRODH = sauv2;               
    }
    #pragma code

Sur le même thème :

Discussions similaires

  1. Quand s'executent les interruptions d'un PIC 16F877???
    Par snorky7 dans le forum Électronique
    Réponses: 11
    Dernier message: 02/05/2008, 22h07
  2. Aides sur les Interruptions
    Par Paulochon dans le forum Électronique
    Réponses: 8
    Dernier message: 18/06/2007, 13h20
  3. PIC F876A et i2c
    Par noisyboxes dans le forum Électronique
    Réponses: 2
    Dernier message: 16/03/2007, 07h44
  4. interruptions PIC 18F452
    Par koaber dans le forum Électronique
    Réponses: 3
    Dernier message: 09/03/2005, 19h37
  5. interruptions portB PIC
    Par romelec dans le forum Électronique
    Réponses: 6
    Dernier message: 02/05/2004, 10h12