problème afficheur LCD
Répondre à la discussion
Affichage des résultats 1 à 5 sur 5

problème afficheur LCD



  1. #1
    invitee8b4fb3e

    problème afficheur LCD


    ------

    Bonjour à tous,

    Je suis en ce moment sur un projet et je suis coincé sur le même problème depuis plusieurs jours.
    Je pilote un afficheur LCD 16 caractères en 8 bits avec un PIC 16F84A.
    Dans mon programme C, j'affiche sur l'écran : "courant: . ., . mA" et j'incrémente une variable "Res" pour tester que l'afficheur augmente bien la valeur affichée à l'écran.
    Le problème est que lorsque je lance le programme, l'afficheur affiche "courant: 00,3 mA" (cela veut dire que le programme à eu le temps de faire quelques boucles avant que l'afficheur s'allume) mais il reste fixe et n'incrémente pas la valeur affichée. d'où vient mon problème?
    je vous passe le listing de mon programme en pièce jointe.

    Merci pour votre aide.

    Floone

    -----
    Fichiers attachés Fichiers attachés

  2. #2
    invitee8b4fb3e

    Re : problème afficheur LCD

    Help me please!

  3. #3
    Murayama

    Re : problème afficheur LCD

    Bonjour!

    Une remarque sur votre programme: vous mettez des fonctions là
    où c'est inutile (fonction LCD)et vous n'en mettez pas là où il en
    faudrait.
    J'imagine que si vous écrivez le programme différemment, il tiendra
    en une demi-page. En clair:

    1. La fonction main est une succession d'ordres d'écriture de
    caractères. Pourquoi ne pas écrire une fonction
    WriteString(char *str); qui peut éventuellement appeler une fonction
    WriteChar(char c); ? Et je m'autoriserais même une fonction
    SetPos(uint8 pos); Et une fonction InitLCD();
    Avec une variable globale CrtPos initialisée au début à 0, on aurait:

    void InitLCD() {
    RS = 0; // envoi d'instructions ‡ l'afficheur.
    RW = 0; // mode Ècriture.
    E = 1; // validation de la communication.
    port_B = 0x0C; // instruction : Allume l'afficheur.
    DELAY_MS(2); // attente de 2ms.
    E = 0; // fin de la communication.
    E = 1;
    port_B = 0x38; // instruction : envoi des donnÈes sur 8 bits, affichage 2 lignes.
    DELAY_MS(2);
    E = 0;
    }

    void SetPos(uint8 pos) {
    E = 1;
    port_B = pos;
    DELAY_MS(2);
    E = 0;
    }

    void WriteChar(char c) {
    E = 1;
    RS = 1;
    port_b = c;
    DELAY_MS(2);
    E = 0;
    }

    void WriteString(char * str) {
    uint8 i;
    while(str[i] != 0) {
    SetPos(CrtPos);
    CrtPos++;
    WriteChar(str[i]);
    }
    }

    Votre fonction main devient:

    void main(void) {
    CrtPos = 0;
    InitLCD();
    WriteString("Courant:,mA");
    while(1) {
    Affichage(Res);
    Res = Res+1;
    delay_ms(500);
    }
    }

    D'autre part, pour la fonction LCD(long int n):
    Pourquoi mettre un long int ch puisque vous ne comptez que
    jusqu'à 10?
    D'autre part, pourquoi ne pas remplacer la fonction complète par
    port_B = 0x30 + val;
    val étant la valeur diza, unit ou dizi? Cette fonction ne sert à rien.

    Dernier point, à vérifier. Je n'utilise jamais de LCDs à caractères,
    mais il me semble que le chip enable (E, je pense), n'a pas à
    être bougé en permanence. Vous pouvez laisser le LCD sélectionné
    durant toute l'opération d'écriture.

    Ah non, encre une chose:
    Écrire RS = 0, c'est bien, mais si vous relisez votre programme dans
    3 mois, vous ne comprendrez plus rien. Pourquoi 0?
    Je suggère:

    #define DATA 1
    #define CMD 0

    Et vous écrivez:
    RS = CMD; pour envoyer une commande ou bien:
    RS = DATA; pour envoyer des données.

    De même, vous pourriez définir:
    #define LCD_ON 0x0C
    De cette façon, quand vous initialisez le LCD, vous écrivez:

    port_B = LCD_ON;

    et le code devient auto-commenté. On comprend même sans le
    commentaire.

    de la même façon,

    #define TWO_LINES_8_BIT 0x38

    pourrait être plus élégant.

    Pascal


    Citation Envoyé par Floone Voir le message
    Bonjour à tous,

    Je suis en ce moment sur un projet et je suis coincé sur le même problème depuis plusieurs jours.
    Je pilote un afficheur LCD 16 caractères en 8 bits avec un PIC 16F84A.
    Dans mon programme C, j'affiche sur l'écran : "courant: . ., . mA" et j'incrémente une variable "Res" pour tester que l'afficheur augmente bien la valeur affichée à l'écran.
    Le problème est que lorsque je lance le programme, l'afficheur affiche "courant: 00,3 mA" (cela veut dire que le programme à eu le temps de faire quelques boucles avant que l'afficheur s'allume) mais il reste fixe et n'incrémente pas la valeur affichée. d'où vient mon problème?
    je vous passe le listing de mon programme en pièce jointe.

    Merci pour votre aide.

    Floone

  4. #4
    invitee8b4fb3e

    Re : problème afficheur LCD

    Merci beaucoup pour votre réponse!
    Je ne suis pas très à l'aise en programmation, mais merci pour vos conseils!
    Pouvez-vous m'expliquer le fonctionnement de la fonction "void WriteString(char * str)" ? merci

  5. A voir en vidéo sur Futura
  6. #5
    Murayama

    Re : problème afficheur LCD

    Bonjour!

    La fonction WriteString:
    Une chaîne de caractères se termine toujours par un caractère 0.
    Par exemple, si je déclare char * str = "hello";, la chaîne prend
    6 caractères en mémoire. Les 5 de hello et un sixième qui est nul.

    Au cas où vous ne le sauriez pas:
    - str est un pointeur. Un pointeur, c'est une adresse, et str indique
    l'adresse du premier élément de la chaîne (adresse de h). str+1
    indique l'adresse du 2ème élément (adresse de e), etc...
    - * sert à indiquer le contenu du pointeur. Par exemple *(str+2)
    est le contenu de l'adresse (str+2), donc un 'l'.

    Dans la fonction WriteChar(char c), je passe la valeur de la variable
    c (je dis que c est un caractère), puisqu'il n'y a qu'une variable.
    Dans la fonction WriteString(char * str), je passe l'adresse de la
    chaîne en disant simplement que *str est un caractère. Ce qui
    signifie que str est un pointeur. On peut interpréter char * str
    de deux façons équivalentes:
    char *str : le contenu de l'adresse str est un caractère
    char* str : str est un pointeur de caractères.

    Si j'ai une fonction d'écriture WriteChar(char c);, je peux l'utiliser
    pour tous les caractères de "Hello".

    Donc, j'écris:
    Code:
    WriteString(char * str) {
        uint8 i = 0;
        while(str[i] != 0) {
            WriteChar(str[i]);
            i = i+1;
        }
    }
    En français, ça donne:

    tant_que_le_caractere_a_la_i-eme_place_n_est_pas_nul {
    ecrire_i-eme_caractere;
    incrementer i;
    };

    Simplification du code:

    i++ signifie "i = i+1".

    Variantes de WriteString (on incrémente en même temps).

    Code:
    void WriteString(char * str) {
        uint8 i = 0;
        while(str[i] != 0) WriteChar(str[i++]);
    }
    Autre variante: On n'utilise pas de variable d'incrémentation,
    on incrémente directement l'adresse.

    Code:
    void WriteString(char * str) {
        while(*str != 0) WriteChar(*str++);
    }
    Autre chose. Tous les écrans graphiques que je connais
    incrémentent directement la position. Donc vous n'avez
    probablement pas à définir la position à chaque fois, mais la
    première fois seulement.

    Bon, maintenant, quelques conseils (tout le monde n'est pas
    forcément d'accord, ce n'est que mon opinion). Le style K&R
    est proche de l'idéal pour moi. K&R veut dire Kernighan and Richie,
    qui se sont rendus célèbres pour leur excellent livre sur le langage C.
    La bible du C, quoi.

    1. Longueur du code
    Pour qu'un morceau de code soit facilement compréhensible, il
    est préférable qu'il tienne en entier dans un écran. Donc de 20 à 50 lignes
    selon l'écran. On essaira donc de faire en sorte que toute fonction tienne
    moins de 1 écran.
    Corollaire: si une fonction est trop longue, il faut absolument la scinder
    en plusieurs.

    2. Une ligne sans code est une ligne inutile. Beaucoup de
    programmeurs sautent une ou deux lignes pour "aérer" le code.
    Cela ne sert à rien sauf s'il y a une explication. Si vous voulez sauter
    des lignes, faites le entre 2 fonctions, pas à l'intérieur d'une fonction.

    3. Les fonctions définies sur plusieurs lignes: ça prend beaucoup
    de place, et c'est inutile.
    Exemple de ce que l'on voit de pire:
    Code:
    void
    DrawRectangle(
        uint16 x,
        uint16 y,
        uint16 w,
        uint16 h,
        uint32 color)
    {
        // Implementation
    }
    alors qu'il est si facile d'écrire:

    Code:
    void DrawRect(uint16 x, uint16 y, uint16 w, uint16 h, uint32 color) {
        // Implementation
    }

    Citation Envoyé par Floone Voir le message
    Merci beaucoup pour votre réponse!
    Je ne suis pas très à l'aise en programmation, mais merci pour vos conseils!
    Pouvez-vous m'expliquer le fonctionnement de la fonction "void WriteString(char * str)" ? merci

Discussions similaires

  1. afficheur LCD problème affichage
    Par invitec205d090 dans le forum Électronique
    Réponses: 28
    Dernier message: 15/05/2010, 14h50
  2. Problème afficheur LCD
    Par invite7daf4c9b dans le forum Électronique
    Réponses: 9
    Dernier message: 04/05/2010, 09h58
  3. probléme afficheur LCD
    Par invitea8b2e1f5 dans le forum Électronique
    Réponses: 2
    Dernier message: 18/12/2009, 15h00
  4. Probleme afficheur lcd
    Par invite456a9298 dans le forum Électronique
    Réponses: 5
    Dernier message: 24/08/2008, 14h23
  5. afficheur lcd en afficheur 7 segment
    Par invite3cc40cdb dans le forum Électronique
    Réponses: 3
    Dernier message: 04/02/2008, 09h43
Découvrez nos comparatifs produits sur l'informatique et les technologies.