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

Communication I2C entre PIC et ordinateur / Problème d'interruption



  1. #1
    Franfrou

    Communication I2C entre PIC et ordinateur / Problème d'interruption


    ------

    Bonsoir,

    Je suis actuellement en train de réaliser une communication I2C entre un PC et un PIC 16F819 (comportant l'I2C intégré, comme le 16F87x).

    Je programme en C, sous Mplab, avec CC5X.

    Côté PC, j'utilise une interface et un driver trouvés sur cette page.

    L'initialisation du PIC (I2C en esclave sur une certaine adresse) se fait sans problème. En effet, lorsque depuis le PC je cherche tous les esclaves sur le port I2C, je retrouve bien mon PIC à l'adresse indiquée dans le PIC.

    Mon but dans un premier temps : faire allumer une LED selon une commande envoyée par le PC (un octet valant une certaine valeur).

    Voici le code à l'heure actuelle (le code est adapté de cette page dans laquelle il y avait selon moi plusieurs erreurs...) :

    Code:
    #include "int16CXX.h"
    
    //////////////////////////////////////////////////////////////////
    //					Configuration Word	(page 90)				//
    //////////////////////////////////////////////////////////////////
    
    #pragma config=0b11111100011000		// 3F18
    // Oscillator			INTRC-RA6 is Port I/O
    // Watchdog Timer		Off
    // Power Up Timer		Off
    // MCLR Select Bit		RA5 is digital I/0, MCLR tied to VDD
    // Brown Out Detect		Off
    // Low Voltage Program	Disabled
    // Flash Program Write	Write Protection Disabled
    // CCP1 Mux				RB2
    // Code Protect			Disabled
    
    //#pragma interruptSaveCheck  n  // no warning or error
    
    
    #pragma bit STAT_DA @ SSPSTAT.5
    #pragma bit STAT_RW @ SSPSTAT.2
    #pragma bit STAT_BF @ SSPSTAT.0
    #pragma bit STAT_S @ SSPSTAT.3
    
    #define NODE_ADDR 0x20 //Adresse du PIC sur le bus
    
    #define ETAT1 0x05
    #define IDENT1 0xFF
    #define IDENT2 0xFE
    #define IDLE 0x00
    
    #define allume 0x11
    
    // Déclaration des variables globales
    char rxindex,txindex;
    char commande ;
    char state ;
    
    bit inter @ PORTB.5;
    bit ledverte @ PORTA.0;
    bit ledorange @ PORTA.1;
    bit ledrouge @ PORTA.2;
    bit ledverte2 @ PORTA.3;
    bit RB0 @ PORTB.0;
    
    //-- Prototypes -- 
    
    void ssp_handler(void) ;
    void setup_i2c_esclave(char adresse);
    void WriteI2C(char data);
    char ReadI2C(void);
    
    #pragma origin 4 //Prise en charge des interruptions
    interrupt serverX(void)
    {
    	int_save_registers // W, STATUS (and PCLATH) char sv_FSR ;
    	//char sv_FSR = FSR ;
    	ssp_handler() ; //le gestionnaire d'I2C
    	if (state==allume)
    	{
    		ledverte=1;
    	}
    	//FSR=sv_FSR ;
    	int_restore_registers // W, STATUS (and PCLATH)
    }
    
    char ReadI2C(void)
    {
    	return(SSPBUF) ;
    }
    
    void ssp_handler(void)
    {
    	char data ;
    	//-------------------------------------------------------------------------------------------
    	// ETAT 1 : S'il s'agit d'une opération d'écriture et que le dernier octet etait une adresse
    	//-------------------------------------------------------------------------------------------
    	if( !STAT_DA && !STAT_RW && STAT_BF && STAT_S)
    	{
    		txindex=0 ; 
    		nop();
    		data=ReadI2C();
    	}
    
    	//if(SSPOV)
    	if(SSPIF)
    	{
    		//SSPOV = 0 ;
    		SSPIF = 0 ;
    		if (data==SSPADD) // On ignore si jamais c’est l’adresse ;
    		{
    			rxindex=1 ;
    			return ;
    		}
    		if (rxindex==1) // Premier octet reçu = commande
    		{
    			commande=data ;
    			rxindex++ ;
    			if (commande==ETAT1)
    			{
    				ledrouge=1;
    				state=allume;
    			}
    			return ;
    		}
    		return ;
    	}
    	else if (STAT_DA && !STAT_RW && STAT_BF)
    	{
    		data=ReadI2C() ; // Normalement , on y arrive jamais, mais on ne sait jamais...
    	}
    	//-------------------------------------------------------------------------------------------
    	// ETAT 3 : Il s'agit d'une operation de Lecture (READ) et le dernier octet etait une adresse
    		//--------------------------------------------------------------------------------------
    	// ETAT 5: Un NACK a été produit par le Maître afin d'indiquer la fin de la transmission
    	//--------------------------------------------------------------------------------------
    	else if (STAT_DA && !STAT_RW && !STAT_BF)
    	nop();
    }
    
    void init_pic(void)
    {
    	ADCON1=0b.0000.0110;	// L’initialisation préalable du registre ADCON1 
    							// est nécessaire pour l’utilisation du PORTA (page 82)
    	OPTION=0b.1100.1000;	// Réglage du timer 0 (page 53-54) + réglage pull-up PORTB (page 17)
    	OSCTUNE=0b.0000.0000;	// (page 36)
    	OSCCON=0b.0110.0100;	// Choix de la fréquence de l'oscillateur interne (page 38)
    
    	TRISA=0;
    	PORTA=0;
    	TRISB=0;
    	TRISB.0=1;				// RB0 configured as input
    	TRISB.5=1;				// RB5 configured as input
    	PIE1=0;
    
    	TMR0=0;
    
    	setup_i2c_esclave(NODE_ADDR);
    }
    
    void setup_i2c_esclave(char adresse)
    {
    	TRISB.1=1;				// SDA configured as input
    	TRISB.4=1;				// SCL configured as input
    
    	PIE1.3=1;				// Equivalent à SSPIE=1 => Enables the SSP interrupt
    	SSPCON=0b.0011.0110;	// Configuration du port série (page 73)
     
    	SSPADD=adresse;//<<1 ; 	// On charge l’adresse du composant
    	INTCON=0b.1101.1000;	// Réglage des interruptions (page 18)
    	//GIE = 1 ; 			// Interrupts allowed
    	//PEIE = 1 ;			// Contenu dans INTCON (page 18)
    	SSPSTAT=0;
    	SSPIF=0;				// Contenu dans PIR1 (page 20)
    }
    
    void main(void)
    {
    	init_pic();
    	state=0;
    
    	while(1)
    	{
    		nop();
    	
    		if (state==allume)
    		{
    			ledverte2=1;		
    		}
    	}
    }
    Lorsque j'envoie l'octet 5 (correspondant à "#define ETAT1 0x05") à l'adresse 32 (correspondant à "
    #define NODE_ADDR 0x20"), le PIC va bien dans l'interruption, il affectue la fonction "ssp_handler()" et affiche la "ledverte".

    Rappel de la routine d'interruption :
    Code:
    #pragma origin 4 //Prise en charge des interruptions
    interrupt serverX(void)
    {
    	int_save_registers // W, STATUS (and PCLATH) char sv_FSR ;
    	//char sv_FSR = FSR ;
    	ssp_handler() ; //le gestionnaire d'I2C
    	if (state==allume)
    	{
    		ledverte=1;
    	}
    	//FSR=sv_FSR ;
    	int_restore_registers // W, STATUS (and PCLATH)
    }
    Le problème, c'est qu'apparemment le PIC ne sort pas de l'interruption et donc il ne revient pas dans la boucle principale. Donc le même test "if (state==allume)" dans la boucle principale ne fonctionne pas et ma ledverte2 ne s'affiche pas...


    J'espère avoir été clair dans la rédaction de mon problème...

    Merci d'avance si quelqu'un peut m'aider

    -----

  2. Publicité
  3. #2
    chrichri51

    Re : Communication I2C entre PIC et ordinateur / Problème d'interruption

    Bonjour
    Je ne peux pas t'aider pour ton problème car je débute l'I2C
    Par contre je recherche des petits programmes qui me permettrait de lire et écrire sur un PCF8574
    Je recherche aussi un petit programme qui me permettrait de lire la températute du TC74 (capteur de température spécial I2C)
    J'utilise le port // (je ne connais pas du tout le c ou c++)
    Si tu as quelques truc la dessus je suis preneur
    A+

  4. #3
    Didelec

    Arrow Re : Communication I2C entre PIC et ordinateur / Problème d'interruption

    Voici quelque article pour chrichri51


    Bus I2C sur le port Parallèle Interface PC N°7 page 80

    Master I2C Electronique Pratique N° 271 page 98

    I2C en C sur PIC Electronique Pratique N° 280 page 24

    Cordialement Didier

  5. #4
    T-Bot

    Re : Communication I2C entre PIC et ordinateur / Problème d'interruption

    teste le SSPIF dans la boucle d'interruption.
    remets le à 0 en sortant.
    pourquoi tu as pas l'état 3 et 4 dans ton SSP handler -> tu auras de problèmes... Si si

  6. A voir en vidéo sur Futura

Discussions similaires

  1. communication i2c entre deux pics
    Par frednico56 dans le forum Électronique
    Réponses: 2
    Dernier message: 02/11/2007, 22h56
  2. probléme entre pic et l298
    Par $$alex$$ dans le forum Électronique
    Réponses: 9
    Dernier message: 26/04/2007, 08h51
  3. Réponses: 2
    Dernier message: 23/04/2007, 12h32
  4. PIC F876A et i2c
    Par noisyboxes dans le forum Électronique
    Réponses: 2
    Dernier message: 16/03/2007, 07h44
  5. probléme de liaison entre pic et rs232
    Par lembi dans le forum Électronique
    Réponses: 2
    Dernier message: 14/11/2006, 19h43
Découvrez nos comparatifs produits sur l'informatique et les technologies.