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

[MikroC] interruption bloque le programme



  1. #1
    nono313

    [MikroC] interruption bloque le programme


    ------

    Bonjour,
    Dans l'optique d'un travail scolaire, je dois faire un programme qui me permette, via une interruption de commander un servo moteur.
    Je suis parti d'un exemple que j'ai trouvé sur le net (ou dans une doc je ne sais plus).
    L'interruption fonctionne bien, elle est appelé toutes les 40µs (PIC 18F452 / 8MHz).
    Mon problème est que lorsque je lance mon programme, seul l'interruption semble est effectué et pas le programme du main (ici un while(1)).
    Voici mon code :
    Code:
    unsigned long cnt=1, servo = 38;		//cnt=1 pour éviter changement d'état au début
    
    // Interrupt Handler
    void interrupt()
    {
    
      if (PIR1.TMR2IF == 1)          // timer 2 interrupt flag
      {
    	if(cnt == servo || cnt == 0)
    		PORTD = ~PORTD;      // Toggle PORTD
        cnt++;
    	if(cnt == 25*15)		//15ms
    		cnt = 0;
        PIR1.TMR2IF = 0;     // clears TMR2IF       bit 1 TMR2IF: TMR2 to PR2 Match Interrupt Flag bit
      }
    }
    
    
    
    // code starts here...
    void main()
    {
    
      TRISD = 0x00;    // PORT is all output...to show the interrupts
      PORTD = 0xFF;       // start with all outputs low
      TRISB = 0xFF;		// entrées
      PORTB = 0;
      TRISC = 0;
      PORTC = 0;
      TRISA = 0;
     // ADCON1=
      PORTA = 0;
    
    //Timer2 Registers Prescaler= 1 - TMR2 PostScaler = 1 - PR2 = 2 - Freq = 1000000.00 Hz - Period = 0.000001 seconds
    T2CON |= 0;        // bits 6-3 Post scaler 1:1 thru 1:16
    T2CON.TMR2ON = 1;  // bit 2 turn timer2 on;
    T2CON.T2CKPS1 = 0; // bits 1-0  Prescaler Rate Select bits
    T2CON.T2CKPS0 = 0;
    PR2 = 2;         // PR2 (Timer2 Match value)
    
    // Interrupt Registers
      INTCON = 0;           // clear the interrpt control register
      INTCON.TMR0IE = 0;        // bit5 TMR0 Overflow Interrupt Enable bit...0 = Disables the TMR0 interrupt
      PIR1.TMR2IF = 0;            // clear timer1 interupt flag TMR1IF
      PIE1.TMR2IE = 1;         // enable Timer2 interrupts
      INTCON.TMR0IF = 0;        // bit2 clear timer 0 interrupt flag
      INTCON.GIE = 1;           // bit7 global interrupt enable
      INTCON.PEIE = 1;          // bit6 Peripheral Interrupt Enable bit...1 = Enables all unmasked peripheral interrupts
    
    
      while(1)  //endless loop
      {  int i=10;
      servo = 32;
    	  if(PORTB == 0b00000001)
    		{
          servo = 38;
        }
    	  if(PORTB == 0b00000010)
    	{
          servo++;
        }
        if(PORTB == 0b00000100)
    		{
          servo--;
        }
        PORTC = servo;
      }
    }

    -----

  2. Publicité
  3. #2
    Forhorse

    Re : [MikroC] interruption bloque le programme

    En 40µs à 8Mhz un PIC n'a le temps d'executer que 80 instructions assembleur, en C c'est vite atteind. A mon avis ton programme ne sort jamais de la routine d'interruption car aussi finit il y retourne.
    Essayes d'augmenter le temps entre chaque interruption.

  4. #3
    nono313

    Re : [MikroC] interruption bloque le programme

    Tout d'abord merci de ta réponse,
    J’essaierais de modifier les valeurs dans les registres de l'interruption dès que j'aurais à nouveau accès au matériel.
    Serait-il possible d'augmenter la fréquence d'horloge du PIC tout en gardant le même micro-contrôleur ?

  5. #4
    Forhorse

    Re : [MikroC] interruption bloque le programme

    Ben oui, mais avant d'augmenter la frequence de travail, il faut déjà voir à optimiser le programme

  6. A voir en vidéo sur Futura
  7. Comparatifs

    Gagnez du temps et de l'argent grâce à nos comparatifs de produits. Parmi nos sujets :
  8. #5
    invite03481543

    Re : [MikroC] interruption bloque le programme

    Bonsoir,

    pourquoi acceder a l'interruption toutes les 40 micro secondes ?

  9. #6
    MorpheusPic

    Re : [MikroC] interruption bloque le programme

    oui pourkoi faire les 40 µs ?

    pour controler un servo on y envoi une pulse toute les 20 mili-secondes

    et aussi avec sa tu fait perdre beaucoup de temp au pic "if(cnt == 25*15)" marque plutot if(cnt == 375) dailleur tu depasse les 8 bits avec sa, verifie si ta variable peut aller au dessu de 256

    a moisque que le compilateur remplace lui meme 25*15 par 375 ?
    Dernière modification par MorpheusPic ; 10/02/2011 à 00h59.

  10. Publicité
  11. #7
    nono313

    Re : [MikroC] interruption bloque le programme

    En mettant la prescaller à 1:16 et le postscaler à 1:16, j'arrive à obtenir (en théorie) des interruptions toutes les 10ms.
    Est-il possible d'utiliser un delay dans l'interruption (voir ci-dessous), sans gêner le programme ?
    Code:
    unsigned long cnt=0, servo = 38;		//cnt=1 pour éviter changement d'état au début		38 init à prescal = 0
    
    // Interrupt Handler
    void interrupt()
    {
    
      // Timer2 Interrupt
      if (PIR1.TMR2IF == 1)          // timer 2 interrupt flag
      {
    	if(cnt == 0)
    	{
    		PORTD = ~PORTD;      // Toggle PORTD
    		delay_µs(servo*40);
    		PORTD = ~PORTD;
    	}
        PIR1.TMR2IF = 0;     // clears TMR2IF       bit 1 TMR2IF: TMR2 to PR2 Match Interrupt Flag bit
    	cnt++;
    	if(cnt == 2)		
    		cnt = 0;
    	}
    }
    
    ...
    
    T2CON = 0b01110000;		//bits 3-6 : postscale
    T2CON.TMR2ON = 1;  // bit 2 turn timer2 on;
    T2CON.T2CKPS1 = 1; // bits 1-0  Prescaler Rate Select bits	 prescaller à 16
    T2CON.T2CKPS0 = 1;		//prescaler à 4
    PR2 = 2;         // PR2 (Timer2 Match value)

  12. #8
    Forhorse

    Re : [MikroC] interruption bloque le programme

    C'est possible mais c'est sâle !
    et ça va faire perdre du temps à tout le reste du programme.
    En principe quand on veut faire du timming précis, on reconfigure à la volé les paramètres et les valeurs du timer pour declancher une nouvelle interruption après le temps voulu.

  13. #9
    Forhorse

    Re : [MikroC] interruption bloque le programme

    sinon :
    [MODE IRONIQUE : ON]
    Met un AVR, comme il est 4 fois plus rapide qu'un PIC a frequence égale, ça doit pouvoir combler les manques de ton code de poney
    [MODE IRONIQUE : OFF]

    Comme quoi avoir un processeur puissant ça sert à rien si on ne sais pas s'en servir correctement.
    NB : j'ai rien contre toi nono, c'était juste une boutade envers qq1 qui se reconnaitra

  14. #10
    invite03481543

    Re : [MikroC] interruption bloque le programme

    On introduit jamais une temporisation dans une interruption.

    Pour commander un servo il faut fixer une periode puis utiliser le module compare de CCPx.

    On joue ensuite sur un offset qui reglera le ton dans cette periode, lorsque le match est realise avec le timer la sortie est mise a zero, vous avez ainsi votre impulsion.

    Regardez la datasheet de votre PIC la procedure est parfaitement documentee (Mode Compare module CCPx).

  15. #11
    nono313

    Re : [MikroC] interruption bloque le programme

    Tout d'abord je tiens à préciser que je suis débutant en programmation mikroC, je n'ai au que très peu de cours sur le sujet et de loin pas suffisamment poussé.
    Citation Envoyé par Forhorse Voir le message
    En principe quand on veut faire du timming précis, on reconfigure à la volé les paramètres et les valeurs du timer pour declancher une nouvelle interruption après le temps voulu.
    Je pense avoir compris ce que tu veux dire, mais le problème est que je ne peux pas non plus mettre de delay dans le programme principale, celui-ci se composant uniquement d'un while(1) qui s'occupera (dans le programme final) de récupérer un code IR.
    Citation Envoyé par HULK28 Voir le message
    Pour commander un servo il faut fixer une periode puis utiliser le module compare de CCPx.

    On joue ensuite sur un offset qui reglera le ton dans cette periode, lorsque le match est realise avec le timer la sortie est mise a zero, vous avez ainsi votre impulsion.

    Regardez la datasheet de votre PIC la procedure est parfaitement documentee (Mode Compare module CCPx).
    Le problème est que le PIC 18F452 ne possède que deux modules Compare/PWM et j'utilise déjà ces deux en PWM pour la turbine et le moteur arrière qui fait avancer l'appareil.
    Je peux cependant essayer de faire en sorte de libérer une des deux PWM.
    Je n'ai pas bien compris le principe du "compare CCP". N'ayant que peu de bases en électronique, je ne comprends pas tout les registres qui sont indiqué dans la doc de mon PIC.
    Auriez-vous un exemple de code sur lequel je pourrais me baser pour comprendre l'utilisation du compare avec un timer ?

  16. #12
    invite03481543

    Re : [MikroC] interruption bloque le programme

    Ici vous trouverez un exemple et des explications claires:

    http://angeliz.free.fr/langagec/howto_compare.htm

  17. Publicité
  18. #13
    Forhorse

    Re : [MikroC] interruption bloque le programme

    Citation Envoyé par nono313 Voir le message
    Je pense avoir compris ce que tu veux dire, mais le problème est que je ne peux pas non plus mettre de delay dans le programme principale, celui-ci se composant uniquement d'un while(1) qui s'occupera (dans le programme final) de récupérer un code IR.
    Non tu n'as pas compris.
    Je te parle d'utiliser les interruptions pour generer une temporisation de la durée voulue, qui te permet donc de faire autre chose en attendant.

  19. #14
    nono313

    Re : [MikroC] interruption bloque le programme

    J'ai essayé d'utiliser le programme de l'exemple (en ayant au par avant adapté les nom des registre à MikroC).
    En gardant mon système de base, j'ai réussi à faire fonctionner mon servo avec ce programme :
    Code:
    #define SERVO_MAX  31
    #define SERVO_MIN  13
    #define SERVO_INIT 24
    unsigned long cnt=1;		//cnt=1 pour éviter changement d'état au début		38 init à prescal = 0
    unsigned int servo = SERVO_INIT;
    // Interrupt Handler
    void interrupt()
    {
    
      // Timer2 Interrupt- Freq = 1000000.00 Hz - Period = 0.000001 seconds
      if (PIR1.TMR2IF == 1)          // timer 2 interrupt flag
      {
    	if(cnt == servo || cnt == 0)
    		PORTD = ~PORTD;      // Toggle PORTD
        cnt++;
    	if(cnt == 400)		//15ms
    		cnt = 0;
        PIR1.TMR2IF = 0;     // clears TMR2IF       bit 1 TMR2IF: TMR2 to PR2 Match Interrupt Flag bit
      }
    }
    
    
    
    // code starts here...
    void main()
    {
    
      // setup portb to show the interrupts by blibking LEDs
      TRISD = 0x00;    // PORT is all output...to show the interrupts
      PORTD = 0xFF;       // start with all outputs low
      TRISB = 0xFF;		// entrées
      PORTB = 0;
      TRISC = 0;
      PORTC = 0;
      TRISA = 0;
      PORTA = 0;
    
    //Timer2 Registers Prescaler= 1 - TMR2 PostScaler = 1 - PR2 = 2 - Freq = 1000000.00 Hz - Period = 0.000001 seconds
    T2CON |= 0;        // bits 6-3 Post scaler 1:1 thru 1:16
    T2CON.TMR2ON = 1;  // bit 2 turn timer2 on;
    T2CON.T2CKPS1 = 1; // bits 1-0  Prescaler Rate Select bits
    T2CON.T2CKPS0 = 1;		//prescaler à 4
    PR2 = 2;         // PR2 (Timer2 Match value)
    
    // Interrupt Registers
      INTCON = 0;           // clear the interrpt control register
      INTCON.TMR0IE = 0;        // bit5 TMR0 Overflow Interrupt Enable bit...0 = Disables the TMR0 interrupt
      PIR1.TMR2IF = 0;            // clear timer1 interupt flag TMR1IF
      PIE1.TMR2IE = 1;         // enable Timer2 interrupts
      INTCON.TMR0IF = 0;        // bit2 clear timer 0 interrupt flag
      INTCON.GIE = 1;           // bit7 global interrupt enable
      INTCON.PEIE = 1;          // bit6 Peripheral Interrupt Enable bit...1 = Enables all unmasked peripheral interrupts
    
    
      while(1)  //endless loop
      {  
    	  if(PORTB == 0b00000001)
    		{
          servo = SERVO_INIT;
          delay_ms(100);
        }
    	  if(PORTB == 0b00000010)
    	{
          servo=SERVO_INIT+10;
          delay_ms(100);
        }
        if(PORTB == 0b00000100)
    		{
          servo=SERVO_INIT-10;
          delay_ms(100);
        }
        PORTA = servo;
        PORTC=servo;
      }
    }
    Maintenant je vais commencer un autre programme pour commander une turbine brushless avec un variateur, et je ne sais pas du tout comment le faire fonctionner. Peut être avec une simple PWM ?

  20. #15
    nono313

    Re : [MikroC] interruption bloque le programme

    Dans ce cas, il faudrait utiliser deux timer : un pour le temps du signal envoyé (Ton) et un pour la période total, le premier ayant une fréquence plus élevé que le second ?

  21. #16
    invite03481543

    Re : [MikroC] interruption bloque le programme

    Vous disposez de 3 timers (timer0, timer1 et timer2), donc l'un (timer1) pour le servo et utilisez timer2 par exemple pour votre commande de moteur.
    Dernière modification par HULK28 ; 13/02/2011 à 01h04.

  22. #17
    MorpheusPic

    Re : [MikroC] interruption bloque le programme

    salut voila un code que je suis en train de faire pour creer une PWM supplementaire

    c'est a metre dans un timer, c'est en assembleur ,et ce n'est pas optimiser mais c'est fonctionnel si sa peut te donner une idée..

    Code:
    ;*****************************************************************************
    ;                     INTERRUPTION TIMER 0                                   *
    ;*****************************************************************************
    inttmr0
    
    	    bcf		INTCON,2	         ; effacer flag interrupt      
    
    		incf	pwm3_cmpt,f
    	 	btfsc	STATUS,0
            incf	pwm3_cmpth,f
            
    		movff	pwm3_periode,WREG
    		cpfseq	pwm3_cmpt
    		Return
    		movff	pwm3_periodeh,WREG
    		cpfseq	pwm3_cmpth
    	 	Return
    	 	clrf  	pwm3_cmpt
    	 	clrf	pwm3_cmpth
    	 	
    	 	
    	 	
    		movff	pwm3_cmpt2,WREG
    		cpfseq	pwm3
    		GoTo 	suite_pwm3
    		movff	pwm3_cmpt2h,WREG
    		cpfseq	pwm3h
    		GoTo 	suite_pwm3
    		bcf		pwm3_out
    suite_pwm3	 	
    	 	incf	pwm3_cmpt2,f
            btfsc	STATUS,0
            incf	pwm3_cmpt2h,f
    	 	btfss	pwm3_cmpt2h,2
    	 	Return	 	  	
    	 	bsf     pwm3_out
    	 	clrf  	pwm3_cmpt2
    	 	clrf	pwm3_cmpt2h
    	 	Return
    pwm3_cmpt doit etre en 16 bits (word)
    pwm3_periode est la periode du pwm3 en 16 bits aussi
    pwm3 est ton rapport cyclique de 0 a 1024 soit 10 bits
    pwm3_out est ta pin de sortie a metre en sortie

    a adapter a ta sauce

  23. #18
    nono313

    Re : [MikroC] interruption bloque le programme

    Voila ce que j'obtiens en utilisant 2 Timer, est-ce que vous pensez que cela devrait fonctionner ?
    Code:
    #define SERVO_MAX  31
    #define SERVO_MIN  13
    #define SERVO_INIT 24
    unsigned long cnt=0, cnt1=0;;		//cnt=1 pour éviter changement d'état au début		38 init à prescal = 0
    unsigned int servo = SERVO_INIT;
    // Interrupt Handler
    void interrupt()
    {
    
      // Timer2 Interrupt- Freq = 1000000.00 Hz - Period = 0.000001 seconds
      if (PIR1.TMR2IF == 1)          // timer 2 interrupt flag
      {
    	if(cnt == 0)
    		PIE1.TMR1IE = 1;	//activer Timer1
        cnt++;
    	if(cnt == 25)		//15ms
    	{	
    		cnt = 0;
    		cnt1 = 0;
    	}
           cnt1++;
        PIR1.TMR2IF = 0;     // clears TMR2IF       bit 1 TMR2IF: TMR2 to PR2 Match Interrupt Flag bit
      }
      if(PIR1.TMR1IF == 1)
      {  
    	if(cnt1 == 0)
    		PORTD = 0xFF;
    	if(cnt1 == SERVO_INIT)
    	{
    		PORTD = 0;
    		PIE1.TMR1IE = 0;
    	}
    	 PIR1.TMR1IF = 0;  
      }
    }
    
    
    
    // code starts here...
    void main()
    {
    
      // setup portb to show the interrupts by blibking LEDs
      TRISD = 0x00;    // PORT is all output...to show the interrupts
      PORTD = 0xFF;       // start with all outputs low
      TRISB = 0xFF;		// entrées
      PORTB = 0;
      TRISC = 0;
      PORTC = 0;
      TRISA = 0;
     // ADCON1=
      PORTA = 0;
    
    //Timer1		PETIT
    T1CON |= 0;        // bits 6-3 Post scaler 1:1 thru 1:16
    T1CON.TMR1ON = ;  // bit 2 turn timer2 on;
    T1CON.T1CKPS1 = 0; // bits 1-0  Prescaler Rate Select bits
    T1CON.T1CKPS0 = 0;		//prescaler à 4
    PR1 = 2;         // PR2 (Timer2 Match value)
    
    //Timer2 		GRAND
    T2CON |= 0;        // bits 6-3 Post scaler 1:1 thru 1:16
    T2CON.TMR2ON = 1;  // bit 2 turn timer2 on;
    T2CON.T2CKPS1 = 1; // bits 1-0  Prescaler Rate Select bits
    T2CON.T2CKPS0 = 1;		//prescaler à 4
    T2CON.TTOUTPS0 =1;		//postscaller
    T2CON.TTOUTPS1 =1;
    T2CON.TTOUTPS2 =1;
    T2CON.TTOUTPS3 =1;
    PR2 = 2;         // PR2 (Timer2 Match value)
    
    // Interrupt Registers
      INTCON = 0;           // clear the interrpt control register
      INTCON.TMR0IE = 0;        // bit5 TMR0 Overflow Interrupt Enable bit...0 = Disables the TMR0 interrupt
      PIR1.TMR1IF = 0;            // clear timer1 interupt flag TMR1IF
      PIE1.TMR1IE = 0;         // enable Timer1 interrupts
      PIR1.TMR2IF = 0;            // clear timer2 interupt flag TMR1IF
      PIE1.TMR2IE = 1;         // enable Timer2 interrupts
      INTCON.TMR0IF = 0;        // bit2 clear timer 0 interrupt flag
      INTCON.GIE = 1;           // bit7 global interrupt enable
      INTCON.PEIE = 1;          // bit6 Peripheral Interrupt Enable bit...1 = Enables all unmasked peripheral interrupts
    
    
      while(1)  //endless loop
      {  
    	  if(PORTB == 0b00000001)
    		{
          servo = SERVO_INIT;
          delay_ms(100);
        }
    	  if(PORTB == 0b00000010)
    	{
          servo=SERVO_INIT+10;
          delay_ms(100);
        }
        if(PORTB == 0b00000100)
    		{
          servo=SERVO_INIT-10;
          delay_ms(100);
        }
        PORTA = servo;
        PORTC=servo;
      }
    }
    Sinon je pense rester sur le code précédent, qui fonctionnait, bien qu'il ne soit pas "optimisé".

  24. Publicité

Discussions similaires

  1. interruption sur MikroC
    Par Pilou81 dans le forum Électronique
    Réponses: 3
    Dernier message: 04/05/2010, 22h36
  2. {MikroC} Besoin d'aide pour petit programme
    Par HeadInTheSky dans le forum Électronique
    Réponses: 4
    Dernier message: 09/02/2010, 10h00
  3. Prob mikroC I2C et programme
    Par lovechoco dans le forum Électronique
    Réponses: 0
    Dernier message: 02/11/2009, 18h53
  4. aide programme c sur MIKROC
    Par coeur noire dans le forum Électronique
    Réponses: 31
    Dernier message: 02/05/2009, 19h30
Découvrez nos comparatifs produits sur l'informatique et les technologies.