IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Embarqué Discussion :

Compteur LCD sur µC PIC16F876


Sujet :

Embarqué

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur validation
    Inscrit en
    Novembre 2015
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur validation

    Informations forums :
    Inscription : Novembre 2015
    Messages : 25
    Par défaut Compteur LCD sur µC PIC16F876
    Bonjour,

    Dans le cadre d'un TP je dois réaliser un programme permettant d'afficher des caractères sur un afficheur LCD de type 16*2.

    Plus précisément il faut qu'au début le LCD affiche en alternance BONJOUR/Appuyez sur une touche, puis on a 2 boutons:
    -Le premier qui permet de passer à la suite du programme, si on appuie dessus le LCD va afficher TOUCHE OK pendant 3 secondes puis il va afficher NBR DE VISITEURS (sur la 1ère ligne) et Nbr : (sur la 2ème).

    C'est là qu'intervient le second bouton, en fait quand on appuie dessus le nombre de visiteurs va augmenter (ex : j'appuie 5 fois dessus le LCD va afficher Nbr : 5).
    En fait il faut donc faire un compteur mais je ne sais pas trop par où commencer.

    De plus j'ai un autre petit problème, je suis obligé de mettre un long délai ( genre 999999999 ms) pour que le LCD affiche un message longtemps, j'imagine que mettre un délai pareil ce n'est pas la solution (surtout si on veut mettre des conditions après !).

    Et maintenant voici le code + un screen de mon schéma Proteus
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
                            //////////Programme permettant d'afficher du texte sur un afficheur LCD\\\\\\\\\\
    ////////////////////////////////////////////////////////////////////////////////
    //Fonctions
    void init(); // Prodédure d'initialisation du PIC
    void affichage(); // Procédure qui gère l'affichage
    void impulsion_E(); // Procédure qui gère l'impulsion E
    void touche_ok(); // Procédure qui affiche "TOUCHE OK" sur le LCD
    ////////////////////////////////////////////////////////////////////////////////
    //Constantes
    #define LCD PORTB
    #define RS PORTC.F3
    #define E PORTC.F4
    #define LED PORTC.F7
    #define TOUCHE_OK PORTC.F6
    #define NBR_VISITEURS PORTC.F5
    #define EFFACER 0x01
    #define LIGNE_BAS 0xC0
    ////////////////////////////////////////////////////////////////////////////////
    //Fonction principale
    void main()
    {
         init(); // appel de la procédure "init"
                 while(1)
                 {
                       affichage(); // appel de la procédure "affichage"
                       while ( TOUCHE_OK == 0)
                       {
                          touche_ok(); // appel de la procédure "touche_ok"
                       }
                 }
    }
    ////////////////////////////////////////////////////////////////////////////////
    void init() //Sous programme qui gère l'initialisation
    {
     // Définition des ports en entrée ou sortie
     trisc.F3 = 0;
     trisc.F4 = 0;
     trisc.F7 = 0;
     trisc.F6 = 1;
     trisc.F5 = 1;
     trisb = 0x00;
    
     RS = 0;
     // Config du LCD
     LCD = 0x38;
     impulsion_E();
    
     LCD = 0x10;
     impulsion_E();
    
     LCD = 0x0C;
     impulsion_E();
    
     LCD = 0x06;
     impulsion_E();
    
     LCD = 0x01;
     impulsion_E();
    
    }
    ////////////////////////////////////////////////////////////////////////////////
    void affichage() // Sous programme qui gère l'affichage sur le LCD
    {
         int boucle;
         char message1[] = "BONJOUR"; // On initialise la variable "message1"
         char message2[] = "Appuyez sur une"; // On initialise la variable "message2"
         char message3[] = "touche"; // On initialise la variable "message3"
         RS = 1; // Permet d'écrire des caractères sur le LCD
    
                        for ( boucle = 0; boucle < 7; boucle ++) // Boucle qui va afficher "BONJOUR"
                        {
                            LCD = message1[boucle]; // Affiche "Appuyez sur une" sur le LCD
                            impulsion_E(); // appel de la procédure "impulsion_E"
                        }
                        delay_ms(1000); // Pendant 1 sec
                        RS = 0;
                        LCD = EFFACER; // Efface le LCD
                        impulsion_E(); // appel de la procédure "impulsion_E"
                        RS = 1;
    
                           for ( boucle = 0; boucle < 15; boucle ++) // Boucle qui affiche "Appuyez sur une touche"
                           {
                               LCD = message2[boucle]; // Affiche "Appuyez sur une" sur le LCD
                               impulsion_E(); // appel de la procédure "impulsion_E"
                           }
                           RS = 0;
                           LCD = LIGNE_BAS; // Affiche sur la deuxième ligne le prochain texte
                           impulsion_E(); // appel de la procédure "impulsion_E"
                           RS = 1;
    
                                for (boucle = 0; boucle < 6; boucle ++) // Boucle qui permet d'afficher la suite de "Appuyez sur une touche"
                                {
                                    LCD = message3[boucle]; // Affiche "touche" sur le LCD
                                    impulsion_E(); // appel de la procédure "impulsion_E"
                                }
                                delay_ms(1000);
                                RS = 0;
                                LCD = EFFACER; // Efface le texte sur le LCD
                                impulsion_E(); // appel de la procédure "impulsion_E"
    
    }
    ////////////////////////////////////////////////////////////////////////////////
    void impulsion_E() // Sous programme qui gère l'impulsion sur E
    {
         E = 1;
         delay_ms(2); //Tempo 2 ms
         E = 0;
    }
    ////////////////////////////////////////////////////////////////////////////////
    void touche_ok() // Sous programme qui gère l'affichage de "TOUCHE OK" sur le LCD
    {
         int boucle;
         char message4[] = "TOUCHE OK"; // On initialise la variable "message4"
         char message5[] = "NBR DE VISITEURS"; // On initialise la variable "message5"
         char message6[] = "Nbr :"; // On initialise la variable "message6"
         RS = 0;
         LCD = EFFACER; // Efface le texte sur le LCD
         impulsion_E(); // appel de la procédure "impulsion_E"
         RS = 1;
    
                     for (boucle = 0; boucle < 9; boucle ++)  // Boucle qui va affiche "TOUCHE OK"
                     {
                         LCD = message4[boucle]; // Affiche "TOUCHE OK" sur le LCD
                         impulsion_E(); // appel de la procédure "impulsion_E"
                     }
                     delay_ms(3000); // Pendant 3 sec
                     RS = 0;
                     LCD = EFFACER; // Efface le texte sur le LCD
                     impulsion_E(); // appel de la procédure "impulsion_E"
                     RS = 1;
    
                          for (boucle = 0; boucle < 16; boucle ++) // Boucle qui affiche "NBR DE VISITEURS"
                          {
                              LCD = message5[boucle]; // Affiche "NBR DE VISITEURS" sur le LCD
                              impulsion_E(); // appel de la procédure "impulsion_E"
                          }
                          RS = 0;
                          LCD = LIGNE_BAS; // Affiche le prochain texte sur la 2ème ligne
                          impulsion_E(); // appel de la procédure "impulsion_E"
                          RS = 1;
    
                             for (boucle = 0; boucle < 5; boucle ++) // Boucle qui affiche "Nbr :"
                             {
                                 LCD = message6[boucle]; // Affiche "Nbr :" sur le LCD
                                 impulsion_E(); // appel de la procédure "impulsion_E"
                             }
                                 delay_ms(999999); // Délai élevé pour que le LCD affiche longtemps le message
    
     }
    Nom : Schem proteurs.png
Affichages : 7401
Taille : 22,7 Ko

    Merci

  2. #2
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 252
    Par défaut
    Salut,
    Tu y es presque, il ne te manque plus que la gymnastique d'esprit avec les interruptions !

    Je vais résumer le cahier des charges :
    Citation Envoyé par Caenem
    Il faut qu'au début le LCD affiche en alternance "BONJOUR" et "Appuyez sur une touche"
    Bouton 1 fait afficher "TOUCHE OK" pendant 3 secondes puis il va afficher NBR DE VISITEURS (sur la 1ère ligne) et une variable NBR : (sur la 2ème).
    Bouton 2 fait augmenter le nombre de visiteurs (ex : j'appuie 5 fois dessus le LCD va afficher Nbr : 5), donc la variable NBR.

    Citation Envoyé par Caenem
    En fait il faut donc faire un compteur mais je ne sais pas trop par où commencer.
    De plus j'ai un autre petit problème, je suis obligé de mettre un long délai ( genre 999999999 ms) pour que le LCD affiche un message longtemps, j'imagine que mettre un délai pareil ce n'est pas la solution (surtout si on veut mettre des conditions après !).
    En effet, il faut un compteur et ton micro a un TIMER qui sert à ça.
    Les délais inséraient dans le code vont bloquer l'exécution du programme principal. Là aussi, ton micro possède ce qu'il faut : les programmes d'interruptions, qui stop ton programme principal le temps s'exécuter puis ils redonnent la main au programme principal.

    Ton algorithme peut ressembler à ça :
    - encadré en pointiller (programme d'interruption)
    Nom : Diagramme1.png
Affichages : 5962
Taille : 105,7 Ko

    Dans un premier temps et avant d'aller plus loin, arrives tu a comprendre les grandes lignes de cet algorithme ?

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur validation
    Inscrit en
    Novembre 2015
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur validation

    Informations forums :
    Inscription : Novembre 2015
    Messages : 25
    Par défaut
    Tiens, il y a des trucs que je ne connais pas comme "Timer overflow" et Indéfiniment ( c'est un délai ?), sinon le reste de l'algo je comprends.
    Mais si tu as fais des "morceaux" d'algo, ça veut dire qu'il faudra les mettre dans des fonctions à part ?

  4. #4
    Modérateur

    Avatar de Vincent PETIT
    Homme Profil pro
    Consultant en Systèmes Embarqués
    Inscrit en
    Avril 2002
    Messages
    3 252
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Pas de Calais (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Consultant en Systèmes Embarqués
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Avril 2002
    Messages : 3 252
    Par défaut
    Demain, je t'expliquerai comment tout ça fonctionne.
    Mais oui c'est bien ça : morceau d'algo = fonction d'interruption.

    Lorsque tu vois une fonction d'interruption dans un programme, tu te dis que c'est bizarre car le programme principal n'appelle jamais cette fonction. En réalité, c'est le hardware qui lance la fonction.

    Si tu créais une fonction d'interruption TIMER, à chaque fois que le TIMER du PIC va déborder (overflow), ton programme principal va se stopper net et c'est la fonction d'interruption qui va s'exécuter. Des que la fonction d'interruption a fait ce que tu voulais qu'elle fasse alors le programme principal reprend à l'endroit où il a été interrompu.

    Si tu regardes l'organigramme, l'idée est de faire une fonction d'interruption qui va incrémenter une variable à chaque débordement du TIMER du PIC. Au préalable il faut régler le TIMER du PIC pour qu'il déborde toutes les secondes. Cette variable va s'incrémenter, va donc toutes les secondes au travers de la fonction d'interruption et cela même si ton programme principal est dans une boucle infinie ou un délai genre 999999999 ms (aucun soucis dans la mesure ou le programme principal va être stoppé, de toute manière, par la fonction d'interruption, qui est prioritaire !)

  5. #5
    Membre averti
    Homme Profil pro
    Ingénieur validation
    Inscrit en
    Novembre 2015
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur validation

    Informations forums :
    Inscription : Novembre 2015
    Messages : 25
    Par défaut
    Je comprends mieux maintenant, à demain.

  6. #6
    Membre Expert
    Homme Profil pro
    Étudiant
    Inscrit en
    Juin 2012
    Messages
    1 711
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juin 2012
    Messages : 1 711
    Par défaut
    Hello,

    Pourquoi utiliser des interruptions pour les 2 boutons ?
    On utilise des interruptions pour simuler du multithreading, pour être notifié d'un évènement extérieur (sans polling) ou pour exécuter du code à intervalle régulier sans avoir à compter les cycles (c'est le cas du timer ici).

    On peut faire du polling sur les boutons sans problèmes (je crois ?). Il y a un avantage à utiliser des interruptions ?

    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    bool btn1 = false;
    bool btn2 = false;
     
    typedef enum { ST_HELLO, ST_DELAY_HELLO /*...*/, ST_WAIT_BTN1 } state_t;
    state_t st = ST_HELLO;
     
    while(1) {
       btn1 |= readBtn1State();
       btn2 |= readBtn2State();
     
       switch(st) {
       case ST_HELLO:
          print("Bonjour");
          st = ST_DELAY_HELLO;
       // ...
       case ST_WAIT_BTN1:
          if(btn1) {
             btn1 = false;
             st = // ...
           }
       }
    }

    (Au passage, c'est quoi ton soft pour faire ces beaux schémas ? Ça à l'air vachement plus pratique que paint *_*).

Discussions similaires

  1. Compteur windows sur la mémoire utilisée par w3wp.exe
    Par maxagaz dans le forum Visual Studio
    Réponses: 2
    Dernier message: 23/01/2008, 20h56
  2. compteur dynamique sur action utilisateur
    Par Goldorak2 dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 18/07/2007, 14h26
  3. [Cookies] un compteur basé sur les cookies
    Par kuja2053 dans le forum Langage
    Réponses: 5
    Dernier message: 12/03/2007, 17h28
  4. Réponses: 11
    Dernier message: 27/06/2006, 16h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo