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

Interrupt On Change sur 18F27K42
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#1 Message par paulfjujo » sam. 22 oct. 2022 09:44

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

... 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
Test_IOC_interrupt_PortA_4567.jpg
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

Interrupt On Change sur 18F27K42
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#2 Message par satinas » jeu. 27 oct. 2022 07:08

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.

Interrupt On Change sur 18F27K42
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#3 Message par paulfjujo » jeu. 27 oct. 2022 09:54

Bonjour à tous,

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é.
:sifflotte: 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é.
Aide toi, le ciel ou FantasPic t'aidera

Interrupt On Change sur 18F27K42
satinas
Expert
Expert
Messages : 1225
Enregistré en : novembre 2015

#4 Message par satinas » jeu. 27 oct. 2022 10:09

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.

Interrupt On Change sur 18F27K42
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2589
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#5 Message par paulfjujo » jeu. 27 oct. 2022 12:42

:sifflotte: un petit effort pour aller dans ton sens ..

Code : Tout sélectionner


void __interrupt
(irq(IRQ_IOC) ,high_priorityIOC_ISR(void)

   if(
IOCAF 0xF0)
   {  
// lecture et test des flag 
      
switch (IOCAF)
      {
        case 
16:    
         
Infos_envoi_DTMF=1;  Flag_IOCA=1Count_IOCA++; break;
        case  
32:   
         
Infos_envoi_DTMF=2Flag_IOCA=1Count_IOCA++ ;break;
       case  
64:
         
Infos_envoi_DTMF=3Flag_IOCA=1;Count_IOCA++; break;
        case  
128:
        
Infos_envoi_DTMF=4;Flag_IOCA=1Count_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
Aide toi, le ciel ou FantasPic t'aidera


Retourner vers « Langage C »

Qui est en ligne

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