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 ---
- 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 ---
Modérateur : Jérémy
Probléme avec l'oscilalteur à 31Khz
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
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 !
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
Merci à vous
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
Merci à vous
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Probléme avec l'oscilalteur à 31Khz
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.
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- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
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
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
Probléme avec l'oscilalteur à 31Khz
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
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 ????
voici une partie de mon programme test
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 !
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 ????
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.
Probléme avec l'oscilalteur à 31Khz
Probléme avec l'oscilalteur à 31Khz
-
Jérémy
Administrateur du site- Messages : 2725
- Âge : 45
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
La vérification de l'OSC est bonne .
Sortie de Fosc/4 sur la Broche RA4 .
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.
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 ?
Sortie de Fosc/4 sur la Broche RA4 .
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 ?
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Probléme avec l'oscilalteur à 31Khz
Bonjour Jérémy, satinas, et tout le forum,
c'est nouveau ça
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
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.
Sinon une petite led qui s'allume quand tu arrives au nombre d'interruption souhaité, c'est une idée.
A+
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 .
c'est nouveau ça
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
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.
Sinon une petite led qui s'allume quand tu arrives au nombre d'interruption souhaité, c'est une idée.
A+
Probléme avec l'oscilalteur à 31Khz
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.
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.
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 98 invités