Répondre à la discussion
Affichage des résultats 1 à 21 sur 21

Gestion d'un afficheur lcd 4x20 avec pic18f4550



  1. #1
    demonkyuubi

    Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Bonjour à tous.

    J'essaye en ce moment, pour un projet, de dompter un afficheur LCD 4x20 lignes display204A de chez displaytech. En m'aidant de la datasheet et en googlisant, j'ai réussi à comprendre certaines choses sur le fonctionnement. En m'inspirant GRANDEMENT du site http://nalhossri.free.fr/LCD4bits.h/LCD4bits.h.html (merci à lui), j'ai adapté son programme à mon pic. Enfin c'est ce que je pensais. Avec le programme suivant, lorsque je lance l’exécution, il ne se passe RIEN. Même la variation du contraste de l'écran avec VO ne fonctionne pas. Si vous pouviez m'aider, je vous en serais reconnaissant.

    Merci.

    #include<p18f4550.h>


    // met le portD comme data

    #define DATA PORTD

    //définir les 3 LSB du port E comme RS/RW/E

    #define LCD_RS PORTEbits.RE0
    #define LCD_RW PORTEbits.RE1
    #define LCD_E PORTEbits.RE2



    //fonction qui envoie un octet de controle pour modifier la config du LCD

    void ecr_ctrl(byte ctrl)
    {
    DATA=ctrl; //ctrl placé sur le bus de donnée
    LCD_RS=0; //envoie un octet de COMMANDE
    LCD_RW=0; //écriture dans la ram du LCD
    LCD_E=1;
    LCD_E=0; //validation par front descendant sur E
    busy_lcd; //test du busy

    }

    /////fonction du test busy: test si le LCD est prêt à recevoir un octet de donnée ou de commande.

    void busy_lcd(void)
    {

    signed char temp; //valeur tampon
    TRISD=0; //port data en entrée
    LCD_RS=0; //commande
    LCD_RW=1; //lecture de la RAM


    do{
    LCD_E=1;
    temp=DATA; //port data dans temp
    LCD_E=0;
    LCD_E=1; //retard
    LCD_E=1;
    LCD_E=0; //validation sur E
    }
    while(temp<0); boucle si busy=1

    LCD_RW=0; //ecriture dans la RAM
    TRISD=1; //port data en sortie
    }


    /////initialisation du lcd
    void init_lcd(curseur);
    {
    TRISD=0xFF; //portD en sortie
    TRISE=0b00000111; //RE0,RE1,RE2 en sortie
    busy_lcd(); //test du busy, attend que le lcd soit prêt


    ecr_ctrl(0b00111000); // adressage 8 bits, afficheur 4 lignes, caractères 5*7
    ecr_ctrl(0b00000110); // direction du curseur quand il bouge: droite
    ecr_ctrl(0b000000001); // efface l'écran, et met curseur en haut à gauche

    switch(curseur)
    {
    case 0:
    ecr_ctrl(0b00001100); // affichage actif, curseur OFF
    break;
    case 1:
    ecr_ctrl(0b00001110); //affichage actif, curseur ON, non clignotant
    break;
    case 2:
    ecr_ctrl(0b00001111); //affichage actif, curseur ON, clignotant
    break;
    default:
    break;
    };
    }



    ////fonction d'écriture d'un seul caractère sur l'afficheur

    void ecr_data(byte data)
    {
    DATA=data; //met le mot sur le bus de donnée
    LCD_RS=1; // octet de donnée
    LCD_RW=0; //ecriture dans la RAM
    LCD_E=1;
    LCD_E=0; // validation avec E
    busy_lcd();
    }


    void main ()
    {

    init_lcd(2);

    }

    -----


  2. Publicité
  3. #2
    laurentnic

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Bonjour

    La variation du contraste devait marcher car c'est du hard!!!!

    La fonction init lcd dans le main n'est pas suffisante.

    il faut un while(1) et appeler tes fonctions lcd en envoyant un caractère au début sur le lcd.

    je n'ai pas vérifié tes fonctions lcd!!!!

    cordialement

    Laurent

  4. #3
    demonkyuubi

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    J'ai testé uniquement en alimentant le LCD et le rétroéclairage en 5V, et en testant le contraste avec un potentiomètre. Cela ne fait absolument rien. Le rétroéclairage fonctionne parfaitement, mais pas le contraste. Peut-être faut-il un message pour voir l'effet du contraste ?

  5. #4
    Forhorse

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Mais ton compilateur n'a t-il pas directement les librairies d’intégré pour piloter ce genre d'afficheur ? car c'est quand même la base...

  6. #5
    demonkyuubi

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Je viens de regarder et tu as raison, une librairie xlcd.h existe déjà sur mon compilateur (MCC18). Coté Hardware, j'ai refait les branchements avec mes yeux au bon endroit, et le contraste fonctionne. Je vous enverrai le code que j'ai, mais pour le moment, je n'arrive à afficher que le curseur clignotant, et à un endroit aléatoire de l'écran.

  7. A voir en vidéo sur Futura
  8. #6
    demonkyuubi

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    bonsoir

    La librairie xlcd ayant besoin d'être modifiée pour correspondre à mon branchement, je l'ai modifiée comme suit:

    /* DATA_PORT defines the port to which the LCD data lines are connected */
    #define DATA_PORT PORTB
    #define TRIS_DATA_PORT TRISB

    /* CTRL_PORT defines the port where the control lines are connected.
    * These are just samples, change to match your application.
    */
    #define RW_PIN PORTEbits.RE1 /* PORT for RW */
    #define TRIS_RW TRISEbits.TRISE1 /* TRIS for RW */

    #define RS_PIN PORTEbits.RE2 /* PORT for RS */
    #define TRIS_RS TRISEbits.TRISE2 /* TRIS for RS */

    #define E_PIN PORTEbits.RE0 /* PORT for E */
    #define TRIS_E TRISEbits.TRISE0 /* TRIS for E */
    J'ai ensuite mis toutes les fonctions du xlcd dans mes sources files (busyxlcd, openxlcd, etc.)

    Le programme que j'utilise est le suivant, mais il ne fonctionne absolument pas. Je peux compiler et l'envoyer sur l'écran lcd sans problème, mais l'écran ne réagit pas (même pas le clignotement attendu).

    #include<p18f4550.h>
    #include <xlcd.h>
    #include <delays.h>

    #pragma config FOSC=HS

    void OpenXLCD(PARAM_SCLASS unsigned char);
    void putrsXLCD(const rom char *);
    void SetDDRamAddr(PARAM_SCLASS unsigned char);
    void WriteCmdXLCD(PARAM_SCLASS unsigned char);


    void DelayPORXLCD(void) {
    Delay1KTCYx(15);
    }
    void DelayFor18TCY(void) {
    Delay10TCYx (2);
    }
    void DelayXLCD(void) {
    Delay1KTCYx(20);
    }

    void main (void)
    {
    OpenXLCD(EIGHT_BIT & LINES_5X7); //lcd en mode 8 bits et caractères 5x7
    SetDDRamAddr(0x00); //place le curseur en haut à gauche
    WriteCmdXLCD(DON & BLINK_ON & CURSOR_ON); // curseur clignotant, et affichage actif
    putrsXLCD("bonjour"); //affichage du mot "bonjour"
    while(1);
    }
    Le problème viendrait-il de ma non utilisation du busy ? Et si oui, où l'utiliser ?


    Merci et bonne soirée.

  9. Publicité
  10. #7
    RISC

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Salut,

    Pour les modules LCD, 2 manières de procéder :
    1/ après chaque commande tu testes BUSY pour savoir si le module LCD a fini de traiter la commande
    2/ tu mets une tempo supérieure au délai max de la commande (pour cela, il faut impérativement connaitre la référence du controleur LCD utilisé dans ton module.


    La datasheet de ton module est celle-ci : http://www.pmb.co.nz/downloads/lcd_204a_series.pdf
    En lisany tu verras que le controleur LCD est le KS0066U (un grand classique) et tu trouveras pour chaque commande le temps nécessaire à l'exécution.
    Adapte les timings pour être sûr (si tu choisis la méthode 2/) que tu laisseras assez de temps à chaque commande pour être traitée.

    CHAQUE MODULE LCD POSSEDE DES TIMINGS DIFFERENTS : c'est de là que viennent 99% des problèmes ;=)

    a+
    Ma marotte ? les microcontrôleurs ;=)

  11. #8
    demonkyuubi

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Si je comprends bien ce que tu dis et ce que je lis sur la doc p6/17, le Busyflag n'est pas dispo de suite. Il faut d'abord initialiser le lcd par une série de tempos et de fonction_set.

    En gros, mon programme devra être de ce type:

    tempo 15ms mini (le temps que VDD monte à 4.5v)
    fonction_set
    tempo 4,1 ms mini
    fonction_set
    tempo 100µs mini
    fonction_set

    A ce moment le BF peut être check (mais pas obligatoirement, si j'ai bien compris, le BF n'est qu'une alternative aux tempos entre les commandes)

    fonction_set (avec mes paramètres nombre de bits et taille des caractères)
    display_off
    display_clear
    entry_mode_set


    Et je met le tout dans une fonction "init". Et seulement ensuite je pourrai jouer à écrire "bonjour" sur l'écran (tout en mettant des tempos ou une lecture du BF entre chaque commande)?

    Je testerai tout cela demain, merci pour ton aide, j'y vois un peu plus clair.

  12. #9
    RISC

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Salut,

    Tu as effectivement compris la séquence de démarrage absolument nécessaire avant de commencer à écrire des caractères.

    Autre petite info. Le compilateur C18 est fourni avec une librairie XLCD (fouille dans les répertoires).

    Tu devrais aussi trouver un exemple de driver LCD dans le code fourni avec la carte PICDEM2PLUS : http://www.microchip.com/PICDEM2PLUS

    a+
    Ma marotte ? les microcontrôleurs ;=)

  13. #10
    demonkyuubi

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    En trifouillant le fichier Openxlcd fourni, je viens de voir qu'il contient ceci:

    // Delay for 15ms to allow for LCD Power on reset
    DelayPORXLCD();
    //-------------------reset procedure through software----------------------
    WriteCmdXLCD(0x30);
    Delay10KTCYx(0x05);

    WriteCmdXLCD(0x30);
    Delay10KTCYx(0x01);


    WriteCmdXLCD(0x32);
    while( BusyXLCD() );
    //------------------------------------------------------------------------------------------


    // Set data interface width, # lines, font
    while(BusyXLCD()); // Wait if LCD busy
    WriteCmdXLCD(lcdtype); // Function set cmd

    // Turn the display on then off
    while(BusyXLCD()); // Wait if LCD busy
    WriteCmdXLCD(DOFF&CURSOR_OFF&B LINK_OFF); // Display OFF/Blink OFF
    while(BusyXLCD()); // Wait if LCD busy
    WriteCmdXLCD(DON&CURSOR_ON&BLI NK_ON); // Display ON/Blink ON

    // Clear display
    while(BusyXLCD()); // Wait if LCD busy
    WriteCmdXLCD(0x01); // Clear display

    // Set entry mode inc, no shift
    while(BusyXLCD()); // Wait if LCD busy
    WriteCmdXLCD(SHIFT_CUR_LEFT); // Entry Mode

    // Set DD Ram address to 0
    while(BusyXLCD()); // Wait if LCD busy
    SetDDRamAddr(0x80); // Set Display data ram address to 0

    Si j'ai bien compris, c'est EXACTEMENT l'initialisation demandée (attendre 15ms, fonction_set, attendre, fonction_set etc.)
    Dans ce cas, pourquoi avec un main comme ca, cela ne fonctionne pas ?

    void main (void)
    {
    OpenXLCD(FOUR_BIT & LINES_5X7);

    while(BusyXLCD());
    WriteCmdXLCD(DON & BLINK_ON & CURSOR_ON);

    while(1);
    }
    Pourtant, juste avant le main j'ai bien déclaré les fonctions de tempos, que j'ai calculé avec Cycles = (TimeDelay * osc) / 4, sachant que mon osc est de 20MHz. Les DON,BLINK_ON, etc. sont définis dans la librairie xlcd.h

    void DelayPORXLCD(void) {
    Delay1KTCYx(75); //delais de 15ms
    }

    void DelayFor18TCY(void) {
    Delay100TCYx(100); // delais de 2ms
    }

    void DelayXLCD(void) {
    Delay10KTCYx(10);//delais 20ms
    }
    J'ai placé tous les fichier openxlcd.c, busyxlcd.c, etc. dans la liste de mes sources files.

    Merci pour votre aide, c'est assez désespérant quand on pense avoir compris quelque chose mais que cela ne fonctionne pas comme on l'attend.

  14. #11
    demonkyuubi

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Alors, cela s'est mis à fonctionner partiellement. Avec mon main comme ceci, je vois bien le curseur se déplacer à la 1ère colonne de chaque ligne, avec une tempo de 1sec à chaque fois (pour bien l'observer).
    void main (void)
    {
    OpenXLCD(EIGHT_BIT & LINES_5X7);


    while(BusyXLCD());
    WriteCmdXLCD(DON & BLINK_ON & CURSOR_ON);
    while(BusyXLCD());
    WriteCmdXLCD(SHIFT_DISP_LEFT & SHIFT_CUR_LEFT);
    while(BusyXLCD());
    SetDDRamAddr(0x00);
    Delay10KTCYx(500);
    SetDDRamAddr(0x40);
    Delay10KTCYx(500);
    SetDDRamAddr(0x14);
    Delay10KTCYx(500);
    SetDDRamAddr(0x54);

    while(1);

    }
    Cependant, nouveau problème. L'utilisation de la fonction putrsXLCD ne fonctionne pas comme prévu. J'ai l'impression que le lcd "confond" putrsXLCD, et setDDRamAddr. En effet, quand j'écris putrsXLCD("A"), le curseur se positionne à la 2nde ligne, et à la 2nde colonne, ce qui correspond exactement à un SetDDRamaddr(0x41). Avec putrsXLCD("B"), le curseur se positionne comme SetDDRamaddr(0x42). Dans le cas de plusieurs caractères, putrsXLCD("aBc"), c'est le "c" qui prime. La même chose se produit si je remonte à la fonction de base WriteDataXLCD(aBc). Voici donc un nouveau problème bien bizarre, si quelqu'un a déjà eu ce problème (et en a trouvé la solution), ce serait super.

    Merci.

  15. #12
    demonkyuubi

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    J'ai lu dans certaines discussions qu'il fallait utiliser LATX au lieu de PORTX. Mais où l'utiliser ? Le seul endroit où je déclare des ports est dans la librairie xlcd.h. Il faudrait le mettre à la place de PORTB, ou alors des PORTEbits ?

    /* DATA_PORT defines the port to which the LCD data lines are connected */
    #define DATA_PORT PORTB
    #define TRIS_DATA_PORT TRISB

    /* CTRL_PORT defines the port where the control lines are connected.
    * These are just samples, change to match your application.
    */
    #define RW_PIN PORTEbits.RE2 /* PORT for RW */
    #define TRIS_RW TRISEbits.TRISE2 /* TRIS for RW */
    #define RS_PIN PORTEbits.RE1 /* PORT for RS */
    #define TRIS_RS TRISEbits.TRIE1 /* TRIS for RS */
    #define E_PIN PORTEbits.RE0 /* PORT for D */
    #define TRIS_E TRISEbits.TRISE0 /* TRIS for E */

  16. Publicité
  17. #13
    RISC

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Salut,

    L'utilisation de LATx est recommandée et utilisable uniquement pour les broches en sortie.
    Pour les broches en entrée il faut impérativement utiliser PORTx

    Es-tu sûr que tes tempos sont bonnes ?
    As-tu vérifié que tu ne restes pas bloqué dans un test du bit busy ?


    a+
    Ma marotte ? les microcontrôleurs ;=)

  18. #14
    demonkyuubi

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Bon, et bien j'ai réglé mon problème. J'ai crée un LATx pour mon port de data et pour RS/RW/E, et j'ai modifié chaque sous programme (openxlcd.c etc.) à chaque fois que le tris=0 (en sortie), j'ai remplacé mon portx par latx.


    Alors merci pour votre aide .

    Et merci de ne pas fermer ce sujet, j'aurai sans doute d'autres soucis par la suite, mon but n'étant pas uniquement d'afficher de jolis messages.

  19. #15
    hoffmann

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Je suis content pour toi que ça marche !

    Tu l'as acheté ou ton écran ?
    Hoffmann

  20. #16
    demonkyuubi

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Je ne l'ai pas acheté moi même mais il me semble que c'était sur radiospares.

    Prochaine étape, envoyer sur l'affichage une tension variable (celle du potar).

  21. #17
    demonkyuubi

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    1er problème.

    Avant même de penser à envoyer la valeur de ma tension sur le lcd, il faudrait déjà que je réussisse à envoyer ne serait-ce qu'un entier qui peut changer.

    for (i=0;i<10;i++)
    {
    while(BusyXLCD());
    SetDDRamAddr(0x05);
    putrsXLCD(i);
    Delay10KTCYx(500);
    }
    Avec ceci, le lcd m'affiche chaque seconde un message incompréhensible. Et le compilateur me renvoie un warning: suspicious pointer conversion.
    C'est surement du au fait que je tente de lui faire passer un entier pour un char, et qu'il n'aime pas se faire duper. Il me semble qu'il y a un moyen, avec une fonction ftoa.c. Sauf que je n'ai pas ce programme.
    La fonction sprintf aussi peut faire ca, mais en mettant

    int i;
    char b[50];
    et sprintf (b‚ "%d"‚ i); dans le for, il me crache une syntax error (j'ai pourtant stdio.h dans mes include)


    Une petite aide ?

  22. #18
    RISC

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Salut,

    T'inquiètes pas du message "suspicious pointer converion". C'est juste un warning pour te rappeler que les types ne sont pas compatibles.
    Si tu sais ce que tu fais pas de PB. Je me souviens d'une version du compilateur C18 qui était très "sensible" et générait des multitudes de messages.
    Par la suite (version ultérieures) cela était revenu à un niveau raisonnable.
    La méthode la plus simple est de caster (cela supprime les warnings) ;=)

    Pour le sprintf il faut lire la documentation : c:\Program Files (x86)\Microchip\mplabc18\v3.40 \doc\hlpC18Lib.chm pour connaitre la syntaxe correcte

    a+

    a+
    Ma marotte ? les microcontrôleurs ;=)

  23. Publicité
  24. #19
    demonkyuubi

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Bonsoir !

    L'affichage de la tension de mon potentiomètre fonctionne parfaitement. J'avais du faire une erreur dans le sprintf.
    Prochaine étape, me faire un compte à rebours, déclenchable par interruption.


    Bonne soirée et merci.

  25. #20
    demonkyuubi

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Bonsoir.

    J'ai un peu travaillé mon compte à rebours, et il fonctionne. Je l'ai mis dans une fonction:

    Code:
    void compterebours(int *pointeurmin, int *pointeursec)
    {
    int init_min=*pointeurmin;
    int init_sec=*pointeursec;
    char buffer2[20];
    char buffer[20];
    
    while(1)
    {
    					if (*pointeursec<=59)
    						{
    
    						sprintf(buffer, "%d", *pointeursec);
    						sprintf(buffer2, "%d", *pointeurmin);
    
    						SetDDRamAddr(0x56);
    
    								if (*pointeurmin<10){putchar('0');}	
    		
    						putsXLCD(buffer2);
    						putrsXLCD(":");
    
    								if (*pointeursec<10){putchar('0');}	
    
    						putsXLCD(buffer);
    						Delay10KTCYx(250);
    						Delay10KTCYx(250); //delais 0.5sec
    
    								if(*pointeursec==0)
    									{
    										*pointeursec=init_sec+1;
    											if(*pointeurmin==0)
    												{
    												SetDDRamAddr(0x56);
    												putrsXLCD("Temps ecoule");
    												break;
    												}
    											else *pointeurmin=*pointeurmin-1;
    									}
    											
    	
    						}
    
    					*pointeursec=*pointeursec-1;
    
    }
    }
    Je l'appelle dans le main avec
    Code:
    int minute=1;
    int seconde=8;
    compterebours(&minute,&seconde);
    J'ai donc un compte à rebours de 1min08 qui marche bien et qui m'affiche "temps écoulé" à la fin du décompte. Comme vous pouvez le voir j'ai utilisé des pointeurs pour les minutes et secondes. Je l'ai fait car je pensais que les pointeurs allaient rendre mes minutes et secondes visibles partout dans le programme.

    Sauf qu'il n'en est rien. Dans ma fonction d'interruption, j'essaye tout d'abord d'afficher mes minutes/seconde présentes au moment de l'interruption (sur le portB dans mon cas). Sauf qu'il me lance la belle erreur du "pointeursec has not been defined". Il ne le connait pas donc... Si je tente d'afficher un message quelconque pour vérifier que j'entre dans mon interruption, cela fonctionne.

    Help ?

  26. #21
    demonkyuubi

    Re : Gestion d'un afficheur lcd 4x20 avec pic18f4550

    Il y avait une petite erreur qui faisait que les secondes ne se remettaient pas à 59 après une décrémentation de minute, c'est réglé. Reste mon problème de variable globale partout sauf dans la fonction interruption.

Sur le même thème :

Discussions similaires

  1. Réponses: 5
    Dernier message: 20/10/2011, 23h01
  2. Gestion d'un afficheur LCD 4x16
    Par ratoto dans le forum Électronique
    Réponses: 5
    Dernier message: 28/07/2008, 19h46
  3. Gestion LCD avec PIC18F4550
    Par ZeloS dans le forum Électronique
    Réponses: 3
    Dernier message: 04/01/2008, 16h36
  4. lcd HD44780 4x20
    Par sdow dans le forum Électronique
    Réponses: 11
    Dernier message: 27/11/2006, 10h50
  5. Gestion d'un afficheur avec un PIC
    Par Patou le fou dans le forum Électronique
    Réponses: 3
    Dernier message: 08/12/2005, 21h28