[Programmation] Gestion d'un bouton poussoir sur microcontrôleur [Résolu] - Page 2
Répondre à la discussion
Page 2 sur 3 PremièrePremière 2 DernièreDernière
Affichage des résultats 31 à 60 sur 76

Gestion d'un bouton poussoir sur microcontrôleur [Résolu]



  1. #31
    invite03481543

    Re : Gestion d'un bouton poussoir sur microcontrôleur


    ------

    Je ne parle pourtant que d'interruptions simples, qui assurent un fonctionnement prévisible à tous les coups et totalement reproductibles.
    Il n'y a aucune complexité dans ce principe, il suffit juste de bien le comprendre pour l'appliquer correctement.
    Je ne sais pas quel est ton compilateur mais qu'est-ce que ce serait si on parlait de machine d'état...
    Car il faut bien voir qu'un programme digne de ce nom fonctionne ainsi.

    -----

  2. #32
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Citation Envoyé par HULK28 Voir le message
    ta capa est inutile pour un µC.
    Un bouton se gère uniquement par soft
    Tout le monde ne semble pas tout à fait d'accord puisque par exemple, Daudet disait que les gens ne savent en général pas gérer l'anti-rebonds par soft. Mais sans plus de précision, difficile de se faire un avis. J'essaie d'ailleurs maintenant de le faire par soft, tout en pensant que lisser les micro-oscillations par un petit condo ne puisse pas être contre-productif. Mais je me trompe peut-être.

    Citation Envoyé par HULK28 Voir le message
    Comme le dit terriblement, en général on ne fait que de détecter la source d'interruption puis on retourne dans le prog principal pour faire l'action.
    Donc dans le programme principal, tu testes la valeur d'une variable à chaque boucle ?
    Ca ne revient pas au même que de tester la valeur de l'entrée à chaque boucle ? Certainement encore quelque chose que je ne comprends pas sur la façon de gérer l'action dans le prog principal.
    -> on choisit par exemple INT0, on active les interruptions, on active le pull-up interne.
    -> on pré-charge une tempo, par exemple TEMPO_bouton sur 100ms
    -> dès que l'interruption est activée on active la tempo TEMPO_bouton que l'on décrémente.
    -> à la fin de la tempo on regarde si l'entrée bouton est toujours ON ou OFF.
    Si OFF on oublie, si ON on considère que l'appui n'est pas accidentel et on valide par l'action qu'il convient de faire.
    Tu mets donc bien un delai au cœur de l'interruption, non ? Mais j'avoue que je ne comprends pas bien ce que tu entends par "précharger une tempo" puis "l'activer et la décrémenter".

    Citation Envoyé par HULK28 Voir le message
    Simplement parce que quand on utilise un µC et bien on s'en sert bien ou on continue à jouer avec des 555.
    En plus c'est très simple, c'est de la mauvaise volonté.
    Je crois que tu n'as pas bien compris le principe des interruptions.
    Merci pour tes conseils.
    Oui, si je suis ici, c'est probablement que je n'ai pas bien compris le principe des interruptions. Et certainement aussi tout plein d'autres choses.
    C'est justement parce que, après avoir lu la datasheet à plusieurs reprises, fait diverses recherches sur le web et cherché seul longtemps, je pense qu'il y a quelque chose de fondamental qui m'échappe que je suis venu poser mes questions ici.

    Citation Envoyé par HULK28 Voir le message
    Dans ce cas mieux vaut qu'il oublie son µC, vu que le reste va aussi impliquer des tempos...[...]
    Ecoute mon petit gars, si tu viens ici pour apprendre et que tu n'écoutes que ce qui t'arrange dans ce cas débrouille toi tout seul.
    Maintenant je te laisse entre les mains des fameux "spécialistes" ci-dessus.[...]
    Il n'y a aucune complexité dans ce principe, il suffit juste de bien le comprendre pour l'appliquer correctement.
    Merci encore pour tous ces bons conseils. J'essaie de faire ce que vous dites, mais vu que ça ne fonctionne pas comme prévu, il y a sûrement quelque chose qui m'a échappé. En revanche, je n'ai vu personne se définir comme un "spécialiste".
    Dernière modification par scaypapa ; 28/06/2016 à 08h58.

  3. #33
    invite03481543

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Ecoute bleue-bite, j'ai pas de temps à perdre avec toi, je fais des programmes depuis suffisamment de temps pour savoir comment on fait.
    Maintenant si ton but est de t'éparpiller, libre à toi.
    Tu passes plus de temps à démêler le bon grain de l'ivraie que d'écouter ce que je t'explique en vain.
    Donc démerde toi.

  4. #34
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Je cherches surtout à décoder tes conseils au milieu de tes insultes...

  5. #35
    DAUDET78

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Citation Envoyé par scaypapa Voir le message
    Tout le monde ne semble pas tout à fait d'accord puisque par exemple, Daudet disait que les gens ne savent en général pas gérer l'anti-rebonds par soft.
    Non , je suis entièrement d'accord avec HULK28 . Le condensateur est inutile si on gère le bouton en interruption .... ... encore faut-il savoir le faire
    Donc dans le programme principal, tu testes la valeur d'une variable à chaque boucle ?
    Ca ne revient pas au même que de tester la valeur de l'entrée à chaque boucle ?
    Dans le programme d'interruption soit :
    - tu gères l'anti-rebond et tu positionnes un flag qui dit Le bouton a été valablement appuyé
    - tu gères un compteur du nombre d'action
    Bref un programme court !

    L'intérêt ? C'est que la prise en compte du bouton est faite et que le test en pooling dans le Void peut se faire dans un délais quelconque (et sans perte de l'information "appuie bouton"
    J'aime pas le Grec

  6. #36
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Je viens de comprendre pourquoi lorsque je faisais fonctionner l'interruption INT2, la LED changeait une seule fois d'état lors de l'appui sur RB4 puis RB4 n'avait plus d'effet.
    Au moment du relâchement de RB2, la variable interTouche passait à 1 mais la LED ne changeait pas d'état car au moment du test, après le délai de 20ms, BP est revenu à 1.
    Comme je ne réinitialisais interTouche que si les conditions de changement d'état étaient vérifiées, au moment de l'appui sur RB4, interTouche est toujours à 1 et l'appui sur RB4 fait passer BP2 à 0 (dans le prog principal). Donc la LED change d'état.

    Il n'y a donc toujours aucune interruption de déclenchée lors de l'appui ou du relâchement de RB4.

    Pour bien gérer l'interruption à n'importe quel moment du programme (même si actuellement le programme principal est vide, c'est pour le principe), j'ai replacé tout le code dans l'interruption :
    Code:
    void interrupt IOC(void)
    {
        if (interTouche) __delay_ms (20);
        if (interTouche && (!BP || !BP2))
            LED = !LED;
        interTouche = 0;
        if (INTCONbits.RBIF)
            INTCONbits.RBIF = 0;
        if (INTCON3bits.INT2IF)
            INTCON3bits.INT2IF = 0;
    }
    void main(void)
    {
        int i;
        
        //Init
        TRISB = 1;              // Config PORTB en entrée
        LATB = 0XFF;
        ANSELD = 0;
        TRISA = TRISD = 0;      // Config PORTD en sortie
        PORTA = 0;
        LED = 1;
        
        // Int2 Interrupt
        INTCON3bits.INT2IE = 1;
        INTCON3bits.INT2IF = 0;
        
        
        // Rb4-7 onChangeInterrupt
        INTCONbits.RBIE = 1;
        if(BP2);                 // juste histoire de le lire pour pouvoir effacer le drapeau
        INTCONbits.RBIF = 0;
        
        // Pullup
        INTCON2bits.RBPU = 0;
        
        interTouche = 0;
        INTCONbits.GIE = 1;
        
        while (1);
    }
    C'est correct ou est-ce que le delai de 20ms au cœur de l'interruption est problématique ?
    Dernière modification par scaypapa ; 28/06/2016 à 09h25.

  7. #37
    DAUDET78

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Citation Envoyé par scaypapa Voir le message
    C'est correct ou est-ce que le delai de 20ms au cœur de l'interruption est problématique ?
    On ne mets jamais un delais dans un programme d'interruption
    Ca fait dix fois qu'on te le dit !
    Un programme en interruption doit être court

    Quand tu détectes l'interruption du bouton Chouette le bouton est appuyé
    Mais est ce bien un bon appuie ?????
    Tu lances le timer de 20ms (que tu avais programmé)

    NB : un timer (opérateur hard ) laisse le µC libre , un délai (par soft) occupe le µC

    Quand l’interruption du Timer arrive au bout de 20ms , tu testes l'état du bouton
    - Il n'est pas appuyé ? fausse alerte !
    - Il est encore appuyé ? c'est tout bon ! Tu positionnes un Flag ou tu incrémentes un compteur.... bref, tu le prend en compte .
    J'aime pas le Grec

  8. #38
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur


    Merci ! J'ai enfin compris où vous vouliez en venir sur cette histoire de gestion de l'anti-rebond sans mettre de délai dans une interruption !
    Vu que j'essayais de faire un petit programme au plus simple pour ne pas risquer de multiplier les sources d'erreur, j'avais complètement oublié que les timers ne consomment pas de ressources CPU.

    J'utilise donc le Timer0 et du coup, mon main pourrait être aussi long que je veux, l'interruption sur un bouton sera prise en compte au moment de l'appui et non plus au moment d'un test quelconque. Cool !

    En revanche, mes interruptions IOC ne font toujours rien
    Je ne vois pas du tout ce qui cloche mais c'est certainement aussi une erreur de newbie (ou de bleue-bite comme dirait l'autre).

    J'ai séparé l'appui sur les BP en deux pour bien visualiser leur action séparément. Voici ce que ça donnerait :
    Code:
    #define _XTAL_FREQ  1000000
    // I/O
    #define BP1         PORTBbits.RB2
    #define BP2         PORTBbits.RB4
    #define LED1        PORTDbits.RD0
    #define LED2        PORTDbits.RD1
    
    void anti_rebond(void)
    {
        TMR0L = 0;
        T0CONbits.TMR0ON = 1;
    }
    
    void interrupt boutons(void)
    {
        if (INTCONbits.RBIF) {
            if (PORTB) NOP();
            INTCONbits.RBIF = 0;
            anti_rebond();
        }
        
        else if (INTCON3bits.INT2IF) {
            INTCON3bits.INT2IF = 0;
            anti_rebond();
        }
        
        else if (INTCONbits.TMR0IF) {
            if (!BP1)
                LED1 = !LED1;
            LED2 = !BP2;
            T0CONbits.TMR0ON = 0;
            INTCONbits.TMR0IF = 0;
        }
    }
    
    void main(void)
    {
        // Ports
        TRISB = 1;              // Config PORTB en entrée
        ANSELD = 0;
        TRISD = 0;              // Config PORTD en sortie
        
        // Rb4-7 onChangeInterrupt
        INTCONbits.RBIE = 1;
        if(BP2);                 // juste histoire de le lire pour pouvoir effacer le drapeau
        INTCONbits.RBIF = 0;
        
        // Tmr0 Interrupt
        T0CON = 0b01000100;     // T0OFF 8bits CLKOUT - Use Postscaler : 1/32   => Tmr0 overflow = 256*32*4/1000000 = 32,768ms
        INTCONbits.TMR0IE = 1;
        INTCONbits.TMR0IF = 0;
        
        // Int2 Interrupt
        INTCON3bits.INT2IE = 1;
        INTCON3bits.INT2IF = 0;
        
        
        // Pullup
        INTCON2bits.RBPU = 0;
        
        // Init
        LED1 = LED2 = 0;
        INTCONbits.GIE = 1;
        
        while (1);
    }
    J'ai essayé aussi de modifier le drapeau RBIF manuellement dans ma boucle principale pour contrôler le bon fonctionnement de mon interruption RBIF :
    Code:
        while (1) {
            __delay_ms(500);
            __delay_ms(500);
            __delay_ms(500);
            INTCONbits.RBIF = 1;
        }
    Si j'appuie sur l'inter correspondant, la LED change bien d'état au bout de 1,5s si l'on appuie sur le BP.
    Ca prouve bien que l'appui sur mon BP ne met pas le drapeau à 1, comme si les interruption RBIE n'étaient pas activées...

  9. #39
    antek

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Commence par apprendre à gérer une seule interruption à la fois, ce sera plus facile.

  10. #40
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Oui, c'est un peu l'idée.
    J'ai d'abord essayé le RBIE seul mais comme il ne fonctionnait pas, j'ai essayé INT0,1,2 pour contrôler que le BP était correctement branché et détecté.
    Au final j'ai laissé les deux types d'interruptions dans le programme pour bien montrer que ça fonctionne bien sur INT mais pas sur RBIE.

    J'ai rajouté l'interruption sur le Timer0 en suivant le conseil de Daudet, afin de gérer l'anti-rebond. Ce qui me semble en effet bien plus logique que de rechercher si une interruption a été detectée dans la boucle principale (on perd ainsi le bénéfice d'utiliser une interruption).

    Je peux très bien retirer l'interruption sur INT2 maintenant que j'ai vu qu'elle fonctionnait bien. C'est vraiment l'interruption sur RBIE qui me pose problème puisque même si l'appui sur le bouton est bien détecté (RB4 change de valeur), l'interruption ne se produit apparemment pas...
    Dernière modification par scaypapa ; 28/06/2016 à 14h38.

  11. #41
    antek

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Citation Envoyé par scaypapa Voir le message
    C'est vraiment l'interruption sur RBIE qui me pose problème puisque même si l'appui sur le bouton est bien détecté (RB4 change de valeur), l'interruption ne se produit apparemment pas...
    Eh ben remet dans le PIC un programme avec RBIE seule (et avec uniquement ce qui est réellement utilisé) et montre le.
    Et aussi le schéma de branchement réel.

  12. #42
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Bien. Alors reprenons du début...

    Voici mon schéma de branchement complet (les seules choses que je n'ai pas représentées sont les fils qui relient entre elles les 2 pattes Vdd et les deux pattes Vss ni les fils qui me permettent de me relier au programmateur). Je n'ai placé qu'un condo de 0,1µF sur une paire Vdd/Vss. L'autre paire étant reliée à la première par 2 fils de moins de 3cm, je ne suis pas sûr qu'elle en ai besoin.

    Nom : shéma IOCTest.jpg
Affichages : 254
Taille : 2,8 Ko
    EDIT : une erreur s'est glissée au moment de dessiner le shéma : ce n'est pas Vcc et Vdd mais bien Vdd et Vss...

    J'ai d'abord essayé ce code qui fonctionne parfaitement :
    Code:
    /* 
     * File:   main.c
     * Essai InterruptOnChange
     *
     * Created on June 27, 2016, 10:24 PM
     */
    
    #include <xc.h>
    
    // CONFIG1H
    #pragma config FOSC = INTIO67   // Oscillator Selection bits (Internal Oscillator Block))
    
    // CONFIG2H
    #pragma config WDTEN = OFF      // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
    
    // CONFIG3H
    #pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<5:0> pins are configured as digital I/O on Reset)
    
    // I/O
    #define BP         PORTBbits.RB4
    #define LED        PORTDbits.RD2
    
    void main(void)
    {
        // Ports
        TRISB = 1;              // Config PORTB en entrée
        ANSELD = 0;             // Digital
        TRISD = 0;              // Config PORTD en sortie
    
        // Pullup
        INTCON2bits.RBPU = 0;
        
        // Init
        LED = 0;
        
        while (1) {
            LED = !BP;
        }
    }
    J'ai ensuite essayé de faire exactement la même chose en utilisant les interruption onChange :
    Code:
    void anti_rebond(void)
    {
        TMR0L = 0;
        T0CONbits.TMR0ON = 1;
    }
    
    void interrupt boutons(void)
    {
        if (INTCONbits.RBIF) {
            if (BP) NOP();
            INTCONbits.RBIF = 0;
            anti_rebond();
        }
        
        else if (INTCONbits.TMR0IF) {
            LED = !BP;
            T0CONbits.TMR0ON = 0;
            INTCONbits.TMR0IF = 0;
        }
    }
    
    
    void main(void)
    {
        // Ports
        TRISB = 1;              // Config PORTB en entrée
        ANSELD = 0;             // Digital
        TRISD = 0;              // Config PORTD en sortie
    
      
        // Rb4-7 Interrupt
        INTCONbits.RBIE = 1;
        if(BP);                 // juste histoire de le lire pour pouvoir effacer le drapeau
        INTCONbits.RBIF = 0;
        
        // Tmr0 Interrupt
        T0CON = 0b01000100;     // T0OFF 8bits CLKOUT - Use Postscaler : 1/32   => Tmr0 overflow = 256*32*4/1000000 = 32,768ms
        INTCONbits.TMR0IE = 1;
        INTCONbits.TMR0IF = 0;
            
        // Pullup
        INTCON2bits.RBPU = 0;
        
        // Init
        LED = 0;
        INTCONbits.GIE = 1;
        
        while (1);
    }
    Ce qui se trouve avant dans le code est strictement identique.

    C'est toujours la même chose depuis le début, je ne voulais juste pas vous embêter avec tous ces détails. Peut-être aurais-je dû...
    En tout cas, il y a forcément une erreur quelque part.
    Les autres essais que j'ai fait n'étaient là que pour valider telle ou telle partie du code/du câblage. Mais à ce stade, je ne vois plus du tout où chercher.
    La LED est bien branchée puisqu'elle s'allume. L'inter est bien reconnu puisqu'il agit sur la LED si le code se trouve directement dans la boucle principale.
    La gestion des rebonds par le Timer0 fonctionne à merveille avec une autre interruption que RBIE.
    Il doit y avoir un problème de configuration quelque part, mais j'ai l'impression d'avoir lu et relu 2 ou 3 pages de résultats Gougloule en boucle sur ce sujet et je ne vois pas ce qui peut clocher.
    Dernière modification par scaypapa ; 28/06/2016 à 19h23. Motif: erreur shéma

  13. #43
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    J'ai fait églament un essai en retirant
    Code:
    // *
       void anti_rebond(void)
       {
           TMR0L = 0;
           T0CONbits.TMR0ON = 1;
       }
    
    // *
       else if (INTCONbits.TMR0IF) {
            LED = !BP;
            T0CONbits.TMR0ON = 0;
            INTCONbits.TMR0IF = 0;
        }
    
    // *
       // Tmr0 Interrupt
        T0CON = 0b01000100;     // T0OFF 8bits CLKOUT - Use Postscaler : 1/32   => Tmr0 overflow = 256*32*4/1000000 = 32,768ms
        INTCONbits.TMR0IE = 1;
        INTCONbits.TMR0IF = 0;
    et remplacé "anti_rebond()" dans l'interruption RBIE par "LED = !BP". Mais ça ne fonctionne pas non plus évidemment.

    De toutes façons, difficile de savoir quelle valeur serait lue puisqu'au moment de la lecture, l'inter serait justement en train de rebondir...
    Dernière modification par scaypapa ; 28/06/2016 à 19h30.

  14. #44
    antek

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Citation Envoyé par scaypapa Voir le message
    Je n'ai placé qu'un condo de 0,1µF sur une paire Vdd/Vss. L'autre paire étant reliée à la première par 2 fils de moins de 3cm, je ne suis pas sûr qu'elle en ai besoin.
    Pièce jointe 317661
    Si, faut en mettre sur chaque pin +5V/0V
    Ton schéma ne marche pas.

  15. #45
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Dur dur de garder sa tête en dessinant le scéma, j'ai aussi placé la LED à l'envers. Ce n'est pas le cas sur la platine . Toutes mes confuses...

  16. #46
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Du coup. Je renvoie le schéma revu et corrigé.
    Il ne manque strictement rien. Même les emplacements des composants correspondent à quelque chose près (ce n'est pas à l'échelle).
    Je n'ai pas symbolisé les entrées/sorties pour les ports A, C et E puisqu'ils ne sont pas configurés (sauf la patte RE3/MCLR/Vpp).
    Si les pattes Vdd et Vss sont plus écartées que les autres sur le schéma, c'est uniquement pour éviter qu'elles ne se chevauchent.
    Nom : IOCTest.jpg
Affichages : 245
Taille : 8,4 Ko

    J'utilise MPLab X IDE 3.30 avec un Pickit3 configuré pour délivrer la puissance directement.
    Mes ports USB ne veulent pas délivrer plus de 4,5V ce qui ne semble pas le déranger outre mesure.
    Il arrive à programmer (si j'alimente le circuit ensuite par une pile 9V régulée, le programme s'exécute de la même façon) et entrer en mode debugger.

    Que dire de plus à part que l'ajout d'un second condensateur sur les bornes Vdd et Vss de droite n'a rien changé :
    la LED réagit bien à l'appui sur le bouton poussoir si elle est commandée dans le main ou dans une interruption de type INT0,1,2 mais ne fait rien du tout si elle est commandée depuis une interruption de type RB4-7 OnChange.

  17. #47
    invite03481543

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Tu as déjà un problème ici (en rouge), la direction d'un port se fait soit individuellement soit en déclarant par un octet l'ensemble du port:
    Code:
    void main(void)
    {
        // Ports
        TRISB = 1;      // Config PORTB en entrée -> non! pour mettre RB4 en entrée -> TRISBbits.RB4=1 ou TRISB = 0x10
        ANSELD = 0;   // Digital
        TRISD = 0;     // Config PORTD en sortie

  18. #48
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Wah merci ! Elle est enorme !
    Évidemment, seul RB0 était une entrée ! Je ne comprend même pas pourquoi j'ai déjà eu quelque chose sur RB1 et RB2 !

    J'y ai cru que c'était... la seule.
    Mêmes réactions. J'ai mis PORTB = 0xFF après avoir essayé différentes combinaisons, toutes aussi peu concluantes.

  19. #49
    invite03481543

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Je ne vois pas non plus PEIE=1 (Peripheral interrupt enable), GIE ne suffit pas.

  20. #50
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Non plus. Par contre, ça je n'étais pas au courant pas qu'il y en avait besoin.
    Je pensais que ça concernait les registres d'interruptions suivants (je n'y suis pas ! ) qu'ils appellent aussi "Peripheral Interrupts" (PIRx/PIEx/IPRx).

    EDIT : Ca veut dire quoi ?
    GIE: Global Interrupt Enable bit
    1 = Enables all unmasked interrupts
    0 = Disables all interrupts including peripherals
    Il faut les "dé-masquer" autrement que par RBIE ?
    Dernière modification par scaypapa ; 28/06/2016 à 23h35.

  21. #51
    invite03481543

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Et ici:
    Code:
    INTCONbits.TMR0IE = 1;
    INTCONbits.TMR0IF = 0;
    il faut faire l'inverse:
    Code:
    INTCONbits.TMR0IF = 0;
    INTCONbits.TMR0IE = 1;
    d'abord effacer le flag puis activer l'interruption du timer

  22. #52
    invite03481543

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Reposte ton code complet avec ces modifications pour qu'on y voit plus clair pour la suite.

  23. #53
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Code:
    #include <xc.h>
    
    // CONFIG1H
    #pragma config FOSC = INTIO67   // Oscillator Selection bits (Internal Oscillator Block))
    
    // CONFIG2H
    #pragma config WDTEN = OFF      // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)
    
    // CONFIG3H
    #pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<5:0> pins are configured as digital I/O on Reset)
    
    
    // I/O
    #define BP         PORTBbits.RB4
    #define LED        PORTDbits.RD2
    
    
    
    void anti_rebond(void)
    {
        TMR0L = 0;
        T0CONbits.TMR0ON = 1;
    }
    
    void interrupt boutons(void)
    {
        if (INTCONbits.RBIF) {
            if (BP) NOP();
            INTCONbits.RBIF = 0;
            anti_rebond();
        }
        
        else if (INTCONbits.TMR0IF) {
            LED = !BP;
            T0CONbits.TMR0ON = 0;
            INTCONbits.TMR0IF = 0;
        }
    }
    
    
    void main(void)
    {
        // Ports
        TRISB = 0xFF;           // Config PORTB en entrée
        ANSELD = 0;             // Digital
        TRISD = 0;              // Config PORTD en sortie
    
        // Rb4-7 Interrupt
        if(BP);                 // juste histoire de le lire pour pouvoir effacer le drapeau
        INTCONbits.RBIF = 0;
        INTCONbits.RBIE = 1;
        
        // Tmr0 Interrupt
        T0CON = 0b01000100;     // T0OFF 8bits CLKOUT - Use Postscaler : 1/32   => Tmr0 overflow = 256*32*4/1000000 = 32,768ms
        INTCONbits.TMR0IF = 0;
        INTCONbits.TMR0IE = 1;
            
        // Pullup
        INTCON2bits.RBPU = 0;
        
        // Init
        LED = 0;
        INTCONbits.PEIE = 1;
        INTCONbits.GIE = 1;
        
        while (1) NOP();
    }
    Merci beaucoup

  24. #54
    invite03481543

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Code:
    #define TEMPO 5  // 5*32ms=160ms
    volatile unsigned char tempo_bouton = 0;
    
    
    void interrupt(void)
    {
        if (INTCONbits.RBIF)  // appui détecté
          {        
            INTCONbits.RBIF = 0;  // flag remis à 0
            tempo_bouton = 1;  // on active la tempo de debounce
          }
        
        if (INTCONbits.TMR0IF) // débordement du timer
          {
            INTCONbits.TMR0IF = 0;  // flag remis à 0
            if(tempo_bouton)  // si tempo debounce activé
              {
                if(TEMPO > 0) TEMPO--;  // si TEMPO pas arrivé à 0 on continue de décompter
                else LED=!LED;  // sinon on change l'état de la led
              }
             // ici on recharge le timer 0 (c'est cela qu'il te manque)
           }
    }

  25. #55
    invite03481543

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Le timer0 doit être calculé pour 32ms par exemple et tu dois mettre dans TMROL et TMROH la valeur exacte avec l'offset qui va bien, puis tu mets ON ton timer.
    A chaque débordement du timer0 tu remets le flag à 0 puis tu recharges le timer pour le coup suivant.

  26. #56
    invite03481543

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    J'ai effectué quelques correctifs:

    Code:
    void interrupt(void)
    {
        if (INTCONbits.RBIF && !tempo_bouton)  // appui détecté et tempo_bouton non actif
          {        
            INTCONbits.RBIF = 0;  // flag remis à 0
            tempo_bouton = 1;  // on active la tempo de debounce et on bloque un nouvel appui
          }
        
        if (INTCONbits.TMR0IF) // débordement du timer
          {
            INTCONbits.TMR0IF = 0;  // flag remis à 0
            if(tempo_bouton)  // si tempo debounce activé
              {
                if(TEMPO_encours > 0) TEMPO_encours--;  // si TEMPO pas arrivé à 0 on continue de décompter
                else
                     {
                      LED=!LED;  // sinon on change l'état de la led
                      TEMPO_encours = TEMPO; // on recharge avec la valeur d'origine
                      tempo_bouton = 0; // on autorise un nouvel appui
                     }
                      
              }
             TMR0H  = 0x63;  // pour 32ms avec une base de temps à 10MHz
             TMR0L  = 0xC0;
    
           }
    }
    Et tu ajoutes ça dans ton main:

    Code:
    void Init_Timer0()
    {
      T0CON  = 0x80;
      TMR0H  = 0x63;
      TMR0L  = 0xC0;  
      TMR0IE_bit  = 1;
    }
    Dernière modification par HULK28 ; 29/06/2016 à 00h09.

  27. #57
    invite03481543

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Il faut aussi déclarer TEMPO_encours
    Code:
    unsigned char TEMPO_encours = TEMPO;
    Dis moi ce que tu obtiens et on verra demain la suite.
    Bonne nuit.

  28. #58
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Non je suis désolé.

    Il veut absolument que je donne un nom à la fonction interrupt et en fait, mon timer0 déborde à 32ms (normalement) en étant initialisé à 0.
    Le PIC tourne depuis l'oscillateur interne (à 1MHz par défaut) :
    Code:
    #pragma config FOSC = INTIO67   // Oscillator Selection bits (Internal Oscillator Block))
    et est configuré en 8 bits avec un postscaler de 32. Si j'ai bien compris comment calculer le temps de débordement, il va de 0 à 256 en incrémentant les 4 impulsions * 32.
    Donc il déborde à 256*32*4/1.000.000 = 32,768ms.
    Ca me permettait de ne ne l'initialiser à 0 qu'une seule fois. Mais il n'est peut-être pas très précis ?

    Merci en tout cas et bonne nuit.
    Dernière modification par scaypapa ; 29/06/2016 à 00h32.

  29. #59
    scaypapa

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    Un autre truc que je ne comprends pas trop.
    Dans le principe, le Tmr0 interromps le programme toutes les 32ms, même si on ne touche à rien ?

  30. #60
    invite03481543

    Re : Gestion d'un bouton poussoir sur microcontrôleur

    C'est quoi ton compilateur?

    en principe pour 1MHz avec un prescaler à 32 tu devrais avoir TMR0L= 0x06
    Il est par contre indispensable de recharger l'offset (0x06) mis dans le timer après chaque débordement pour conserver les 32ms.

    Je te conseille de vérifier si ça fonctionne en faisant ceci:
    Code:
    unsigned char tick=0;
    
    void interrupt(void)
    {
        if(INTCONbits.TMR0IF)
            {        
            INTCONbits.TMR0IF = 0;  // flag remis à 0
            if(tick <= 20) tick++; 
            else
                 {
                 LED = !LED; // la led changera d'état si t>32ms*20
                 tick = 0;  // on remet à 0 le comptage de boucle du timer0
                 }
              
              TMR0L  = 0x06; // pour 32ms avec une base de temps à 1MHz        
    
           }
    }
    Il faut regarder comment la routine d'interruption doit être déclarée, ça dépend des compilateurs.
    Dernière modification par gienas ; 29/06/2016 à 09h23. Motif: Suppression de } excédentaire

Page 2 sur 3 PremièrePremière 2 DernièreDernière

Discussions similaires

  1. Bouton poussoir farçeur (énervant) [résolu]
    Par invite424deccd dans le forum Bricolage et décoration
    Réponses: 29
    Dernier message: 10/09/2012, 17h53
  2. Bouton poussoir et minuterie ? [résolu]
    Par crobe dans le forum Bricolage et décoration
    Réponses: 15
    Dernier message: 03/04/2011, 14h42
  3. Gestion de bouton poussoir - différencier appui bref ou long
    Par micr0m dans le forum Électronique
    Réponses: 3
    Dernier message: 07/09/2010, 09h31
  4. [C/PIC] - Gestion bouton poussoir
    Par jorg1n dans le forum Électronique
    Réponses: 6
    Dernier message: 29/04/2009, 07h07
  5. Gestion Bouton poussoir ON/OFF
    Par jorg1n dans le forum Électronique
    Réponses: 22
    Dernier message: 19/10/2007, 15h24
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...