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
Timer et Interruption-On-Change
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 44
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Bonjour à tous,
je vous soumet quelque chose que je n'explique pas encore !
Je souhaite synchroniser un signal avec un timer pour pouvoir à termes modifier le rapport cyclique.
La synchronisation s'effectue sur le secteur soit un signal 230V/50Hz .
Après une mise en forme HARD du signal secteur, j'obtiens donc des impulsions toutes les 10ms (100hz).
Ces impulsions sont tirées au 3V3 pour une pull-up de 10k.
Elles viennent attaquées la broche RA3 de mon PIC .( DS en haut du post)
Cette broche RA3 ne peut être qu'une entrée. Elle est également la PIN MCLR du PIC, j'ai donc désactivé cette fonction bien entendu, sinon le PIC redémarrerait sans cesse !
J'ai donc configurée celle-ci pour recevoir une Interrupt-On-Change(IOC) sur un front montant.
Mon idée est la suivante:
A chaque front montant détecté par interruption, j'active une sortie (RA2) pour un temps donné .
Pour mes tests ce temps n'est pas variable.
Je l'ai fixé à 30 boucles de 100µS soit 3ms
Au bout de ces 3ms j’éteins ma sortie.
Voici ce que j'obtiens en sortie à l'oscilloscope
j'ai, aléatoirement, des pulses qui dure plus longtemps. que les 3ms attendu. Les pulses sont soient de 3.2ms ( grossomodo) soit de 4.5ms( grossomodo).
Comment expliquer les pulses de 4.5ms ?
Je vous mets partiellement le code pour vous simplifier la chose. y'a pas grand chose de plus si ce n'est la partie Radio UART.
Merci à tous
je vous soumet quelque chose que je n'explique pas encore !
Je souhaite synchroniser un signal avec un timer pour pouvoir à termes modifier le rapport cyclique.
La synchronisation s'effectue sur le secteur soit un signal 230V/50Hz .
Après une mise en forme HARD du signal secteur, j'obtiens donc des impulsions toutes les 10ms (100hz).
Ces impulsions sont tirées au 3V3 pour une pull-up de 10k.
Elles viennent attaquées la broche RA3 de mon PIC .( DS en haut du post)
Cette broche RA3 ne peut être qu'une entrée. Elle est également la PIN MCLR du PIC, j'ai donc désactivé cette fonction bien entendu, sinon le PIC redémarrerait sans cesse !
J'ai donc configurée celle-ci pour recevoir une Interrupt-On-Change(IOC) sur un front montant.
Mon idée est la suivante:
A chaque front montant détecté par interruption, j'active une sortie (RA2) pour un temps donné .
Pour mes tests ce temps n'est pas variable.
Je l'ai fixé à 30 boucles de 100µS soit 3ms
Au bout de ces 3ms j’éteins ma sortie.
Voici ce que j'obtiens en sortie à l'oscilloscope
j'ai, aléatoirement, des pulses qui dure plus longtemps. que les 3ms attendu. Les pulses sont soient de 3.2ms ( grossomodo) soit de 4.5ms( grossomodo).
Comment expliquer les pulses de 4.5ms ?
Je vous mets partiellement le code pour vous simplifier la chose. y'a pas grand chose de plus si ce n'est la partie Radio UART.
Code : Tout sélectionner
//############################## VARIABLES ################################################
unsigned int i=0, Temps_ON;
bit Etat_Lampe;
bit direction_variation;
bit long_press;
//-------- Dans les intteruptions
volatile bit F_appui_bref;
volatile bit F_appui_long;
volatile char F_Attente_300ms;
unsigned int Compteur_100us = 0, Compteur_100ms = 0;
unsigned char Valeur;
//-------- UART
unsigned char tmp, Time_out, RSSI ;
//#################################################################################################
//----------------------- INTERRUPTION -----------------------------
void interrupt(){
//------------------ IOC ------------------------
if (IOCIF_bit)
{
IOCAF = 0; // RAZ des interruptions
TMR0 = 56; // je RAZ le timer a chaque activation
Compteur_100us = 0; //car on ne sait pas exactemetn quand il s'est arreté
TMR0IF_bit = 0 ;
Pulse = 1; // J'active la sortie
TMR0IE_bit = 1; // J'active la tempo pour le temps_ON
}
//------------------ TIMER 0 : 100µs ------------------------
if (TMR0IF_bit){
TMR0IF_bit = 0;
TMR0 = 56;
Compteur_100us++;
if (Compteur_100us >= Temps_ON-1)
{
Compteur_100us = 0;
Pulse = 0;
TMR0IE_bit = 0;
}
}
}
/*#################################################################################################
################################ MAIN #######################################
#################################################################################################*/
void main(){
ANSELA = 0b00000000; // Lecture analogique tout en OFF
TRISA.B1 = 1; // RA1 en entrée(BP)
TRISA.B0 = 0; // LED_orange en sortie
TRISA.B2 = 0; // Pulse en sortie
OPTION_REG.B7 = 0; // Active les pull up individuelles
WPUA = 0b00000010; // Active les pull up sur RA1 pour BP
RXDTSEL_bit = 1; // RX_UArt sur RA5
TXCKSEL_bit = 1; // TX_Uart sur RA4
// ----- OSCILLATEUR
OSCCON = 0b01110010; // réglage de l'Oscillateur à 8Mhz (P.53)
//------------ Initialisation UART ----------
UART1_Init(115200);
delay_ms(10);
TRISA.B0 = 0; // LED_orange en sortie
//------------ IOC ----------
IOCAP = 0b00001000; // front montant sur RA3
IOCIE_bit = 0 ; // Interrupt-on-Change Enable bit
//------------ TIMER 1 : 100uS ---------------
T1CON = 0x21;
TMR1IF_bit = 0;
TMR1H = 0x3C;
TMR1L = 0xB0;
TMR1IE_bit = 0;
//------------ TIMER 0 : 10mS ---------------
OPTION_REG = 0x08;
TMR0 = 56;
TMR0IE_bit = 0;
//------------ Interruption ----------
PEIE_bit = 1;
RCIE_bit = 1;
RCIF_bit = 0;
GIE_bit = 1;
Etat_Lampe = Off;
Pulse = 0 ;
Temps_ON = 30;
F_appui_bref = 0;
F_appui_long = 0;
/*#################################################################################################
################################ BOUCLE PRINCIPALE #######################################
#################################################################################################*/
while (1){
if ( F_appui_bref == 1)
{
F_appui_bref = 0;
Etat_Lampe = ~Etat_Lampe;
if (Etat_Lampe == On)
{
IOCIE_bit = 1;
}
else
{
IOCIE_bit = 0;
}
}
if ( BP_PIC == 0) asm reset;
}
}
Merci à tous
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Timer et Interruption-On-Change
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 44
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Bon....
La bonne nouvelle , j'ai trouvé par chance pourquoi il y a un décalage.
La mauvaise nouvelle c'est que je ne sais pas comment le résoudre.
Au lieu de faire des boucles de 100µs que je compte 30 fois , donc je multiplie l'imprécision par 30. Je voulais faire uen temporisation directement de 3ms avec le timer 0. sauf que je me suis trompe dans le prescaler et mon timer est de 100µs.
Voila ce que j'obtiens à l'oscillo.
On voit clairement que j'ai un déclenchement sur un front descendant de temps en temps!
cela me ramène bien à mes 1.2ms de trop sur certaines impulsions.
La question comment est ce possible que je détecte une IOC sur un front descendant alors que celle-ci est configurée sur un front montant ? des rebonds ?
Bon je me dis OK je vais traiter l'info sur un front descendant, et ben bingo le même phénomène.
Ai-je loupé ma config IOC , probléme de timing ? dois je redressser la courbe de detection ? dois je la filtrée ?
La bonne nouvelle , j'ai trouvé par chance pourquoi il y a un décalage.
La mauvaise nouvelle c'est que je ne sais pas comment le résoudre.
Au lieu de faire des boucles de 100µs que je compte 30 fois , donc je multiplie l'imprécision par 30. Je voulais faire uen temporisation directement de 3ms avec le timer 0. sauf que je me suis trompe dans le prescaler et mon timer est de 100µs.
Voila ce que j'obtiens à l'oscillo.
On voit clairement que j'ai un déclenchement sur un front descendant de temps en temps!
cela me ramène bien à mes 1.2ms de trop sur certaines impulsions.
La question comment est ce possible que je détecte une IOC sur un front descendant alors que celle-ci est configurée sur un front montant ? des rebonds ?
Bon je me dis OK je vais traiter l'info sur un front descendant, et ben bingo le même phénomène.
Ai-je loupé ma config IOC , probléme de timing ? dois je redressser la courbe de detection ? dois je la filtrée ?
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Timer et Interruption-On-Change
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 44
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Je continue mes investigations......
j'ai augmenter la résistance de tirage au 3V3 de 10K à 33K pour augmenter la pente de détection et raccourcir sa largeur afin d'eviter les rebonds.
Je suis passer à 1ms de largeur d'impulsions au lieu de 1.5ms.
cela n'as pas changer grand chose j'ai toujours des erreurs.
Chose plus perturbantes qui m'oriente du coup vers le HARD.
J'ai modifié le code ainsi.
Quand je détecte un front montant, j’éteins les interruptions sur IOC ( donc je suis censé ne pas en recevoir). J'active ma sortie et lance ma temporisation.
A la fin de ma tempo, je mets à zéro ma sortie, j'éteins mon timer et je réactive mes interruptions SUR IOC.
Et be surprise, je reçois quand même des interruptions sur IOC alors que l'INT est éteinte !
j'ai augmenter la résistance de tirage au 3V3 de 10K à 33K pour augmenter la pente de détection et raccourcir sa largeur afin d'eviter les rebonds.
Je suis passer à 1ms de largeur d'impulsions au lieu de 1.5ms.
cela n'as pas changer grand chose j'ai toujours des erreurs.
Chose plus perturbantes qui m'oriente du coup vers le HARD.
J'ai modifié le code ainsi.
Quand je détecte un front montant, j’éteins les interruptions sur IOC ( donc je suis censé ne pas en recevoir). J'active ma sortie et lance ma temporisation.
A la fin de ma tempo, je mets à zéro ma sortie, j'éteins mon timer et je réactive mes interruptions SUR IOC.
Code : Tout sélectionner
void interrupt(){
//------------------ IOC ------------------------
if (IOCIF_bit)
{
if (IOCAF3_bit)
{
IOCAF = 0; // RAZ des interruptions
IOCIE_bit = 0;
TMR0 = 68; // je RAZ le timer a chaque activation
TMR0IF_bit = 0 ;
Pulse = 1; // J'active la sortie
TMR0IE_bit = 1; // J'active la tempo pour le temps_ON
}
}
//------------------ TIMER 0 ------------------------
if (TMR0IF_bit){
TMR0IF_bit = 0;
TMR0 = 68;
Pulse = 0;
TMR0IE_bit = 0;
IOCIE_bit = 1;
}
Et be surprise, je reçois quand même des interruptions sur IOC alors que l'INT est éteinte !
Timer et Interruption-On-Change
Bonjour Jérémy,
Les F_appui_xxx n'ont pas à être volatile car elles n'apparaissent que dans le main.
Par contre Compteur_100us je la mettrais en volatile, comme toute variable globale figurant dans l'ISR.
Pour le dernier message, l'int IOC n'est pas éteinte car tu fais IOCIE_bit = 1 à la fin de la tempo.
Après pour les problèmes de déclenchement, teste ton programme avec un autre signal, tu as un générateur de fonction ?
Les F_appui_xxx n'ont pas à être volatile car elles n'apparaissent que dans le main.
Par contre Compteur_100us je la mettrais en volatile, comme toute variable globale figurant dans l'ISR.
Pour le dernier message, l'int IOC n'est pas éteinte car tu fais IOCIE_bit = 1 à la fin de la tempo.
Après pour les problèmes de déclenchement, teste ton programme avec un autre signal, tu as un générateur de fonction ?
Timer et Interruption-On-Change
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 44
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Merci satinas pour ta réponse.
Les F_appui_xxx sont dans l'interrptuion UART que je n'ai pas dans le code pour le simplifier. Cette partie réception UART fonctionne parfaitement.
Je n'ai pas mis Compteur_100us en volatile car cette variable n'est utilisé que dans l'ISR et n'est pas modifié ailleurs. Mais t uas raison ca ne mange pas de pain de la mettre aussi en volatile !
Oui je rallume à la fin de la tempo, mais je l'éteins quand je reçois une IOC .
en gros quand je détecte une IOC, je peux plus en détecter jusqu’à la fin de la tempo qui la rallume.
Oui mon oscilloscope peut générer un signal ! a quoi penses tu ?
Je précise que les déclencher son bien précis, c'est pourquoi j'ai un doute sur le parasitage. Si c'était des parasites, les erreurs se produiraient n'importe quand ? Hors la c'est vraiment a chaque détection de zéro en front montant a 1.17V et en descendant à 1.0V , c'est vraiment précis
Les F_appui_xxx sont dans l'interrptuion UART que je n'ai pas dans le code pour le simplifier. Cette partie réception UART fonctionne parfaitement.
Je n'ai pas mis Compteur_100us en volatile car cette variable n'est utilisé que dans l'ISR et n'est pas modifié ailleurs. Mais t uas raison ca ne mange pas de pain de la mettre aussi en volatile !
satinas a écrit :Source du message Pour le dernier message, l'int IOC n'est pas éteinte car tu fais IOCIE_bit = 1 à la fin de la tempo.
Oui je rallume à la fin de la tempo, mais je l'éteins quand je reçois une IOC .
en gros quand je détecte une IOC, je peux plus en détecter jusqu’à la fin de la tempo qui la rallume.
Oui mon oscilloscope peut générer un signal ! a quoi penses tu ?
Je précise que les déclencher son bien précis, c'est pourquoi j'ai un doute sur le parasitage. Si c'était des parasites, les erreurs se produiraient n'importe quand ? Hors la c'est vraiment a chaque détection de zéro en front montant a 1.17V et en descendant à 1.0V , c'est vraiment précis
Timer et Interruption-On-Change
Si il déclenche sur le front descendant de façon systématique, et si IOCAN est bien à 0, cela pose question.
Un générateur de fonctions peut créer des signaux de toutes formes, si ton oscillo en possède un c'est bien, cela permettrait de tester de façon plus complète. En fait c'est plutôt un générateur d'impulsions qu'il faut :)
Un générateur de fonctions peut créer des signaux de toutes formes, si ton oscillo en possède un c'est bien, cela permettrait de tester de façon plus complète. En fait c'est plutôt un générateur d'impulsions qu'il faut :)
Timer et Interruption-On-Change
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 44
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Ok.
Pour le moment les IOC se déclenche toujours sur un front montant , et c'est nickel. par contre de temps en temps il y a un déclenchement sur un front descendant, ce n'est pas systématique ....... C'est ce qui met le flou. Par contre je pense que c'est bien sur un front descendant car c'est très précis a chaque fois qu'il y en a un.
Oui mon oscillo peut faire des faire d'impulsions maximum de 2V d'amplitude j'espere que cela sera suffisant .
Pour le moment les IOC se déclenche toujours sur un front montant , et c'est nickel. par contre de temps en temps il y a un déclenchement sur un front descendant, ce n'est pas systématique ....... C'est ce qui met le flou. Par contre je pense que c'est bien sur un front descendant car c'est très précis a chaque fois qu'il y en a un.
Oui mon oscillo peut faire des faire d'impulsions maximum de 2V d'amplitude j'espere que cela sera suffisant .
Timer et Interruption-On-Change
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 44
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
Fin du test.
Alors on avance un peu mais c'est pas folichon.
Quand je substitue mon signal de détection "zéro-cross" par une impulsion parfaite de 2V . J'entends par impulsion parfaite des fronts bien droits comme sur l'image ci dessus
Aucun problème et aucune erreur. le signal est conforme
par contre quand je modifie l'impulsion générée par une autre plus ressemblante c'est à dire avec des pentes moins droites.
j'ai un nombre d'erreur conséquent !
C'est quand même incroyable qu'il me déclenche une IOC alors que la courbe est en phase descendante !
En modifiant l'impulsion comme cela , c'est à dire une éloignant la phase montante de la phase descendante j'ai quasiment aucune erreur , mais quelques unes tout de même.
Alors on avance un peu mais c'est pas folichon.
Quand je substitue mon signal de détection "zéro-cross" par une impulsion parfaite de 2V . J'entends par impulsion parfaite des fronts bien droits comme sur l'image ci dessus
Aucun problème et aucune erreur. le signal est conforme
par contre quand je modifie l'impulsion générée par une autre plus ressemblante c'est à dire avec des pentes moins droites.
j'ai un nombre d'erreur conséquent !
C'est quand même incroyable qu'il me déclenche une IOC alors que la courbe est en phase descendante !
En modifiant l'impulsion comme cela , c'est à dire une éloignant la phase montante de la phase descendante j'ai quasiment aucune erreur , mais quelques unes tout de même.
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Timer et Interruption-On-Change
Timer et Interruption-On-Change
-
Jérémy
Administrateur du site- Messages : 2722
- Âge : 44
- Enregistré en : juillet 2015
- Localisation : Dans le sud
- Contact :
satinas a écrit :Source du message Nombre max de déclenchements pour une impulsion d'entrée ?
Je ne suis pas sûr d'avoir compris ta question.
Une impulsion d'entrée = un déclenchement pour une durée déterminée
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 46 invités