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
Interrupt On Change sur 18F27K42
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
bonjour,
Ce sujet à un lien avec PORTIER AUdiophone
et aussi L'interruption INTERRUPT-ON-CHANGE
et sur microchip form : Halbees (1-wire slaves) and the curious difference between INT and IOC
* soit on peut traiter la surveillance par Pooling regulier des entrees du PORTA ( exemple via un timer calé à 100mS)
* soit on detourne le programme principal via une interruption concernant le BP actionné.. avec IOC
sur ce PIC on peut affecter n'importe quelle PIN sur cette interruption ..( reservée au portB sur les anciens PIC)
* application HOME : IOC traitement des 4 BP port A
j'ai donc commencé des tests pour la capture d'appui des 4 BP (ABCD) en mode interruption
Interrupt On Change sur front montant ...
au depart ,mes 4 entrees sont au Vss (0V) via un fil strap ..elles ont leur pull-up activée
en ouvrant un strap,je genere un front montant
si je mainteient ouvert le strap pendant <=1sec , je peux voir le changement d'etat sur mon terminal
si<1sec, je ne le vois pas car ma boucle d'ecriture sur terminal est seulement dans le main programme .
Ca se presente bien !
MAISj'ai pu remarqué, en faisant des test sur une breadboard, BP remplacé par un fil qui s'enfiche ,
( J'avoue que ce n'est pas l'ideal !) que certains rebonds pouvaient avoir lieu ..
grace au compteur d'interrupt inséré, incrementé dans l'interrupt elle même
( et la sortie UART ! utilisé comme d'hab. pour debugger ..)) voir resultat terminal
je peux voir 2 interruptions sur 1 seul info mise à 1 .. (compteur s'incremente de 2 au lieu de 1!)
l'interrupt sur front descendant n'est pourtant pas armée !
vu qu'un front de 62nS peut etre détectable .. sans condo sur l'entree PIC (RA6 et RA7)
mais probleme non constaté AVEC condo. sur les entrees RA4 et RA5.
une solution hardware:
un condo de 22nF à 100nF aux bornes du BP ( ou entree PIC) nettoie bien et supprime
ces detections parasites...
il faut peut etre le prévoir ...au cas ou Murphy s'inviterait.
....Il y a TOUJOURS des rebonds mecaniques sur les Interrupteurs.
A cet instant précis , je ne sais pas encore si je peux faire un traitement anti rebond
par software , car le flag d'interruption peut se réarmer DANS l'interruption elle meme !
.. si j'ai bien compris/traduit le texte ci dessous
la solution proposée en asm, ci dessus
serait plutot de ne pas en rater ,que de ne garder que la 1ere interrupt ?
je mets pourtant IOCIE à zero , tant que je n'ai pas recupéré la valeur lue sur le portA ...
A priori je ne devrait pas non plus detecter un front descendant.
init :
l'interrupt :
sortie terminal
schema partiel impliquant les Boutons poussoirs à surveiller via IOC
Ce sujet à un lien avec PORTIER AUdiophone
et aussi L'interruption INTERRUPT-ON-CHANGE
et sur microchip form : Halbees (1-wire slaves) and the curious difference between INT and IOC
* soit on peut traiter la surveillance par Pooling regulier des entrees du PORTA ( exemple via un timer calé à 100mS)
* soit on detourne le programme principal via une interruption concernant le BP actionné.. avec IOC
sur ce PIC on peut affecter n'importe quelle PIN sur cette interruption ..( reservée au portB sur les anciens PIC)
* application HOME : IOC traitement des 4 BP port A
j'ai donc commencé des tests pour la capture d'appui des 4 BP (ABCD) en mode interruption
Interrupt On Change sur front montant ...
au depart ,mes 4 entrees sont au Vss (0V) via un fil strap ..elles ont leur pull-up activée
en ouvrant un strap,je genere un front montant
si je mainteient ouvert le strap pendant <=1sec , je peux voir le changement d'etat sur mon terminal
si<1sec, je ne le vois pas car ma boucle d'ecriture sur terminal est seulement dans le main programme .
Ca se presente bien !
MAISj'ai pu remarqué, en faisant des test sur une breadboard, BP remplacé par un fil qui s'enfiche ,
( J'avoue que ce n'est pas l'ideal !) que certains rebonds pouvaient avoir lieu ..
grace au compteur d'interrupt inséré, incrementé dans l'interrupt elle même
( et la sortie UART ! utilisé comme d'hab. pour debugger ..)) voir resultat terminal
je peux voir 2 interruptions sur 1 seul info mise à 1 .. (compteur s'incremente de 2 au lieu de 1!)
l'interrupt sur front descendant n'est pourtant pas armée !
vu qu'un front de 62nS peut etre détectable .. sans condo sur l'entree PIC (RA6 et RA7)
mais probleme non constaté AVEC condo. sur les entrees RA4 et RA5.
une solution hardware:
un condo de 22nF à 100nF aux bornes du BP ( ou entree PIC) nettoie bien et supprime
ces detections parasites...
il faut peut etre le prévoir ...au cas ou Murphy s'inviterait.
....Il y a TOUJOURS des rebonds mecaniques sur les Interrupteurs.
A cet instant précis , je ne sais pas encore si je peux faire un traitement anti rebond
par software , car le flag d'interruption peut se réarmer DANS l'interruption elle meme !
.. si j'ai bien compris/traduit le texte ci dessous
... DS40001919G-page 286
18.4 Clearing Interrupt Flags
The individual status flags, (IOCAFx, IOCBFx, IOCCFx and IOCEF3 bits),
can be cleared by resetting them to zero.
If another edge is detected during this clearing operation,
the associated status flag will be set at the end of the sequence,
regardless of the value actually being written.
In order to ensure that no detected edge is lost while clearing flags,
only AND operations masking out known changed bits may be performed.
The following sequence is an example of what may be performed.
EXAMPLE 18-1: CLEARING INTERRUPT FLAGS
(PORTA EXAMPLE)
MOVLW 0xff
XORWF IOCAF, W
ANDWF IOCAF, F
la solution proposée en asm, ci dessus
serait plutot de ne pas en rater ,que de ne garder que la 1ere interrupt ?
je mets pourtant IOCIE à zero , tant que je n'ai pas recupéré la valeur lue sur le portA ...
A priori je ne devrait pas non plus detecter un front descendant.
init :
Code : Tout sélectionner
CPrint(" Init IOC sur PORTA RA4 ..RA7 et sur RC4 \r\n");
//1 = ST input used for port reads and interrupt-on-change
INLVLA4=1; INLVLA5=1; INLVLA6=1; INLVLA7=1;
IOCAP4= 1; // Interrupt ON rising edge RA4
IOCAN4= 0; // no interrupt on Falling edge on RA4
IOCAP5= 1; IOCAP6= 1; IOCAP7= 1;
IOCAN5= 0; IOCAN6= 0; IOCAN7= 0;
IOCAF=0;
INLVLC4=1;
IOCCP4= 1; // Interrupt ON rising edge RA4
IOCCN4= 0; // no interrupt on Falling edge on RA4
IOCCF=0;
GIE = 1;
Count_IOCA=0;
Flag_IOCA=0;
Count_IOCC=0;
Flag_IOCC=0;
IOCIF = 0; // drapeau general interrupt
IOCIE= 1; //IOCIE: Interrupt-on-Change Enable bit
l'interrupt :
Code : Tout sélectionner
void __interrupt(irq(IRQ_IOC) ,high_priority) IOC_ISR(void)
{
if ( (IOCIE) && ( IOCIF))
{
if ( (IOCAF4) || (IOCAF5) || (IOCAF6) || (IOCAF7) )
{
Infos_envoi_DTMF=(PORTA & 0xF0) >>4;
Out_EnbDTMF=1; // Enable envoi code DTMF
Flag_IOCA=1;
Count_IOCA++;
IOCAF=0;
}
if(IOCCF4) //Port C
{
Count_IOCC++;
Flag_IOCC=1;
IOCCF=0;
}
}
IOCIF=0;
//pour ne capturer qu'1 seule IT
IOCIE=0;
}
sortie terminal
Init IOC sur PORTA RA4 ..RA7 et sur RC4
Test Interrupt On Change sur RA4..RA7 et sur RC4
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 0 0x 0
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 0 0x 0
A4=1, A5=0, A6=0, A7=0, C4=0
IOC sur PORTA Count_IOCFA= 1 Infos_envoi_DTMF= 1 0x1
A4=1, A5=0, A6=0, A7=0, C4=0 PORTA= 16 Infos_envoi_DTMF= 1 0x 1
A4=1, A5=0, A6=0, A7=0, C4=0 PORTA= 16 Infos_envoi_DTMF= 1 0x 1
A4=1, A5=0, A6=0, A7=0, C4=0 PORTA= 16 Infos_envoi_DTMF= 1 0x 1
A4=1, A5=0, A6=0, A7=0, C4=0 PORTA= 16 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=1, A5=0, A6=0, A7=0, C4=0
IOC sur PORTA Count_IOCFA= 2 Infos_envoi_DTMF= 1 0x1
A4=1, A5=0, A6=0, A7=0, C4=0 PORTA= 16 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=1, A6=0, A7=0, C4=0
IOC sur PORTA Count_IOCFA= 4 Infos_envoi_DTMF= 2 0x2
A4=0, A5=1, A6=0, A7=0, C4=0 PORTA= 32 Infos_envoi_DTMF= 2 0x 2
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 2 0x 2
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 2 0x 2
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 2 0x 2
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 2 0x 2
A4=0, A5=0, A6=1, A7=0, C4=0
IOC sur PORTA Count_IOCFA= 6 Infos_envoi_DTMF= 4 0x4
A4=0, A5=0, A6=1, A7=0, C4=0 PORTA= 64 Infos_envoi_DTMF= 4 0x 4
A4=0, A5=0, A6=0, A7=0, C4=0
IOC sur PORTA Count_IOCFA= 8 Infos_envoi_DTMF= 0 0x0
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 0 0x 0
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 0 0x 0
A4=0, A5=0, A6=0, A7=1, C4=0
IOC sur PORTA Count_IOCFA= 10 Infos_envoi_DTMF= 8 0x8
A4=0, A5=0, A6=0, A7=1, C4=0 PORTA= 128 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=1 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
IOC PORT C4 =0xFF Count_IOCCF= 1
A4=0, A5=0, A6=0, A7=0, C4=1 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
IOC PORT C4 =0xEF Count_IOCCF= 2
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 8 0x 8
A4=1, A5=0, A6=0, A7=0, C4=0
IOC sur PORTA Count_IOCFA= 11 Infos_envoi_DTMF= 1 0x1
A4=1, A5=0, A6=0, A7=0, C4=0 PORTA= 16 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0
IOC sur PORTA Count_IOCFA= 12 Infos_envoi_DTMF= 2 0x2
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 2 0x 2
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 2 0x 2
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 2 0x 2
A4=1, A5=0, A6=0, A7=0, C4=0
IOC sur PORTA Count_IOCFA= 13 Infos_envoi_DTMF= 1 0x1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
A4=0, A5=0, A6=0, A7=0, C4=0 PORTA= 0 Infos_envoi_DTMF= 1 0x 1
schema partiel impliquant les Boutons poussoirs à surveiller via IOC
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Interrupt On Change sur 18F27K42
Bonjour Paul,
Une seule petite remarque d"un point de vue logique.
D'après les paramètres de la fonction interrupt, tu utilises le mode IVT, un vecteur pour chaque type d'interruption, mode activé par MVECEN=1 dans la configuration hardware.
On entre dans interrupt(irq(IRQ_IOC) uniquement si un évènement IOC se produit et si IOCIE est à 1, il n'est donc pas nécessaire de tester le bit IOCIE dans l'ISR, il est forcément à 1.
Une seule petite remarque d"un point de vue logique.
D'après les paramètres de la fonction interrupt, tu utilises le mode IVT, un vecteur pour chaque type d'interruption, mode activé par MVECEN=1 dans la configuration hardware.
On entre dans interrupt(irq(IRQ_IOC) uniquement si un évènement IOC se produit et si IOCIE est à 1, il n'est donc pas nécessaire de tester le bit IOCIE dans l'ISR, il est forcément à 1.
Interrupt On Change sur 18F27K42
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
Bonjour à tous,
mode IVT ..oui
OK,... ça fait Bretelle ET ceinture , c'est une mauvaise habitude prise pour les interrupts multiples..
.. mais qui ne mange pas de pain ( ou alors .des miettes de quelques bytes ou nS )
je le test ,car je le mets à zero dans mon traitement interrupt...
et ce, aussi, pour la compréhension du programme, au cas ou l'interrupt ne se declencherait pas
si le drapeau IOCFmonte .. et que IOC IE n'est pas armé.
Disons que je fais "un noeud à mon mouchoir "
L' IOC IE n'étant ré-armé, plus tard dans le main, qu'apres l'envoi du code DTMF formé.
satinas a écrit :Bonjour Paul,
Une seule petite remarque d"un point de vue logique.
D'après les paramètres de la fonction interrupt, tu utilises le mode IVT, un vecteur pour chaque type d'interruption, mode activé par MVECEN=1 dans la configuration hardware.
On entre dans interrupt(irq(IRQ_IOC) uniquement si un évènement IOC se produit et si IOCIE est à 1,
il n'est donc pas nécessaire de tester le bit IOCIE dans l'ISR, il est forcément à 1.
mode IVT ..oui
OK,... ça fait Bretelle ET ceinture , c'est une mauvaise habitude prise pour les interrupts multiples..
.. mais qui ne mange pas de pain ( ou alors .des miettes de quelques bytes ou nS )
je le test ,car je le mets à zero dans mon traitement interrupt...
et ce, aussi, pour la compréhension du programme, au cas ou l'interrupt ne se declencherait pas
si le drapeau IOCFmonte .. et que IOC IE n'est pas armé.
Disons que je fais "un noeud à mon mouchoir "
L' IOC IE n'étant ré-armé, plus tard dans le main, qu'apres l'envoi du code DTMF formé.
Interrupt On Change sur 18F27K42
C'est pas grave bien sûr, mais cela complique la compréhension de ton code par les autres, on a du mal à s'y retrouver, car on se dit pourquoi il a fait ça, c'est un exemple.
Je pense aussi à la config 64MHz des 18F, une fois qu'on a déclaré FOSC=64MHz dans la config hardware, l'horloge démarre sans avoir à écrire un seul registre.
Je pense aussi à la config 64MHz des 18F, une fois qu'on a déclaré FOSC=64MHz dans la config hardware, l'horloge démarre sans avoir à écrire un seul registre.
Interrupt On Change sur 18F27K42
- paulfjujo
Expert- Messages : 2597
- Âge : 73
- Enregistré en : juillet 2015
- Localisation : 01800
- Contact :
un petit effort pour aller dans ton sens ..
Code : Tout sélectionner
void __interrupt(irq(IRQ_IOC) ,high_priority) IOC_ISR(void)
{
if(IOCAF & 0xF0)
{ // lecture et test des flag
switch (IOCAF)
{
case 16:
Infos_envoi_DTMF=1; Flag_IOCA=1; Count_IOCA++; break;
case 32:
Infos_envoi_DTMF=2; Flag_IOCA=1; Count_IOCA++ ;break;
case 64:
Infos_envoi_DTMF=3; Flag_IOCA=1;Count_IOCA++; break;
case 128:
Infos_envoi_DTMF=4;Flag_IOCA=1; Count_IOCA++;break;
default :
Infos_envoi_DTMF=0;Flag_IOCA=1;Count_IOCA++;break;
}
IOCAF=0;
}
// ------- Port C ------------
if(IOCCF4)
{
Count_IOCC++;
Flag_IOCC=1;
Etat_Combine=RC4;
IOCCF=0;
}
IOCIF=0;
//pour ne capturer qu'1 seule IT
IOCIE=0;
}
Qui est en ligne
Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 54 invités