Problème programme PIC18F2580 (int/timer)
Répondre à la discussion
Affichage des résultats 1 à 6 sur 6

Problème programme PIC18F2580 (int/timer)



  1. #1
    invite070f05b5

    Problème programme PIC18F2580 (int/timer)


    ------

    Bonjour,
    Comme indiqué dans le titre, j'ai un soucis avec mon programme. J'ai vérifié une dizaine de fois et je ne vois toujours pas ou est mon problème.
    Le programme est un chenillard un peut spécial pour mon hexacopter, il y a un bouton pour les modes du chenillard et un signal PWM pour faire varier la vitesse de défilement.
    PWM mini => Ton = 1ms => vitesse défilement minimale
    PWM max => Ton = 2ms => vitesse défilement maximale

    Programme :
    Code:
    /*******************************************************************************************************
    * Fichier:        	        leds.c
    * auteur:    		David Lejeune
    * date:    			09/04/2013 
    * but :	                controler leds hexa par radio (pwm)
    ********************************************************************************************************/     
    
    #include <p18f4520.h> 
    
    /*******************************************************************************************************
    * Configuration des bits */
    
    #pragma config OSC = XT					// oscillateur du type quartz
    #pragma config WDT = OFF				// pas de watchdog timer
    #pragma config LVP = OFF				// single-supply ICSP inacticf	
    #pragma config BOREN = OFF				// brown-out reset inactif
    
    /*******************************************************************************************************
    * declaration des variables */
    
    unsigned char capture;
    unsigned char tampon;
    unsigned char mode;
    unsigned int temps;
    
    
    /*******************************************************************************************************
    * Configuration interruption de priorité basse */
    
    void low_isr (void);
    
    #pragma code low_vector=0x18
    
    void interrupt_at_low_vector(void)
    {
     _asm GOTO low_isr _endasm
    }
    
    /*******************************************************************************************************
    * Programme d'interruption de priorité basse */
    
    #pragma code /* return to the default code section */
    #pragma interruptlow low_isr
    
    void low_isr (void)
    {
    	if(INTCON3bits.INT1IF)					// verification si INT1(RB1) est la cause de l'IT
    		{									
    			mode = mode + 1;				//Mode suivant
    			if(mode == 6)					//Retour au mode 1 si dernier mode
    				mode = 1;
    			INTCON3bits.INT1IF = 0;			// remise à '0' du flag  INT1IF
    		}									
    	else
    		{									// si pas INT1 (RB1) alors rien 
    			Nop();							
    		}
    }
    
    /*******************************************************************************************************
    * Configuration interruption de priorité haute */
    
    void high_isr (void);
    
    #pragma code high_vector=0x08
    void interrupt_at_high_vector(void)
    {
     _asm GOTO high_isr _endasm
    }
    
    /*******************************************************************************************************
    * Programme d'interruption de priorité haute */
    
    #pragma code /* return to the default code section */
    #pragma interrupt high_isr
    
    void high_isr (void)
    {
    	if(INTCONbits.INT0IF)					// verification si INT0(RB0) est la cause de l'IT
    		{	
    			if(capture == 1)					//Si capture en cours
    			{
    				T0CONbits.TMR0ON = 0;			//Arrêt comptage du timer0
    				tampon = TMR0L;					//Récuperation valeur
    				temps = TMR0H;
    				temps = temps<<8;
    				temps = temps | tampon;
    				temps = temps - 1000; 
    				INTCON2bits.INTEDG0=1;			//Interruption sur front montant
    				capture = 0;					//Indication capture terminée
    			}
    			else
    			{								
    				T0CONbits.TMR0ON = 1;			// Début comptage timer0
    				INTCON2bits.INTEDG0=0;			//Interruption sur front descendant
    				capture = 1;					//Indication capture en cours
    			}
    
    			INTCONbits.INT0IF = 0;			// remise à '0' du flag  INT0IF
    		}									
    	else
    		{									// si pas INT0 (RB0) alors rien 
    			Nop();							
    		}	
    }
    
    /*******************************************************************************************************
    * Programmme principal */
    
    #pragma code
    
    void tempo(char delais,int temps)
    {
     	int j=0;
      
    	for( j=0 ; j<temps ; j++ )
    	{
    		Delay100TCYx(delais);
    	}
    
    
    }
    
    
    void main (void)
    {
    	TRISC = 0xFF;							//Port C en entrée
    	TRISB = 0xFF;							//Port B en entrée
    	TRISA = 0x3F;							//Port A en sortie
    			
    		
    	ADCON1 = 0x0F;							//0 entrées analogiques
    
    	T0CON = 0b00011000;
    	TMR0H = 0x00;
    	TMR0L = 0x00;
    	INTCONbits.TMR0IF = 0;
    	
    	RCONbits.IPEN = 1;                           //...diverses initialisations
    	INTCONbits.INT0IF = 0;
    	INTCON3bits.INT1IF = 0;
    	INTCON2bits.INTEDG0 = 1;
    	INTCON2bits.INTEDG1 = 0;
    	INTCONbits.GIE = 1;
    
    	INTCONbits.INT0IE = 1;
    	INTCON3bits.INT1IE = 1;
    
    	mode = 1;
    	capture = 0;
    
    
      	while (1)
        {
    		if(mode == 1)				//	Mode 1
    		{
    		    PORTA = 0x03;
    		    tempo(20, temps);
    		    PORTA = 0x00;
    		    tempo(20, temps);
    		    PORTA = 0x03;
    		    tempo(20, temps);
    		    PORTA = 0x00;
    		    tempo(50, temps);
    		    PORTA = 0x3C;
    		    tempo(20, temps);
    		    PORTA = 0x00;
    		    tempo(20, temps);
    		    PORTA = 0x3C;
    		    tempo(20, temps);
    		    PORTA = 0x00;
    		    tempo(50, temps);
    		}
    	
    	        	
    		if(mode == 2)				//	Mode 2
    		{
    		    PORTA = 0x01;
    		    tempo(25, temps);
    		    PORTA = 0x02;
    		    tempo(25, temps);
    		    PORTA = 0x04;
    		    tempo(25, temps);
    		    PORTA = 0x08;
    		    tempo(25, temps);
    		    PORTA = 0x10;
    		    tempo(25, temps);
    		    PORTA = 0x20;
    		    tempo(25, temps);
    		}
    	    
    	             
    		if(mode == 3)				//	 Mode 3
    		{
    		    PORTA = 0x20;
    		    tempo(25, temps);
    		    PORTA = 0x10;
    		    tempo(25, temps);
    		    PORTA = 0x08;
    		    tempo(25, temps);
    		    PORTA = 0x04;
    		    tempo(25, temps);
    		    PORTA = 0x02;
    		    tempo(25, temps);
    		    PORTA = 0x01;
    		    tempo(25, temps);
    		}
    	    
    	             
    		if(mode == 4)				//	 Mode 4
    		{
    		    PORTA = 0x02;
    		    tempo(25, temps);
    		    PORTA = 0x04;
    		    tempo(25, temps);
    		    PORTA = 0x08;
    		    tempo(25, temps);
    		    PORTA = 0x10;
    		    tempo(25, temps);
    		    PORTA = 0x20;
    		    tempo(25, temps);
    		    PORTA = 0x01;
    		    tempo(25, temps);
    		    PORTA = 0x20;
    		    tempo(25, temps);
    		    PORTA = 0x10;
    		    tempo(25, temps);
    		    PORTA = 0x08;
    		    tempo(25, temps);
    		    PORTA = 0x04;
    		    tempo(25, temps);
    		}
    	
    	              
    		if(mode == 5)				//	Mode 5
    		{
    		    PORTA = 0x03;
    		    tempo(25, temps);
    		    PORTA = 0x24;
    		    tempo(25, temps);
    		    PORTA = 0x18;
    		    tempo(25, temps);
    		}
    			
    		
       	}
    }
    Petite photo pour montrer a quoi va servir tout cela Nom : DSC_0146[1].jpg
Affichages : 76
Taille : 278,4 Ko

    -----

  2. #2
    invite070f05b5

    Re : Problème programme PIC18F2580 (int/timer)

    Je précise que c'est un quartz de 4 mhz

  3. #3
    RISC

    Re : Problème programme PIC18F2580 (int/timer)

    Salut,

    Il y a des choses incorrectes dans ton programme :


    volatile unsigned char mode;
    .....

    Code:
    void low_isr (void)
    {
    	if(INTCON3bits.INT1IF && INTCON3bits.INT1IE)		// verification si INT1(RB1) est la cause de l'IT
    		{									
    			mode = mode + 1;				//Mode suivant
    			if(mode == 6)					//Retour au mode 1 si dernier mode
    				mode = 1;
    			INTCON3bits.INT1IF = 0;			// remise à '0' du flag  INT1IF
    		}									
    	else
    		{									
    			while(1);					// si on vient ici c'est grave...on ne devrait JAMAIS y venir !!! 
    		}
    }
    Code:
    void high_isr (void)
    {
    	if(INTCONbits.INT0IF && INTCONbits.INT0IE)					// verification si INT0(RB0) est la cause de l'IT
    		{	
    			if(capture == 1)					//Si capture en cours
    			{
    				T0CONbits.TMR0ON = 0;			//Arrêt comptage du timer0
    				tampon = TMR0L;					//Récuperation valeur
    				temps = TMR0H;
    				temps = temps<<8;
    				temps = temps | tampon;
    				temps = temps - 1000; 
    				INTCON2bits.INTEDG0=1;			//Interruption sur front montant
    				capture = 0;					//Indication capture terminée
    			}
    			else
    			{								
    				T0CONbits.TMR0ON = 1;			// Début comptage timer0
    				INTCON2bits.INTEDG0=0;			//Interruption sur front descendant
    				capture = 1;					//Indication capture en cours
    			}
    
    			INTCONbits.INT0IF = 0;			// remise à '0' du flag  INT0IF
    		}									
    	else
    		{									// si pas INT0 (RB0) alors rien 
    			while(1);						// si on vient ici c'est grave...on ne devrait JAMAIS y venir !!! 							
    		}	
    }
    Dans ton programme principal, il FAUT initialiser mode avant d'autoriser les interruptions.
    D'autre part, lorsque RCONbits.IPEN = 1;

    Tu devrais avoir dans ton programme :
    INTCONbits.GIEH = 1; // autoriser les interruptions de priorité haute
    et
    INTCONbits.GIEL = 1; // autoriser les interruptions de priorité basse

    et pour TOUTES ls variables globales modiifées dans les interruptions, il faut ajouter volatile :

    Code:
    * declaration des variables */
    
    volatile unsigned char capture;
    volatile unsigned char tampon;
    volatile unsigned char mode;
    volatile unsigned int temps;

  4. #4
    invite070f05b5

    Re : Problème programme PIC18F2580 (int/timer)

    Voila donc j'ai fait comme tu m'as dit mais le problème persiste.

    Programme modifié :
    Code:
    /*******************************************************************************************************
    * Fichier:        	leds.c
    * auteur:    		David Lejeune
    * date:    			09/04/2013 
    * but :				controler leds hexa par radio (pwm)
    ********************************************************************************************************/     
    
    #include <p18f4520.h> 
    
    /*******************************************************************************************************
    * Configuration des bits */
    
    #pragma config OSC = XT					// oscillateur du type quartz
    #pragma config WDT = OFF				// pas de watchdog timer
    #pragma config LVP = OFF				// single-supply ICSP inacticf	
    #pragma config BOREN = OFF				// brown-out reset inactif
    
    /*******************************************************************************************************
    * declaration des variables */
    
    volatile unsigned char capture;
    volatile unsigned char tampon;
    volatile unsigned char mode;
    volatile unsigned int temps;
    
    
    /*******************************************************************************************************
    * Configuration interruption de priorité basse */
    
    void low_isr (void);
    
    #pragma code low_vector=0x18
    
    void interrupt_at_low_vector(void)
    {
     _asm GOTO low_isr _endasm
    }
    
    /*******************************************************************************************************
    * Programme d'interruption de priorité basse */
    
    #pragma code /* return to the default code section */
    #pragma interruptlow low_isr
    
    void low_isr (void)
    {
    	if(INTCON3bits.INT1IF && INTCON3bits.INT1IE)		// verification si INT1(RB1) est la cause de l'IT
    		{									
    			mode = mode + 1;				//Mode suivant
    			if(mode == 6)					//Retour au mode 1 si dernier mode
    				mode = 1;
    			INTCON3bits.INT1IF = 0;			// remise à '0' du flag  INT1IF
    		}									
    	else
    		{									
    			while(1);					// si on vient ici c'est grave...on ne devrait JAMAIS y venir !!! 
    		}
    }
    
    /*******************************************************************************************************
    * Configuration interruption de priorité haute */
    
    void high_isr (void);
    
    #pragma code high_vector=0x08
    void interrupt_at_high_vector(void)
    {
     _asm GOTO high_isr _endasm
    }
    
    /*******************************************************************************************************
    * Programme d'interruption de priorité haute */
    
    #pragma code /* return to the default code section */
    #pragma interrupt high_isr
    
    void high_isr (void)
    {
    	if(INTCONbits.INT0IF && INTCONbits.INT0IE)					// verification si INT0(RB0) est la cause de l'IT
    		{	
    			if(capture == 1)					//Si capture en cours
    			{
    				T0CONbits.TMR0ON = 0;			//Arrêt comptage du timer0
    				tampon = TMR0L;					//Récuperation valeur
    				temps = TMR0H;
    				temps = temps<<8;
    				temps = temps | tampon;
    				temps = temps - 1000; 
    				INTCON2bits.INTEDG0=1;			//Interruption sur front montant
    				capture = 0;					//Indication capture terminée
    			}
    			else
    			{								
    				T0CONbits.TMR0ON = 1;			// Début comptage timer0
    				INTCON2bits.INTEDG0=0;			//Interruption sur front descendant
    				capture = 1;					//Indication capture en cours
    			}
    
    			INTCONbits.INT0IF = 0;			// remise à '0' du flag  INT0IF
    		}									
    	else
    		{									// si pas INT0 (RB0) alors rien 
    			while(1);						// si on vient ici c'est grave...on ne devrait JAMAIS y venir !!! 	mais on y vient quand même :hum:						
    		}	
    }
    
    /*******************************************************************************************************
    * Programmme principal */
    
    #pragma code
    
    void tempo(char delais,int temps)
    {
     	int j=0;
      
    	for( j=0 ; j<temps ; j++ )
    	{
    		Delay100TCYx(delais);
    	}
    
    
    }
    
    
    void main (void)
    {
    	TRISC = 0xFF;							//Port C en entrée
    	TRISB = 0xFF;							//Port B en entrée
    	TRISA = 0x3F;							//Port A en sortie
    			
    		
    	ADCON1 = 0x0F;							//0 entrées analogiques
    
    	T0CON = 0b00011000;
    	TMR0H = 0x00;
    	TMR0L = 0x00;
    	INTCONbits.TMR0IF = 0;
    	
    	RCONbits.IPEN = 1;                           //...diverses initialisations
    	INTCONbits.INT0IF = 0;
    	INTCON3bits.INT1IF = 0;
    	INTCON2bits.INTEDG0 = 1;
    	INTCON2bits.INTEDG1 = 0;
    
    	INTCONbits.GIEH = 1; 						// autoriser les interruptions de priorité haute
    	INTCONbits.GIEL = 1;						// autoriser les interruptions de priorité basse
    
    	mode = 1;
    	capture = 0;
    
    	INTCONbits.INT0IE = 1;
    	INTCON3bits.INT1IE = 1;
    
    
      	while (1)
        {
    		if(mode == 1)				//	Mode 1
    		{
    		    PORTA = 0x03;
    		    tempo(20, temps);
    		    PORTA = 0x00;
    		    tempo(20, temps);
    		    PORTA = 0x03;
    		    tempo(20, temps);
    		    PORTA = 0x00;
    		    tempo(50, temps);
    		    PORTA = 0x3C;
    		    tempo(20, temps);
    		    PORTA = 0x00;
    		    tempo(20, temps);
    		    PORTA = 0x3C;
    		    tempo(20, temps);
    		    PORTA = 0x00;
    		    tempo(50, temps);
    		}
    	
    	        	
    		if(mode == 2)				//	Mode 2
    		{
    		    PORTA = 0x01;
    		    tempo(25, temps);
    		    PORTA = 0x02;
    		    tempo(25, temps);
    		    PORTA = 0x04;
    		    tempo(25, temps);
    		    PORTA = 0x08;
    		    tempo(25, temps);
    		    PORTA = 0x10;
    		    tempo(25, temps);
    		    PORTA = 0x20;
    		    tempo(25, temps);
    		}
    	    
    	             
    		if(mode == 3)				//	 Mode 3
    		{
    		    PORTA = 0x20;
    		    tempo(25, temps);
    		    PORTA = 0x10;
    		    tempo(25, temps);
    		    PORTA = 0x08;
    		    tempo(25, temps);
    		    PORTA = 0x04;
    		    tempo(25, temps);
    		    PORTA = 0x02;
    		    tempo(25, temps);
    		    PORTA = 0x01;
    		    tempo(25, temps);
    		}
    	    
    	             
    		if(mode == 4)				//	 Mode 4
    		{
    		    PORTA = 0x02;
    		    tempo(25, temps);
    		    PORTA = 0x04;
    		    tempo(25, temps);
    		    PORTA = 0x08;
    		    tempo(25, temps);
    		    PORTA = 0x10;
    		    tempo(25, temps);
    		    PORTA = 0x20;
    		    tempo(25, temps);
    		    PORTA = 0x01;
    		    tempo(25, temps);
    		    PORTA = 0x20;
    		    tempo(25, temps);
    		    PORTA = 0x10;
    		    tempo(25, temps);
    		    PORTA = 0x08;
    		    tempo(25, temps);
    		    PORTA = 0x04;
    		    tempo(25, temps);
    		}
    	
    	              
    		if(mode == 5)				//	Mode 5
    		{
    		    PORTA = 0x03;
    		    tempo(25, temps);
    		    PORTA = 0x24;
    		    tempo(25, temps);
    		    PORTA = 0x18;
    		    tempo(25, temps);
    		}
    			
    		
       	}
    }
    J'ai essayé d’exécuter le programme en pas a pas mais il vas soit dans la boucle "interdite" des interruptions hautes ou sinon c'est MPLAB qui plante , pourquoi ?
    J'ai compris mes erreurs mais pour les interruption, je vois pas pourquoi tu mets INTCONbits.INT0IE dans la condition if(INTCONbits.INT0IF && INTCONbits.INT0IE)
    Si il est a 0 on ne devrait pas rentrer dans l'interruption ?

  5. A voir en vidéo sur Futura
  6. #5
    invite0e5af214

    Re : Problème programme PIC18F2580 (int/timer)

    Salut,

    Je ne vois pas de :
    INTCON3bits.INT1IP = 0 qui permettrait de configurer le fait que tu veux que cette interruption soit une lowinterrupt.

    C'est surement ca qui te fait partir dans l'interrupt high.

  7. #6
    invite070f05b5

    Re : Problème programme PIC18F2580 (int/timer)

    Bonjour,
    Désolé de répondre si tard je n'ai pas pu ce week-end.
    Merci cherwam07 j'y pensais pas du tout à ça ^^
    Donc ça marche, quelques optimisation à faire au niveau de la tempo et ce sera impect. merci a tous
    Cordialement

Discussions similaires

  1. Probleme de variable de type int PIC18F4620
    Par invite52e85ae4 dans le forum Électronique
    Réponses: 9
    Dernier message: 22/07/2010, 11h52
  2. Programmation en C avec Timer 0 et Timer 1
    Par invite6844fe5f dans le forum Électronique
    Réponses: 43
    Dernier message: 20/04/2010, 14h27
  3. probleme can pic18f2580
    Par invite6641b91f dans le forum Électronique
    Réponses: 2
    Dernier message: 18/05/2009, 15h49
  4. Problème avec les broches spéciales RB0/INT et RA4/T0CKI
    Par Montd'est dans le forum Électronique
    Réponses: 5
    Dernier message: 21/12/2008, 20h14
  5. INT management / Telecom INT
    Par invitefaf40fa4 dans le forum Orientation après le BAC
    Réponses: 0
    Dernier message: 02/02/2005, 18h44
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...