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

Pic16f876A/communication RS232



  1. #1
    Bidebuster

    Pic16f876A/communication RS232

    Bonjour,

    J'ai un petit (gros) problème où je commence à craquer tellement je sais plus quoi faire !!!
    Je vous explique :
    je dois contrôler un moteur pas à pas via le port série de mon pc et un pic 16f876A.
    Voici le programme entré dans le pic :
    Code:
    #include <INT16CXX.H>
    
    //Définition des variables globales
     unsigned char cData;	       	         	// Octet de réception de donnée 
     bit bSerie;
     const char msgOK[]="OK";	        		// Message ok
     char cT;			        				// Déclaration d'une variable char nommée cT
     char X,Y;
     char T;
    
    //Liste des fonctions
     void Serial_Init(void); 					// Initialisation Port série 9600 baud 8 data bit ,1 bit stop, pas de parité
     void Serial_Putchar(unsigned char cD);  	// Cette fonction envoie des données sur le port série
     static interrupt inter();	         		// Fonction d'interruption, détecte l'arrivée d'une donnée
     void mov_D(void);
     void deplacementX(void);
     void tempo(void);
    
    
    #pragma origin 4
    #pragma config |= 0xb71
    #pragma chip PIC16F876A
    
    
     void main() //****************** debut Main ******************************
     {
      	GIE=1; PEIE=1; 								// Autorise les interruptions
      	TRISC=0b10000000;							// RC7 RX en entrée, RC6 TX en sortie 
    	X=0;										//1ère étape de l'ordre des phases du moteur Gauche-Droit
    	Y=0;										//1ère étape de l'ordre des phases du moteur Haut-Bas
    
      	Serial_Init();								// Initialisation port série     
    
     	/* boucle principale */
      	while(1)	
      	{
             if(bSerie)
    		{		
    		
    		if(cData==48) 
    			{
    			for(cT=0;cT<=1;cT++)
    			Serial_Putchar(msgOK[cT]);
    			PORTB=0x0F&0x0A;
    			tempo();
    			Serial_Putchar(X);
    			X++;
    			}
    		if(cData==49) 
    			{
    			for(cT=0;cT<=1;cT++)
    			Serial_Putchar(msgOK[cT]);
    			PORTB=0x0F&0x09;
    			tempo();
    			Serial_Putchar(X);
    			X++;
    			}	
    		if(cData==50)
    			{
    			for(cT=0;cT<=1;cT++)
    			Serial_Putchar(msgOK[cT]); 
    			PORTB=0x0F&0x05;
    			tempo();
    			Serial_Putchar(X);
    			X++;
    			}
    		if(cData==51) 
    			{
    			for(cT=0;cT<=1;cT++)
    			Serial_Putchar(msgOK[cT]);
    			PORTB=0x0F&0x06;
    			tempo();
    			Serial_Putchar(X);
    			X=0;
    			}
    		bSerie=0;			           	// bSerie passe à 0, attente nouvelle interruption		
    		CREN=1;          		       		// Active la réception série
    		}
        }
    
     }// ************************ fin de main******************************
    
    
     void Serial_Init(void)    // Initialisation Port série 9600 baud 8 data bit, 1 bit stop, pas de parité
    {
    	RCIE=1;				   // valide l'interruption de réception
    	RCSTA=0b10010000;	   // SPEN=1 valide le port série, CREN=1 valide la réception de donnée
    	TXSTA=0b00100110;	   // high speed mode brgh1 , TXEN 1 autorise émission de donnée
    	SPBRG=25;			   // 9600 baud
    	TRISB=0;
    	PORTB=0;
    	bSerie=0;			   // si 1 traité caractère serie reçu.
    }
    
     void Serial_Putchar(unsigned char cD)   // Emission de donnée sur le port série
    {
    	while(!TXIF);						// si 1 registre d'émission vide, donc on sort de la boucle                 	
    	TXREG=cD;							// On place le caractère cD à envoyer dans le registre TXREG
    	while(!TRMT);						// Lorsque TRMT passe à 1 TXREG recoit la donnée cD                         
    } 
    
    static interrupt inter()   // Fonction d'interruption
    {
    	int_save_registers
    	if(RCIF)
    	{
    		   
    	       cData=RCREG;   	// Place le caractère reçu dans cData
    	       CREN=0;			// Désactive la réception de donnée
    	       bSerie=1;        // bSerie passe à 1 pour indiquer au programme de traiter la donnée		
    	       RCIF=0;			
    	 }  
    	int_restore_registers
    }
    
    //La fonction tempo
    	void tempo(void)
    	{
    		int i;
    		int vitesse=100;
    		for(i=0;i<vitesse;i++)
    		{
    			nop();
    		}
    	}
    (au début, il était bien plus optimisé, mais je me suis ramené à des choses plus simples pour essayer de comprendre :P )

    Quand je met en commentaire les sorties sur le PORTB, pas de problème, la communication se fait sans problèmes, aucun souci.
    Par contre, quand j'essaye d'envoyer les différentes séquences vers le moteur pas à pas (via une carte de puissance), les problèmes arrivent !!!
    Je m'explique :
    Si j'envoie la donnée "048" ou "049", pas de problème, le pic me renvoie la bonne séquence.
    Par contre, dès que j'envoie "050" ou "051", le pic me renvoie la séquence suivante "079 075 002 255".
    Pourtant, il n'y a aucune différence entre les deux premières étapes et les deux dernières
    Je ne comprends vraiment pas ce qui ne va pas...
    Est-ce du à la configuration du portB ???

    Merci

    -----


  2. Publicité
  3. #2
    Bidebuster

    Re : Pic16f876A/communication RS232

    Re,
    j'ai un peu modifié le code pour voir d'où pouvait venir l'erreur :
    Code:
    #include <INT16CXX.H>
    
    //Définition des variables globales
     unsigned char cData;	       	         	// Octet de réception de donnée 
     bit bSerie;
     const char msgOK[]="OK";	        		// Message ok
     const char msgE1[]="E1";	        		// Message E1
     const char msgE2[]="E2";	        		// Message E2
     char cT;			        				// Déclaration d'une variable char nommée cT
     char X,Y;
     char T;
    
    //Liste des fonctions
     void Serial_Init(void); 					// Initialisation Port série 9600 baud 8 data bit ,1 bit stop, pas de parité
     void Serial_Putchar(unsigned char cD);  	// Cette fonction envoie des données sur le port série
     static interrupt inter();	         		// Fonction d'interruption, détecte l'arrivée d'une donnée
     void mov_D(void);
     void deplacementX(void);
     void tempo(void);
    
    
    #pragma origin 4
    #pragma pic16f876A
    
    static interrupt inter()   // Fonction d'interruption
    {
    	int_save_registers
    	if(RCIF)
    	{
    		   
    	       cData=RCREG;   	// Place le caractère reçu dans cData
    	       CREN=0;			// Désactive la réception de donnée
    	       bSerie=1;        // bSerie passe à 1 pour indiquer au programme de traiter la donnée		
    	       RCIF=0;			
    	 }  
    	int_restore_registers
    }
    
     void main() //****************** debut Main ******************************
     {
      	GIE=1; PEIE=1; 								// Autorise les interruptions
      	TRISC=0b10000000;							// RC7 RX en entrée, RC6 TX en sortie 
    	X=0;										//1ère étape de l'ordre des phases du moteur Gauche-Droit
    	Y=0;										//1ère étape de l'ordre des phases du moteur Haut-Bas
    
      	Serial_Init();								// Initialisation port série     
    
     	/* boucle principale */
      	while(1)	
      	{
    	    if(bSerie)
    		{		
    			for(cT=0;cT<=1;cT++)
    			Serial_Putchar(msgE1[cT]);
    		//	if(cData==68) 		    			// Détection de la donnée 'D'   
    		//	{		
    		//		mov_D();  						// Déplacement vers la droite 
    		//		for(cT=0;cT<=1;cT++)
    		//			Serial_Putchar(msgOK[cT]);  // Envoi du message OK 
    			//	Serial_Putchar(X);
    			//	TXREG=0;
    		//	}
    if(cData==48) {
    for(cT=0;cT<=1;cT++)
    Serial_Putchar(msgOK[cT]);
    PORTB=0x0F&0x08;
    tempo();
    //Serial_Putchar(X);
    // X++;
    }
    if(cData==49) {
    for(cT=0;cT<=1;cT++)
    Serial_Putchar(msgOK[cT]);
    PORTB=0x0F&0x02;
    tempo();
    //Serial_Putchar(X);
    //X++;
    }
    if(cData==50) {
    for(cT=0;cT<=1;cT++)
    Serial_Putchar(msgOK[cT]);
    PORTB=0x0F&0x04;
    tempo();
    //Serial_Putchar(X);
    // X++; 
    }
    if(cData==51) {
    for(cT=0;cT<=1;cT++)
    Serial_Putchar(msgOK[cT]);
    PORTB=0x0F&0x01;
    tempo();
    //Serial_Putchar(X);
    //X=0;
    }
    			for(cT=0;cT<=1;cT++)
    			Serial_Putchar(msgE2[cT]);
    			bSerie=0;			           		// bSerie passe à 0, attente nouvelle interruption		
    			CREN=1;          		       		// Active la réception série
    		}
        }
    
     }// ************************ fin de main******************************
    
    
     void Serial_Init(void)    // Initialisation Port série 9600 baud 8 data bit, 1 bit stop, pas de parité
    {
    	RCIE=1;				   // valide l'interruption de réception
    	RCSTA=0b10010000;	   // SPEN=1 valide le port série, CREN=1 valide la réception de donnée
    	TXSTA=0b00100110;	   // high speed mode brgh1 , TXEN 1 autorise émission de donnée
    	SPBRG=25;			   // 9600 baud
    	TRISB=0;
    	PORTB=0;
    	bSerie=0;			   // si 1 traité caractère serie reçu.
    }
    
     void Serial_Putchar(unsigned char cD)   // Emission de donnée sur le port série
    {
    	while(!TXIF);						// si 1 registre d'émission vide, donc on sort de la boucle                 	
    	TXREG=cD;							// On place le caractère cD à envoyer dans le registre TXREG
    	while(!TRMT);						// Lorsque TRMT passe à 1 TXREG recoit la donnée cD                         
    } 
    
    //La fonction tempo
    	void tempo(void)
    	{
    		unsigned delay: 16;
    		for(delay=0;delay<10;delay++)
    			nop(); 		//fonction qui ne fait rien
    	}
    voila ce que j'obtiens en communiquant avec le pic :


    si ça peut aider quelqu'un à mieux comprendre mon problème

    merci

  4. #3
    freepicbasic

    Re : Pic16f876A/communication RS232

    rien de visible...
    Les bits de config sont bizarres ...
    essai les bits de config "0x3f31"

    sinon voir le hard
    A+, pat

  5. #4
    Bidebuster

    Re : Pic16f876A/communication RS232

    Bonjour,
    merci de ta réponse
    Pour les bits de configs, je vais essayer
    Par contre, pour le hard, j'ai des doutes :s En effet, tout ce qui est carte de puissance pour contrôler le moteur est fonctionnel, vu que le système existant auparavant (à savoir un pic contrôler par une sorte de télécommande basée sur des interrupteurs) marchait bien !!! Et ici, ce n'est pas la liaison rs232 qui est en cause, elle marche parfaitement à partir du moment où l'on ne demande pas au pic de sortir quelque chose du port B...

    Merci

  6. #5
    HULK28

    Re : Pic16f876A/communication RS232

    Salut,

    en regardant vite fait, je me demande si la variable cT ne serait pas la cause du non passage dans les boucles suivantes, comme si elle n'était pas correctement (ré)initialisée...

  7. A voir en vidéo sur Futura
  8. #6
    Bidebuster

    Re : Pic16f876A/communication RS232

    Salut,
    En remettant cT à zéro après chaque envoi de donnée, il y a un léger mieux mais ce n'est pas encore ça
    Sinon, j'ai remarqué un truc bizarre... en débranchant les connecteurs qui relient le pic à la carte de puissance, j'ai remarqué qu'il y avait une différence de tension de de l'ordre du volt par rapport à la masse... j'ai alors réessayé en version "manuelle", mais ça marche toujours nickel... le fait qu'il y ait cette tension sur le portB pourrait-il perturber la liaison rs232 ?

    Par ailleurs, à partir du moment où ça commence à bugger, j'observe un fonctionnement totalement aléatoire de la communication série jusqu'au moment où je reçois le caractère ÿ, soit 255. Ensuite, cela remarche, mais il semble que toutes les variables sont réinitialisées. L'envoi du caractère ÿ signifie-t'il qu'il y a eu un reset ?

  9. Publicité
  10. #7
    freepicbasic

    Re : Pic16f876A/communication RS232

    symptome caractéristique ...

    ca ressemble à une mauvaise connexion d'alime !
    Vérifier le vcc et gnd.
    Le pic arrive à fonctionner avec un retour de masse sur un PORT !

    lorsque le port change d'état c'est le plantage.
    A+, pat

  11. #8
    Bidebuster

    Re : Pic16f876A/communication RS232

    Bon, grande avancée !!!
    J'ai testé les bits de sortie du portB un par un, et un seul fait planter le truc : le bit B2... j'ai donc mis les séquences de sortie sur les quatres derniers bits et là ça fonctionnait
    Ca fait plaisir !!!
    Par contre, vu qu'en fait je dois contrôler deux moteurs, il faudrait savoir pourquoi ça coince pour ce bit là... Au niveau alim,tout à l'air ok, c'est peut-être au niveau du support qu'il y a un problème... On verra ça lundi

    Dernière chtite question : le moteur tourne bien moins vite qu'en pilotage manuelle, cela est-il du au débit de la liaison (9600 bauds) ? Si l'on veut augmenter le débit, peut-on le faire indépendamment de la fréquence du quartz ou alors faut-il le changer ?

    Merci

  12. #9
    Bidebuster

    Re : Pic16f876A/communication RS232

    Bonjour bonjour !
    Alors si je reviens c'est qu'il y a encore des problèmes...
    Concernant le problème du port B, je l'ai contourné en utilisant quatre bits du portC...

    Maintenant, à vide, pas de problème le pic répond bien, il envoie les bonnes tensions.

    Quand je teste les moteurs indépendamment l'un de l'autre (c'est à dire en ne connectant qu'une seule des cartes de puissance) , pas de problèmes non plus.

    Par contre, en connectant les deux cartes de puissance en même temps, le pic ne réagit plus
    Il est même complètement effacé certaines fois ???

    Est-ce que ça peut venir du fait qu'on mesure une tension provenant de la carte de puissance ?
    Pourtant, en mode "manuel", on observe les mêmes tensions et ça ne pose pas de problèmes....

Sur le même thème :

Discussions similaires

  1. communication pic 16f877+RS232
    Par T-bag dans le forum Électronique
    Réponses: 9
    Dernier message: 17/09/2013, 10h06
  2. communication par rs232
    Par the_lightner dans le forum Électronique
    Réponses: 14
    Dernier message: 18/07/2007, 10h24
  3. Pb de Quartz PIC16F876A
    Par FantomX dans le forum Électronique
    Réponses: 5
    Dernier message: 12/01/2007, 08h08
  4. Communication GSM/PC via rs232
    Par zanzeoo dans le forum Électronique
    Réponses: 4
    Dernier message: 25/09/2006, 11h40
  5. pbm PIC16f876A et I2C
    Par midnight dans le forum Électronique
    Réponses: 14
    Dernier message: 03/01/2004, 23h12