Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

Probléme avec l'oscilalteur à 31Khz
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#1 Message par Jérémy » sam. 13 avr. 2019 13:10 lien vers la Data-Sheet : Cliquez ici

Bonjour à tous,

Afin de diminuer la consommation sur un projet avec des leds, je souhaite baisser au maximum la fréquence de mon PIC .

Mais malheureusement mes résultats ne sont pas ceux escomptés !
Il faut que je trouve par test le bon compromis entre fréquence et consommation.

Le programme est on ne peut plus simple . je règle mon oscillateur interne sur 31Khz. ( page 61 de la DS).
d’après mes calculs 31Khz me donne une instruction toutes les 129µS.

ensuite je règle mon timer 1 avec le clock source à Fosc . préscaler à 1:1
Donc avec 8 coups d'horloge de 129µs, je devrais obtenir un état haut de 8x129=1.032 ms
Pour obtenir 8 coups d’horloges je règle les registres du timer1 sur 65536-8 = 65528 = 0xFFF8 ;

Voici mon programme raccourci !

Code : Tout sélectionner

//###############################################################################################
void Interrupt(){
  if (
TMR1IF_bit){

     
PWM = !PWM;       // J'inverse ma sortie

     
TMR1H      0xFF;
     
TMR1L      0xF8;
     
TMR1IF_bit 0;
  }
}

//###############################################################################################
void main() {
 
ANSELA 0b00000100;    // RA2 en analogique
 
TRISA  0b11001101;    // Definition In/Out

 
On_Off 1;             // J'allume l'auto-maintien

 
OSCCON 0b00000010;    // réglage de l'Oscillateur à 31Khz (P.61)
 
OPTION_REG.B7 0;       // Active les pull up individuelles
 
WPUA 0b00001000;      // Active les pull up sur RA3 pour BP

 //----- Initialisation timer 1 pour PWM :
 
T1CON      0b01000001;   //  Source=Fosc; presclaer à 1:1; TMR1_ON à 1 ;  (P.171)
 
TMR1IF_bit 0;
 
TMR1H      0xFF;
 
TMR1L      0xF8;
 
TMR1IE_bit 1;
 
INTCON     0xC0;         // GIE & PEIE activés

//###############################################################################################
while(1){

 }


Je ne comprends pas pourquoi je n'ai pas environ 1ms d'état haut et bas ?
J'ai essayé de nombreuses configurations sans résultat notables.
Avec d'autres valeurs d'oscillateur ( de 500KhZ à 8Mhz ), pas de probléme, les temps correspondent parfaitement mais en dessous de 500Khz ça bug .

Avez vous une idée ? quelques chose doit m'échapper mais je vois pas quoi .
Voici une capture de ma sortie PWM qui allume mes leds ! On voit que l'état haut dur 2.356ms au lieu des 8x129=1.0.32 ms

Sans titre.jpg


Merci à vous
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Probléme avec l'oscilalteur à 31Khz
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#2 Message par satinas » sam. 13 avr. 2019 14:48 lien vers la Data-Sheet : Cliquez ici

Bonjour Jeremy

Tu as programmé ton timer pour démarrer la routine d'interruption toutes les 8*129us = 1ms
L'exécution de cette routine dure au moins une dizaine de cycles, soit 10*129 = 1,3 ms
Là, il y a un problème, entraînant soit du retard, soit des pertes d'interruptions.
En remettant à zéro le flag TMR1IF_bit en fin de routine, tu annules les demandes d'interruption qui se sont redéclenchées en cours de routine.

Les interruptions mangent du temps cpu, il faut en tenir compte, d'autant plus qu'elles consomment 4 cycles rien que pour l'appel et le return. Il faut faire en sorte qu'elles aient le temps de s'exécuter, et laissent respirer le programme principal.

En augmentant Fosc, la routine est plus rapide, et a le temps de se terminer avant de remettre ça.

Probléme avec l'oscilalteur à 31Khz
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#3 Message par Jérémy » sam. 13 avr. 2019 15:13 lien vers la Data-Sheet : Cliquez ici

Effectivement, tu as certainement raison .

En gros mon oscillateur est lent et mon interruption de pwm trop rapide !

Je peux donc raisonnablement penser, qu'en augmentant la fréquence de mon PWM, je laisserais plus de temps à mon interruption !
Je vais essayer ta piste .

Merci
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Probléme avec l'oscilalteur à 31Khz
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#4 Message par Jérémy » sam. 13 avr. 2019 16:27 lien vers la Data-Sheet : Cliquez ici

Bon ben j'y arrive pas !

En mettant 100 instructions pour la recharge du timer1, soit 129 * 100 = 12.9ms ! soit une période théorique de 25.8ms j'obtiens ceci :

soit 9.63ms pour une période ????

Sans titre.jpg



voici une partie de mon programme test

Code : Tout sélectionner



//###############################################################################################
void Interrupt(){
  if (TMR1IF_bit){
  
    TMR1H      
= 0xFF;
    TMR1L      = 0x9C;
    TMR1IF_bit = 0;
    
    PWM 
= !PWM;   // J'inverse ma sortie
  }
}

//###############################################################################################
void main() {
 ANSELA = 0b00000100;    // RA2 en analogique
 TRISA  = 0b11001101;    // Definition In/Out

 On_Off = 1;             // J'allume l'auto-maintien
 OPTION_REG.B7 = 0;      // Active les pull up individuelles
 WPUA = 0b00001000;      // Active les pull up sur RA3 pour BP

 // ----- OSCILLATEUR
 OSCCON = 0b00000010;    // réglage de l'Oscillateur à 31Khz (P.61)
  
  
 
//----- Initialisation timer 1 pour PWM :
 T1CON      = 0b01000001;   //  Source=Fosc; presclaer à 1:1; TMR1_ON à 1 ;  (P.171)
 TMR1IF_bit = 0;
 TMR1H      = 0xFF;
 TMR1L      = 0x9C;
 TMR1IE_bit = 1;
 INTCON     = 0xC0;         // GIE & PEIE activés

//###############################################################################################
while(1){
  asm nop;
 }
}


L'idée étant d'obtenir une fréquence quand même supérieur à 50Hertz pour ne pas voir le clignotement des LED. Une fréquence de 100Hertz me conviendrais parfaitement !
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Probléme avec l'oscilalteur à 31Khz
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#5 Message par satinas » sam. 13 avr. 2019 17:00 lien vers la Data-Sheet : Cliquez ici

Tu peux déjà vérifier la valeur de l'horloge avec le bit CLKOUTEN = 0 dans la config hardware du pic, pour sortir FOSC/4 sur la pin CLKOUT.
Tu utilises quelle horloge pour le timer, FOSC ou FOSC/4 ?
Ce serait pas T1CON = 0b00000001;

Probléme avec l'oscilalteur à 31Khz
Jérémy
Administrateur du site
Administrateur du site
Messages : 2722
Âge : 44
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#6 Message par Jérémy » sam. 13 avr. 2019 18:43 lien vers la Data-Sheet : Cliquez ici

La vérification de l'OSC est bonne .

Sortie de Fosc/4 sur la Broche RA4 .
Sans titre.jpg


Impeccable j'ai bien mes 129µs pour un cycle d'horloge.
Je précharge donc mon timer1 avec la valeur 65436 pour faire 100 cycles d'horloges.
je devrais donc avoir 100*129=12.9ms pour un état haut et un état bas sur la sortie pwm.


Code : Tout sélectionner

//###############################################################################################
void Interrupt(){
  if (TMR1IF_bit){
  
    TMR1H      
= 0xFF;
    TMR1L      = 0x9C;    // 65436 soit 100 cycles
    TMR1IF_bit = 0;
    
    PWM 
= !PWM;   // J'inverse ma sortie
  }
}

//###############################################################################################
void main() {
 ANSELA = 0b00000100;    // RA2 en analogique
 TRISA  = 0b11001101;    // Definition In/Out

 On_Off = 1;             // J'allume l'auto-maintien

 OPTION_REG.B7 = 0;      // Active les pull up individuelles
 WPUA = 0b00001000;      // Active les pull up sur RA3 pour BP

 // ----- OSCILLATEUR
 OSCCON = 0b00000010;    // réglage de l'Oscillateur à 31Khz (P.61)

 //----- Initialisation timer 1 pour PWM :
 T1CON      = 0b00000001;   //  Source=Fosc/4; presclaer à 1:1; TMR1_ON à 1 ;  (P.171)
 TMR1IF_bit = 0;
 TMR1H      = 0xFF;
 TMR1L      = 0x9C;
 TMR1IE_bit = 1;
 INTCON     = 0xC0;         // GIE & PEIE activés

//###############################################################################################
while(1){
  asm nop;
 }
}


Mais je me retrouve avec 14.57ms ? est ce qu'un si gros écart est normal ? comme le dis satinas , si l’interruption me prends une dizaine de cycles, ça devrait tomber bien au final .

est il possible de savoir exactement le nombre de cycles de mon interruption ?


Sans titre2.jpg
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
C'est en faisant des erreurs, que l'on apprend le mieux !!!

Probléme avec l'oscilalteur à 31Khz
Temps-x
Avatar de l’utilisateur
Expert
Expert
Messages : 2595
Enregistré en : juillet 2016
Localisation : Terre

#7 Message par Temps-x » sam. 13 avr. 2019 20:46 lien vers la Data-Sheet : Cliquez ici

Bonjour Jérémy, satinas, et tout le forum,

Jérémy a écrit :Source du message Afin de diminuer la consommation sur un projet avec des leds, je souhaite baisser au maximum la fréquence de mon PIC .

:sifflotte: c'est nouveau ça :shock:

Jérémy a écrit :Source du message est il possible de savoir exactement le nombre de cycles de mon interruption ?


Oui, et non, tout dépends le langage que tu pratiques, en assembleur, on peut compter les instructions et les suives sous MPLAB .

On C, on peut suives les instructions, mais pas compter le temps qu'il prenne, car derrière le C, il y a de l'assembleur.

Et on ne peut pas savoir ce qui est écrit dans leurs routines ASM de C :langue:

Maintenant pour ton réglage, je te conseille un réglage par incrémentation de ton timer1, via l'entrée d'une porte numérique.

A raison de 1024 valeur ça te laisse du réglage.

idea ! Sinon une petite led qui s'allume quand tu arrives au nombre d'interruption souhaité, c'est une idée.

A+
:roll: Les requins, c'est comme le langage ASM, c'est le sommet de la chaîne alimentaire. :wink:

Probléme avec l'oscilalteur à 31Khz
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#8 Message par satinas » sam. 13 avr. 2019 21:37 lien vers la Data-Sheet : Cliquez ici

La majorité des instructions consomme 1 cycle, sauf les sauts et les tests.
Voir les pages datasheet 309 et 310 pour la durée d'exécution de chaque instruction.
L'appel de la routine d'interruption dure 2 cycles comme le CALL, et la sortie de la routine 2 cycles aussi, comme le RETURN.
Avec le menu View/assembly de MikroC, tu peux afficher le listing d'assemblage.
Avec le debugger il doit y avoir moyen de compter les cycles, dans la watch clock en bas à droite.


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 38 invités