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

Pic et driver pour GLCD



  1. #1
    mortaurat

    Pic et driver pour GLCD


    ------

    Bonjour,
    je me suis acheté une plaque QL_200 sur ebay avec un petit afficheur graphique LCD.
    Le microcontroleur de l'afficheur est un ST7921, je programme sous CCS.
    n'arrivant pas à trouver un driver pour piloter cet afficheur, j'ai essayé d'en faire un. Mais, pour je ne sais qu'elle raison il n'affiche strictement rien.

    Voici mon code.
    Code:
    #include <16f876.h>
    #use delay (clock = 4000000)
    
    #define  rs  PIN_A5                    //COMMNAD/DATA SELECT
    #define  rw  PIN_A4                    //READ/WRITE SELECT             
    #define  e   PIN_A3                    //ENABLE SIGNAL                 
    #define  psb PIN_A2                    //PARALLEL/SERIAL 
    #define  rst PIN_A0                    //RESET SIGNAL   
    //data are send with the port b.
    
    void lcd_init();                    //LCD init
    void lcd_clear();                   //clear lcd display and cursor back to home
    void lcd_display(unsigned char);                 //affichage lcd
    void lcd_instruction(unsigned char, int);             //send instruction to lcd
    void lcd_data(unsigned char);                    //send data to lcd
    
    const unsigned char TAB[]={'A','B','C','D','E','F','g','h','i','j','k','L','M' };
    int i ;
    void main ()
    {
    delay_ms(30);
    lcd_init();
    delay_ms(10);
    lcd_clear();
    delay_ms(5);
    for(i=0; i<8;i++)
    {
    lcd_display (TAB[i]);
    delay_ms(500);
    }
    }
    //initialisation du LCD 
    void lcd_init()
    {
      output_low(rst);                  //reset LCD
      delay_ms(10);                       
      output_high(rst);                //LCD normal work.
      output_high(psb);               //8 bit as parrallel.
      delay_ms(1);
    } 
    void lcd_clear ()
    {
    lcd_instruction(0x01,2);          //clear display and cursor back to home
    delay_ms(2);
    }
    void lcd_display(unsigned char data)
    {
       lcd_data(data); 
    }
    
    void lcd_instruction (unsigned char x, int tempo)
    {
     output_low(rs);                         //data not commnad. 
       output_low(rw);                         //write not read.   
       output_b(x);                      //data to bus.       
       output_high(e);                          //enable.           
       delay_ms(tempo);
       output_low(e);                         //disable. 
    }
    
    void lcd_data (unsigned char x)
    {
       output_high(rs);                        //data not commnad. 
       output_low(rw);                        //write not read.   
       output_b(x);                     //data to bus.       
       output_high(e);                         //enable.           
       delay_ms(1);
       output_low(e);                         //disable. 
    }
    Normalement pas d'erreur de cablage vu que c'est sur la platine. Je pense que ca doit être à cause des delay, mais je ne sais pas du tout quoi changer.

    Avez vous une idée ?

    Merci

    -----

  2. Publicité
  3. #2
    mortaurat

    Re : Pic et driver pour GLCD

    Personne ?

  4. #3
    Alain94360

    Re : Pic et driver pour GLCD

    Citation Envoyé par mortaurat Voir le message
    Personne ?
    juste au cas ou... une piste...
    un gars avait eu un soucis avec le réglage de contraste... est-ce que tu vois l'afficheur s'initialiser ...

    sinon essaye de multiplier les délais par 10, et si ca marche, de les réduire un par un...

    sinon sur le site du fabriquant ils parlent de
    Sample with C and ASM Program sources code as below (using PIC16F877A):

    ...
    * 128x64 GLCD (See the following Photos)
    * 1602 LCD (See the following Photos)
    ...

  5. #4
    mortaurat

    Re : Pic et driver pour GLCD

    Bonjour,
    tout dabord merci de ta reponse.

    Je n'est pas de probléme de constrast, le LCD s'allume parfaitement et il est d'ailleur controlé par un petit potentiomettre.

    je pensais justement que mes tempo etaient trop grandes et que ca pouvais poser des problémes. Le temps moyen d'une instruction (sauf clear et return) est d'environ 450 ns.
    Je me suis dit qu'il valait mieux en avoir trop que pas assez...

    Oui en effet il y avais un code source en assembleur et en C. Mais qui ne marche pas sur mon compilo.
    Je me suis grandement inspiré de ce dernier.
    le voici:
    Code:
    //THE experiment is to familiarity the use of 12864LCD
    //12864LCD with the lib of chinese      
    //program to display company's logo and tel.
    //the configration of hardware   
    //Tip:Please open RA4 pull UP, will S10'S NO.4 in the "on"   ,Jump J14 all connect, 
    
     #include<pic.h>
     __CONFIG(0x1832);        
    //__CONFIG _DEBUG_OFF&_CP_ALL&_WRT_HALF&_CPD_ON&_LVP_OFF&_BODEN_OFF&_PWRTE_ON&_WDT_OFF&_HS_OSC
     
    
    #define  rs  RA5                    //COMMNAD/DATA SELECT            
    #define  rw  RA4                    //READ/WRITE SELECT              
    #define  e   RA3                    //ENABLE SIGNAL                  
    #define  psb RA2                    //PARALLEL/SERIAL SELECT£¨H/L£©  
    #define  rst RA0                    //RESET SIGNAL                   
    #define  nop()  asm("nop")          //nop func
    
    //ÉîÛÚǬÁúÊ¢µç×Ó
    const unsigned char TAB1A[ ]={0xC9,0xEE,0xDB,0xDA,0xC7,0xAC,0xC1,0xFA,0xCA,0xA2,0xB5,0xE7,0xD7,0xD3};
    //WWW.PIC16.COM
    const unsigned char TAB1B[ ]={' ', ' ', 'W', 'W', 'W', '.', 'P', 'I', 'C', '1','6', '.', 'C', 'O', 'M', ' '};      
    //TEL0755-28187975
    const unsigned char TAB1C[ ]={'T', 'E', 'L' ,'0' ,'7', '5' ,'5','-', '2', '8','1', '8' ,'7','9' ,'7','5'};    
    //FAX0755-28187976     
    const unsigned char TAB1D[ ]={'F', 'A', 'X', '0', '7', '5', '5', '-','2', '8','1', '8', '7', '9', '7', '6'};       
     unsigned int lcd_x;                //X address    
     unsigned int lcd_y;                //Y address    
      bit busy;                         //busy flag    
    
    void init();                        //system init.   
    void lcd_init();                    //LCD init       
    void clear_p();                     //clear screen   
    void han_wr2a();                    //company name.
    void han_wr2b();                    //company website.
    void han_wr2c();                    //company tel.
    void han_wr2d();                    //company fax.
    void wr_zb();                       //display setting mode.
    void flash();                       //lcd blink func.
    void qushu(int counts,const unsigned char *ps);       //search table.
    void send_d(unsigned char x);       //send data
    void send_i(unsigned char x);       //send command.
    void chk_busy();                    //check busy sub.
    void delay();                       //delay func, decide the speed of display.
    void delay1();                      //delay func, decide the speed of blink.
    
    //-------------------------------------------
    //main
    void main()
    {
       while(1)
         {
           init();                      //system init.
           lcd_init();                  //    
           clear_p();                   //    
           han_wr2a();                  //company name.        
           han_wr2b();                  //company website.     
           han_wr2c();                  //company tel.     
           han_wr2d();                  //company fax.     
           delay();                     //
           flash();                     //
           clear_p();                   //
         }
    }
    
    //-------------------------------------------
    //I/O¿Ú setting func.
    void init()
    {
      TRISA=0X00;                       //A port as output         
      TRISD=0X00;                       //d port as output         
      ADCON1=0X06;                      //A port as ordinary i/o   
    }
    
    //-------------------------------------------
    //-------------------------------------------
    void lcd_init()
    {
      rst=0;                         //reset LCD
      delay();                        
      rst=1;                         //LCD normal work.
      nop();        
      psb=1;                         //8 bit as parrallel.
      send_i(0x30);                  //basic operation instruction
      send_i(0x01);                  //off display  
      send_i(0x06);                  //set the cursor's moving direction.
      send_i(0x0c);                  //on display,off cursor,off blink
    }
    
    //-------------------------------------------
    //company name.
    void han_wr2a()
    {
      send_i(0x81);                     //set display position
      qushu(0xe,TAB1A);                 //get data from table
    }
    
    //-------------------------------------------
    //company website.
    void han_wr2b()
    {
      send_i(0x90);                    //set display position  
      qushu(0x10,TAB1B);               //get data from table   
    }  
      
    //-------------------------------------------
    //company tel.
    void han_wr2c()
    {
      send_i(0x88);                   //set display position  
      qushu(0X10,TAB1C);              //get data from table   
    }
    
    //-------------------------------------------
    //company fax.
    void han_wr2d()
    {
      send_i(0x98);                  //set display position  
      qushu(0X10,TAB1D);             //get data from table   
    }
    
    //display setting.
    void wr_zb()
    {
      send_i(lcd_y);
      send_i(lcd_x);
    }
    
    //-------------------------------------------
    //blink
    void flash()
    {
      send_i(0x08);                  //off display.
      delay1();                      //delay
      send_i(0x0c);                  //on display
      delay1();
      delay1();                      //delay
      send_i(0x08);                  //off
      delay1();
      send_i(0x0c);                  //on
      delay1();
      delay1();
      send_i(0x08);                  //off
      delay1();
      send_i(0x0c);                  //on
      delay1();
      delay1();
    }
    
    //-------------------------------------------
    //clear screen
    void clear_p()
    {
      send_i(0x1);                   //clear all
      send_i(0x34);                  //extend.
      send_i(0x30);                  //basic
    }
    
    //------------------------------------------
    //search.
    void qushu(int counts,const unsigned char *ps)
    {
      int i;                         //define loop count.
      for(i=counts;i>0;i--)          //
         {  
            send_d(*ps);             //
            delay();                 //
            ps++;                    //get next.
         }
    }
    
    //-------------------------------------------
    //display the next.
    void send_d(unsigned char x)
    {
       chk_busy();                  //check busy.
       rs=1;                        //data not commnad.  
       rw=0;                        //write not read.    
       PORTD=x;                     //data to bus.       
       e=1;                         //enable.            
       nop();
       nop();
       nop();                       
       e=0;                         //disable.
    }
    
    //--------------------------------------------
    //send command.
    void send_i(unsigned char x)
    {
       chk_busy();                   //check lcd if busy. 
       rs=0;                         //data not commnad.  
       rw=0;                         //write not read.    
       PORTD=x;                      //data to bus.       
       e=1;                          //enable.            
       nop();
       nop();
       nop();
       e=0;                         //disable.
    }
    
    //-------------------------------------------
    //check lcd busy.
    void chk_busy()
    {  
       busy=1;                      //set busy signal                   
       TRISD=0XFF;                  //change the bus to input.          
       rs=0;                        //command not data.                 
       rw=1;                        //read not write.                   
       while(busy)                  
          {
             nop();
             nop();
             nop();
             e=1;                   //enable.
             nop();
             nop();
             nop();
             if(!RD7) busy=0;       //
             nop();
             nop();
             nop();
             e=0;                   //DISABLE.
          }
       e=0;                         //DISABLE.
       TRISD=0X00;                  //bus as output.
     }
    
    //-------------------------------------------
    //delay
    void delay()
    {
        int i;
        for(i=0;i<5000;i++)
           {;}
    }
    
    //-------------------------------------------
    //delay1
    void delay1()
    {
        int i;
        for(i=0;i<10;i++)
          {
            delay();               //call delay.
          }
    }
    En gros il distingue instruction et donnée (normal), il utilise un tableaux de caractere et envoi dans la fonction "qushu" le nombre de caractére que contient ce tableaux, ainsi que le code ascii du caractere a afficher.
    Puis il lest affiche un à un.

    J'ai remplacé dans mon code les "nop" par des delay, peut être que l'erreur vient de là...

  6. A voir en vidéo sur Futura
  7. Comparatifs

    Gagnez du temps et de l'argent grâce à nos comparatifs de produits. Parmi nos sujets :
  8. #5
    Alain94360

    Re : Pic et driver pour GLCD

    Citation Envoyé par mortaurat Voir le message
    J'ai remplacé dans mon code les "nop" par des delay, peut être que l'erreur vient de là...
    mon seul honneur est d'avoir potassé divers docs de contrôleurs vite fait pour en choisir un ...

    tu parle d'opération NOP dans le LCD (pas dans le uC)... bonne idée!
    a lire certains docs, les NOP sont utiles pour assurer des synchro internes dans les LCD.

    autre piste, comment fonctionnent les fameux délais ? peut être qu'ils sont mal étalonnés pour ton uC?

  9. #6
    mortaurat

    Re : Pic et driver pour GLCD

    J'imagine que les delais comptent le nombre d'impulsion d'horloge et en deduisent le temps passé.
    La fonction NOP permet d'attendre un cycle d'horloge normalement.

    j'ai essayé de reproduire un peu ce que fesait l'autre programme puis je l'etoferais au fur et à mesure.
    voici ce que ca donne.
    Code:
    #include <16f876.h>
    #use delay (clock = 4000000)
    
    #define  rs  PIN_A5                    //COMMNAD/DATA SELECT
    #define  rw  PIN_A4                    //READ/WRITE SELECT             
    #define  e   PIN_A3                    //ENABLE SIGNAL                 
    #define  psb PIN_A2                    //PARALLEL/SERIAL 
    #define  rst PIN_A0                    //RESET SIGNAL   
    //data are send with the port b.
    
    void lcd_init();                    //LCD init
    void lcd_clear();                   //clear lcd display and cursor back to home
    void lcd_display(unsigned char);                 //affichage lcd
    void lcd_instruction(unsigned char);             //send instruction to lcd
    void lcd_data(unsigned char);                    //send data to lcd
    void delay();                       //delay func, decide the speed of display.
    void lcd_check_busy();               //check if the lcd display is busy
    
    
    const unsigned char TAB[]={'A','B','C','D','E','F','g','h','i','j','k','L','M' };
    
    void main ()
    {
    int i ;
    output_c(1);   //test 
    while(1)
    {
    lcd_init();
    output_c(254);     //test
    for(i=0;i<8;i++)
    {
    lcd_display(TAB[i]);
    output_c(255);  //test
    delay();
    }
    delay_ms(1000); //pause de 1 seconde permettant de voir l'affichage
    lcd_clear();
    }
    }
    
    //initialisation du LCD 
    void lcd_init()
    {
      output_low(rst);                  //reset LCD
      output_c(2);                      //test   
      delay();                      
      output_high(rst);                //LCD normal work.
      output_c(3);                      //test
      ;
      output_high(psb);               //8 bit as parrallel.
      output_c(4);                            //test
      lcd_instruction(0x30);                  //basic operation instruction
      lcd_instruction(0x01);                  //off display  
      lcd_instruction(0x06);                  //set the cursor's moving direction.
      lcd_instruction(0x0c);                  //on display,off cursor,off blink
      output_c(5);                            //test
    
    } 
    void lcd_clear ()
    {
    lcd_instruction(0x01);          //clear display and cursor back to home
    lcd_instruction(0x34);                  //extend.
    lcd_instruction(0x30);                  //basic operation instruction
    
    }
    void lcd_display(unsigned char data)
    {
       lcd_data(data); 
    }
    
    void lcd_instruction (unsigned char x)
    {
       lcd_check_busy();
       output_low(rs);                         //data not commnad. 
       output_low(rw);                         //write not read.   
       output_b(x);                      //data to bus.       
       output_high(e);                          //enable.           
       ;
       ;
       ;
       output_low(e);                         //disable. 
    }
    
    void lcd_data (unsigned char x)
    {
       lcd_check_busy();
       output_high(rs);                        //data not commnad. 
       output_low(rw);                        //write not read.   
       output_b(x);                     //data to bus.       
       output_high(e);                         //enable.           
       ;
       ;
       ;
       output_low(e);                         //disable. 
    }
    
    //delay
    void delay()
    {
        int i;
        for(i=0;i<5000;i++)
           {
           #asm
           NOP
           #endasm
           }
    }
    
    //check lcd busy.
    void lcd_check_busy()
    { 
    int busy;
       busy=1;                      //set busy signal                     
       output_low(rs);                        //command not data.                 
       output_high(rw);                        //read not write.                   
       while(busy)                 
          {
             ;
             ;
             ;
             output_high(e);                   //enable.
             ;
             ;
             ;
             if(!input(PIN_B7)) busy=0;       //
             ;
             ;
             ;
             output_low(e);                   //DISABLE.
          }
       output_low(e);                         //DISABLE.
      
     }
    A savoir:
    la fonction NOP est representé en C par un simple ';' On peut aussi utiliser dans mon compilateur la fonction '#asm NOP #endasm'.

    J'ai reussi à trouver pourquoi ca ne marcher pas. En fait dés qu'il rencontre une fonction NOP, le programme s'arrete.
    J'ai essayé de mettres des petits reperes avec le port C afin de voir où il s'arrete et j'en est deduit que c'etait dés la premiere fonction NOP.
    Avez vous une idée de comment je pourais faire pour que mon programme continue sa route ?

  10. Publicité
  11. #7
    DAUDET78

    Re : Pic et driver pour GLCD

    Je ne connais pas le C, mais tu mets une instruction qui sert à rien (du genre VariableBidon ==1)
    J'aime pas le Grec

  12. #8
    mortaurat

    Re : Pic et driver pour GLCD

    Citation Envoyé par DAUDET78 Voir le message
    Je ne connais pas le C, mais tu mets une instruction qui sert à rien (du genre VariableBidon ==1)
    Je ne comprend pas bien où mettre cette variable.

    le programme ce bloque lors de cette fonction:
    Code:
    //delay
    void delay()
    {
        int i;
        for(i=0;i<5000;i++)
           {
           #asm
           NOP
           #endasm
           }
    }
    Et j'imagine qu'il se bloquera à chaque fois qu'il rencontrera un NOP ou ;.


    edit: je crois avoir compris, tu veux dire remplacer le NOP par un variable_bidon = 1 ; ?
    Dernière modification par mortaurat ; 04/08/2009 à 10h07.

  13. #9
    mortaurat

    Re : Pic et driver pour GLCD

    YATAAAAA!!!!!
    Mon lcd marche!!!
    en fait ce n'etais pas une erreur dans le NOP mais il semblerais que le for(i=0;i<5000;i++) posait des problémes, j'ai juste reduit le i<5000 à 50 et ca a marché .
    Grande joie !

  14. #10
    sdec25

    Re : Pic et driver pour GLCD

    Content que ça marche
    Cependant, juste une remarque : En C la fonction Nop n'existe pas !
    Tu peux mettre autant que point-virgule ( ; ) que tu veux ça ne va pas ralentir le programme.
    En asm une ligne = un cycle = une instruction, pas en C.
    La seule façon d'utiliser le Nop en C est d'inclure de l'assembleur.
    On peut aussi, comme DAUDET l'a dit, ajouter une autre instruction (comme une affectation), mais on n'est pas sûr que ça ne prenne qu'un cycle. En plus il n'y a pas besoin de remplir les boucles car un for c'est déjà plusieurs instructions asm (test, saut, ...).

    Et je trouve bizarre que l'on bloque sur le for. La seule explication est qu'un int est sur 8 bits avec ton compilateur. Pour éviter les futurs problèmes je te conseilles d'analyser le code assembleur généré, ou d'exécuter pas à pas sur simulateur, tu verras l'erreur tout de suite.
    Dernière modification par sdec25 ; 04/08/2009 à 11h04.

  15. #11
    mortaurat

    Re : Pic et driver pour GLCD

    Citation Envoyé par sdec25 Voir le message
    Content que ça marche
    Cependant, juste une remarque : En C la fonction Nop n'existe pas !
    Tu peux mettre autant que point-virgule ( ; ) que tu veux ça ne va pas ralentir le programme.
    En asm une ligne = un cycle = une instruction, pas en C.
    La seule façon d'utiliser le Nop en C est d'inclure de l'assembleur.
    On peut aussi, comme DAUDET l'a dit, ajouter une autre instruction (comme une affectation), mais on n'est pas sûr que ça ne prenne qu'un cycle. En plus il n'y a pas besoin de remplir les boucles car un for c'est déjà plusieurs instructions asm (test, saut, ...).

    Et je trouve bizarre que l'on bloque sur le for. La seule explication est qu'un int est sur 8 bits avec ton compilateur. Pour éviter les futurs problèmes je te conseilles d'analyser le code assembleur généré, ou d'exécuter pas à pas sur simulateur, tu verras l'erreur tout de suite.
    Oui tu as raison, la taille d'un INT depend de la taille du system et la famille 16F est sur 8 bit...

    J'avais lu sur wikipedia que la fonction NOP pouvait être remplacée par un simple point virgule.
    http://en.wikipedia.org/wiki/NOP

    Je pense que si rajouter des points virgules ne ralentissait pas mon programme, il ne marcherais pas.
    d'ailleur le voici pour ceux qui n'ont pas de driver sous CCS pour la platine QL_200 ou un afficheur avec controleur ST7921 !
    Code:
    #include <16f876.h>
    #use delay (clock = 4000000)
    
    #define  rs  PIN_A5                    //COMMNAD/DATA SELECT
    #define  rw  PIN_A4                    //READ/WRITE SELECT             
    #define  e   PIN_A3                    //ENABLE SIGNAL                 
    #define  psb PIN_A2                    //PARALLEL/SERIAL 
    #define  rst PIN_A0                    //RESET SIGNAL   
    /*data are send by defaut with the port b. in order to change the port of data, 
    please change output_x in lcd_data and lcd_instruction and don't forget to change 
    in func lcd_check_busy 'input(PIN_B7)'*/
    
    void lcd_init();                    //LCD init
    void lcd_clear();                   //clear lcd display and cursor back to home
    void lcd_display(unsigned char);                 //affichage lcd
    void lcd_instruction(unsigned char);             //send instruction to lcd
    void lcd_data(unsigned char);                    //send data to lcd
    void delay();                       //delay func, decide the speed of init.
    void lcd_check_busy();               //check if the lcd display is busy
    
    const unsigned char TAB[]={'A','B','C','D','E','F','g','h','i','j','k','L','M' };
    
    void main ()
    {
    int i ;
    while(1)
    {
    lcd_init();
    for(i=0;i<8;i++)
    {
    lcd_display(TAB[i]);
    delay();
    }
    delay_ms(1000); //pause de 1 seconde permettant de voir l'affichage
    lcd_clear();
    }
    }
    
    //initialisation du LCD 
    void lcd_init()
    {
      output_low(rst);                  //reset LCD
      delay();                      
      output_high(rst);                //LCD normal work.
      ;
      output_high(psb);               //8 bit as parrallel.
      lcd_instruction(0x30);                  //basic operation instruction
      lcd_instruction(0x01);                  //off display  
      lcd_instruction(0x06);                  //set the cursor's moving direction.
      lcd_instruction(0x0c);                  //on display,off cursor,off blink
    
    } 
    void lcd_clear ()
    {
    lcd_instruction(0x01);          //clear display and cursor back to home
    lcd_instruction(0x34);                  //extend.
    lcd_instruction(0x30);                  //basic operation instruction
    
    }
    void lcd_display(unsigned char data)
    {
       lcd_data(data); 
    }
    
    void lcd_instruction (unsigned char x)
    {
       lcd_check_busy();
       output_low(rs);                         //data not commnad. 
       output_low(rw);                         //write not read.   
       output_b(x);                      //data to bus.       
       output_high(e);                          //enable.           
       ;
       ;
       ;
       output_low(e);                         //disable. 
    }
    
    void lcd_data (unsigned char x)
    {
       lcd_check_busy();
       output_high(rs);                        //data not commnad. 
       output_low(rw);                        //write not read.   
       output_b(x);                     //data to bus.       
       output_high(e);                         //enable.           
       ;
       ;
       ;
       output_low(e);                         //disable. 
    }
    
    //delay
    void delay()
    {
        int i=0;
        while(i<50)
           {
           i=i+1;
           }
    }
    
    //check lcd busy.
    void lcd_check_busy()
    { 
    int busy;
       busy=1;                      //set busy signal                     
       output_low(rs);                        //command not data.                 
       output_high(rw);                        //read not write.                   
       while(busy)                 
          {
             ;
             ;
             ;
             output_high(e);                   //enable.
             ;
             ;
             ;
             if(!input(PIN_B7)) busy=0;       //
             ;
             ;
             ;
             output_low(e);                   //DISABLE.
          }
       output_low(e);                         //DISABLE.
      
     }
    je vais lui rajouter d'autre fonction, mais voila pour l'instant ce que ca donne.

  16. #12
    sdec25

    Re : Pic et driver pour GLCD

    Citation Envoyé par mortaurat Voir le message
    J'avais lu sur wikipedia que la fonction NOP pouvait être remplacée par un simple point virgule.
    http://en.wikipedia.org/wiki/NOP

    Je pense que si rajouter des points virgules ne ralentissait pas mon programme, il ne marcherais pas.
    Il y a aussi écrit
    the issue is whether the statement affects program output, not whether or not a compiler generates any code for this statement
    ...
    typically no instructions whatsoever would be generated
    Donc un point-virgule ne génère pas de Nop. Si tu veux vérifier par toi-même regarde le code assembleur généré.

    Il n'y a pas besoin de Nop puisqu'une boucle sans rien dedans dure déjà un certain temps.
    Dernière modification par sdec25 ; 04/08/2009 à 11h57.

  17. Publicité
  18. #13
    mortaurat

    Re : Pic et driver pour GLCD

    Tu semble effectivement avoir raison, j'ai viré les ; et ca marche pareil.
    Cela m'a permis de voir une autre limitation du programme.
    Bien que avec un quartz de 4MHz, l'afficheur est le temps de traité les données, ca ne marche pas avec du 20 MHz.
    Je vais devoir donc rajouter des petites pauses comme l'a dit daudet

  19. #14
    sdec25

    Re : Pic et driver pour GLCD

    Pour avoir plus de souplesse tu peux créer des fonction delay avec une base de temps en seconde.
    Par exemple delay_ms(x) pour une pause de x ms.
    Ensuite, dans delay_ms, utiliser une constante dépendant de la fréquence du processeur. Par exemple :
    Code:
    #define FREQ ((unsigned long)20000000)
    Comme ça, on n'aura pas besoin de modifier la fonction delay_ms si on change la fréquence.

  20. #15
    alainav1

    Re : Pic et driver pour GLCD

    bonjour,
    j'ai eu un probleme d'affichage sur LCD en passant de 4à 20Mhz
    je programme en basic et le LCD se configure avec les fonctions
    lcd_commandus=5000
    lcd_dataus=100
    lcd_initms=100
    pour du 4 Mhz

    j'ai modifier pour du 20Mhz de la façon suivante
    cd_commandus=9000
    lcd_dataus=200
    lcd_initms=200
    je ne sais pas si c'est optimisé mais ça marche !

    si cela peux t'aider
    cordialement
    Alain
    Décider de faire, c'est bien . Décider quand, c'est mieux !

  21. #16
    mortaurat

    Re : Pic et driver pour GLCD

    Code:
    #include <16f876.h>
    #use delay (clock = 4000000)
    
    #define  rs  PIN_A5                    //COMMNAD/DATA SELECT
    #define  rw  PIN_A4                    //READ/WRITE SELECT             
    #define  e   PIN_A3                    //ENABLE SIGNAL                 
    #define  psb PIN_A2                    //PARALLEL/SERIAL 
    #define  rst PIN_A0                    //RESET SIGNAL   
    /*data are send by defaut with the port b. in order to change the port of data, 
    please change output_x in lcd_data and lcd_instruction and don't forget to change 
    in func lcd_check_busy 'input(PIN_B7)'*/
    
    void lcd_init();                    //LCD init
    void lcd_clear();                   //clear lcd display and cursor back to home
    void lcd_display(unsigned char);                 //affichage lcd
    void lcd_instruction(unsigned char);             //send instruction to lcd
    void lcd_data(unsigned char);                    //send data to lcd
    void delay();                       //delay func, decide the speed of init.
    void lcd_check_busy();               //check if the lcd display is busy
    
    const unsigned char TAB[]={'A','B','C','D','E','F','g','h','i','j','k','L','M' };
    
    void main ()
    {
    int i ;
    while(1)
    {
    lcd_init();
    for(i=0;i<8;i++)
    {
    lcd_display(TAB[i]);
    delay_us(10);
    }
    delay_ms(1000); //pause de 1 seconde permettant de voir l'affichage
    lcd_clear();
    }
    }
    
    //initialisation du LCD 
    void lcd_init()
    {
      output_low(rst);                  //reset LCD
      delay_us(45);                      
      output_high(rst);                //LCD normal work.
      output_high(psb);               //8 bit as parrallel.
      delay_us(1);
      lcd_instruction(0x30);                  //basic operation instruction
      delay_us(45);
      lcd_instruction(0x01);                  //clear display and cursor back to home 
      delay_ms(2);
      lcd_instruction(0x06);               //set the cursor's moving direction.
      delay_us(45);
      lcd_instruction(0x0c);                  //on display,off cursor,off blink
      delay_us(45);
    } 
    void lcd_clear ()
    {
    lcd_instruction(0x01);          //clear display and cursor back to home
    delay_ms(2);
    lcd_instruction(0x34);                  //extend.
    delay_us(45);
    lcd_instruction(0x30);                  //basic operation instruction
    delay_us(45);
    }
    void lcd_display(unsigned char data)
    {
       lcd_data(data); 
    }
    
    void lcd_instruction (unsigned char x)
    {
       lcd_check_busy();
       output_low(rs);                         //data not commnad. 
       output_low(rw);                         //write not read.   
       delay_us(1);
       output_b(x);                   //data to bus.
       delay_us(1);
       output_high(e);                      //enable.
       delay_us(10);
       output_low(e);                         //disable. 
       delay_us(1);
    }
    
    void lcd_data (unsigned char x)
    {
       lcd_check_busy();
       output_high(rs);                        //data not commnad. 
       output_low(rw);                        //write not read.
       delay_us(1);
       output_b(x);                     //data to bus.  
       delay_us(1);
       output_high(e);                         //enable. 
       delay_us(10);
       output_low(e);                         //disable.
       delay_us(1);
    }
    
    //delay
    void delay()
    {
        int i=0;
        while(i<50)
           {
           i=i+1;
           }
    }
    
    //check lcd busy.
    void lcd_check_busy()
    { 
    int busy;
       busy=1;                      //set busy signal                     
       output_low(rs);                        //command not data.                 
       output_high(rw);                        //read not write.                   
       while(busy)                 
          {
             delay_us(10);
             output_high(e);                   //enable.
             delay_us(10);
             if(!input(PIN_B7)) busy=0;       //
             delay_us(10);
             output_low(e);                   //DISABLE.
          }
       output_low(e);                         //DISABLE.
      
     }
    J'ai essayé de mettre des pauses un peu partout mais rien à faire.
    Ca ne marche pas avec un quartz de 20 MHz.
    je peut voir les pin actives sur ma plaque.
    Lorsque je branche le 4MHz je peut voir RA0 RA2 RA5 allumés avec un clignotement regulier pour les autres pin. Sur le port B RB3, RB5 et RB6 allumés (surement toujours à 1 d'aprés le code ASCII pour abcdefgh) avec toujours un clignotement regulier pour les autres pin.

    Avec le quartz de 20 MHz seul RA4 est allumé et aucun clignotement pour les autres pin.

  22. #17
    mortaurat

    Re : Pic et driver pour GLCD

    Personne à d'idée sur pourquoi mon lcd ne marche pas à 20 MHz ?
    merci

  23. #18
    alainav1

    Re : Pic et driver pour GLCD

    bonjour,
    je pense qu'il faut que tu trouves l'equivalent en C des instructions de configuration du LCD
    soit des fonctions basic
    cd_commandus
    lcd_dataus
    lcd_initms
    mais je ne connais pas le C et je ne peux t'aider
    cordialement
    Alain
    Décider de faire, c'est bien . Décider quand, c'est mieux !

  24. Publicité
  25. #19
    sdec25

    Re : Pic et driver pour GLCD

    Voir les chronogrammes sur cette page pour avoir les délais. Je pense que c'est le même genre de µc.
    A mon avis, un délai n'est pas respecté.

  26. #20
    mortaurat

    Re : Pic et driver pour GLCD

    Citation Envoyé par alainav1 Voir le message
    je pense qu'il faut que tu trouves l'equivalent en C des instructions de configuration du LCD
    soit des fonctions basic
    cd_commandus
    lcd_dataus
    lcd_initms
    et bien c'est ce que j'ai fais dans mon programme.
    Mais je pense serieusement à un probléme de tempo.
    à 4MHz, mon µc met 1µs pour executer une instruction il met donc 200ns à 20 MHz.
    même sans tempo, il devrait être sufisament 'lent' pour le controleur du LCD.
    Enfin d'aprés la datasheet...

  27. #21
    sdec25

    Re : Pic et driver pour GLCD

    Code:
    #use delay (clock = 4000000)
    Tu n'aurais pas oublié de changer ça ?
    Sinon tu peux mettre 5 Nop après chaque instruction :
    Code:
    Nop(); Nop(); Nop(); Nop(); Nop();

  28. #22
    mortaurat

    Re : Pic et driver pour GLCD

    Je crois que j'ai compris où etait l'erreur.
    quand j'avais dit:
    Lorsque je branche le 4MHz je peut voir RA0 RA2 RA5 allumés avec un clignotement regulier pour les autres pin. Sur le port B RB3, RB5 et RB6 allumés (surement toujours à 1 d'aprés le code ASCII pour abcdefgh) avec toujours un clignotement regulier pour les autres pin.

    Avec le quartz de 20 MHz seul RA4 est allumé et aucun clignotement pour les autres pin.
    C'est que en fait, il semblerais que le pic 16f876 ne pas supporter les 20MHz.
    un programme aussi simple que
    void main()
    {
    int i=0;
    while(1)
    {
    output_b(i);
    delay_ms(1000);
    i=i+1;
    }
    }
    ne fonctionne pas...

    D'aprés la datasheet, pas de probléme pour les 20MHz, mais celon certain auteur, incompatible.
    j'ai les boules menu, je vais me pendre avec un cable usb ou m'ouvrir les veines avec les broches d'un pic.

Discussions similaires

  1. [PIC+GLCD] - Stockage d'images dans mémoire externe
    Par jorg1n dans le forum Électronique
    Réponses: 32
    Dernier message: 08/03/2010, 12h48
  2. Impossible d'installer le driver USB microchip pour un PIC
    Par adrien45 dans le forum Électronique
    Réponses: 4
    Dernier message: 15/09/2009, 19h31
  3. librairie Glcd pour C18 ?
    Par MorpheusPic dans le forum Électronique
    Réponses: 20
    Dernier message: 18/02/2009, 11h37
  4. Driver LCD 2*16 avec PIC 16F877
    Par misstik dans le forum Électronique
    Réponses: 2
    Dernier message: 20/07/2007, 22h54
Découvrez nos comparatifs produits sur l'informatique et les technologies.