[ Divers / C ] Ecrire pour un afficheur LCD

Ecrire pour un afficheur LCD [ Divers / C ] - C - Programmation

Marsh Posté le 27-10-2011 à 15:58:33    

Bonjour
Je m'aventure dans la programmation pour un afficheur LCD qui n'est apparemment pas celui que je croyait.
En effet, je pensais avoir acquit un afficheur basé sur le micro-contrôleur Hitachi HD44780, mais il semble que ce ne soit pas le modèle escompté.
 
Mon afficheur est un Xiamen Ocular GDM2004D.
Je viens de trouver quelques info ainsi que quelque ligne de code que j'essaie de compiler en vain.
 
Ce qui fait que je viens chercher de l'aide sur mon forum préféré pour programmer cet afficheur.
 
Vous trouverez facilement le datasheet en googlant avec la référence de l'afficheur.
 
Côté code. j'ai trouvé ce web qui semble montrer comment piloter l'afficheur : Rickey's World
 
J'ai donc coller/copier le fichier at89x51.h, que vous trouverez à cette adresse : Koders.com, mais impossible de compiler ; Le code ne semble pas conforme à du C, malgrès que ça soit en être ; Mais comme je ne connais as le C, j'apprends.
Je vais ensuite construire mon programme à partir des bouts de code fournit sur le site de Rickey's World
 
Si vous pouviez me dire dans un premier temps ce qui cloche dans ce fichier at89x51.h
Et me corriger si je m'et trompé, je plaisante, si je me suis trompé.
Merci pour votre aide.
 
 
J'ai compilé avec la ligne de commande suivante :

gcc -o lcd_prog lcd_prog.c

...
Le code suivant :

Code :
  1. #include "./at89x51.h"
  2. #define LCD_data P2
  3. #define LCD_D7   P2_7
  4. #define LCD_rs   P1_0
  5. #define LCD_rw   P1_1
  6. #define LCD_en   P1_2
  7.  
  8. void LCD_init()
  9. {
  10.  LCD_data = 0x38;     //Function set: 2 Line, 8-bit, 5x7 dots                  
  11.  LCD_rs   = 0;        //Selected command register                              
  12.  LCD_rw   = 0;        //We are writing in data register                        
  13.  LCD_en   = 1;        //Enable H->L                                            
  14.  LCD_en   = 0;
  15.  LCD_busy();          //Wait for LCD to process the command                    
  16.  LCD_data = 0x0F;     //Display on, Curson blinking command                    
  17.  LCD_rs   = 0;        //Selected command register                              
  18.  LCD_rw   = 0;        //We are writing in data register                        
  19.  LCD_en   = 1;        //Enable H->L                                            
  20.  LCD_en   = 0;
  21.  LCD_busy();          //Wait for LCD to process the command                    
  22.  LCD_data = 0x01;     //Clear LCD                                              
  23.  LCD_rs   = 0;        //Selected command register                              
  24.  LCD_rw   = 0;        //We are writing in data register                        
  25.  LCD_en   = 1;        //Enable H->L                                            
  26.  LCD_en   = 0;
  27.  LCD_busy();          //Wait for LCD to process the command                    
  28.  LCD_data = 0x06;     //Entry mode, auto increment with no shift              
  29.  LCD_rs   = 0;        //Selected command register                              
  30.  LCD_rw   = 0;        //We are writing in data register                        
  31.  LCD_en   = 1;        //Enable H->L                                            
  32.  LCD_busy();
  33. }


 
Et j'ai presque autant d'erreur que de ligne relative au fichier ./at89x51.h.
 

void:/home/root/8051# gcc -o lcd_prog lcd_prog.c
In file included from lcd_prog.c:1:
./at89x51.h:32: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__at’
./at89x51.h:33: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__at’
./at89x51.h:34: error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘__at’
 
.../... Etc

Reply

Marsh Posté le 27-10-2011 à 15:58:33   

Reply

Marsh Posté le 27-10-2011 à 17:10:54    

Ben comme les erreurs sont manifestement dans "./at89x51.h"
comment répondre sans voir ce fichier?
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-10-2011 à 17:19:48    

Comme tu peux lire sur le premier site que tu donnes, c'est du code pour du Keil C
avec des mots clés spécifiques
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-10-2011 à 17:39:02    

Merci Gilou.
 
A part ça, à partir du datasheet, y aurais moyen d'avoir un coup de main pour déchiffrer le document.
je bidouille un peut, mais j'ai pas fait electro ni même elec, s'il vous plaît bien sûr !

Reply

Marsh Posté le 27-10-2011 à 17:47:28    

Oui, mais ça ne nous dit pas comment tu relies ça à quelque chose que tu commandes et qui lui envoie un signal sur ses pins.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-10-2011 à 17:57:03    

Ah, pardon,  :heink:  
 
J'ai connecté l'afficheur au port parallèle d'un Compatible IBM PC selon le schéma donné dans le Linux magasine N°8, comme suit :
 
 
Afficheur              port parallèle
 
pin 1           =>   broche 24 GND
pin 2          =>   +5volt
pin 3           =>   unused
pin 4           =>   broche 17
pin 5           =>   broche 24 GND
pin 6  à 14   =>   broche 1 à 9
 
Merci Gilou.

Reply

Marsh Posté le 27-10-2011 à 18:16:35    

Donc il va falloir que tu transposes ça (les commandes pour l'afficheur)  en commandes positionnant le registre du port parallèle.
Si tu es sous Linux, faut peut être voir du coté de parapin pour avoir une librairie prête à l'emploi.
A+,


Message édité par gilou le 27-10-2011 à 18:21:14

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-10-2011 à 18:33:49    

Ca correspond pas au Datasheet: il y a 16 pins, et le pin 5, je suis pas sur qu'il faille le mettre à GND (si tu lis jamais les flags et les valeurs mémoire de l'afficheur, c'est sans doute bon, mais la dans le code en exemple, c'est testé (les flags) dans LCD_busy(), mais il y a une méthode sans aussi, et donc j'ai un doute). Les pins 15 et 16, c'est le courant pour les LEDs, tu as relié ça ailleurs, c'est pour ça que tu en parles pas?
Tel que je vois les choses, il est logique d'associer les pins 2-9 (bidirectionnels) du port parallèle à DB0-DB7, donc aux pins 7-14 de l'afficheur.
Pour RS, R/W et E on n'a besoin que de la direction en output, donc on devrait associer trois des pins 1, 14, 16 ou 17 à RS, R/W et E, donc aux pins 4, 5 et 6 de l'afficheur (tu as associé RS au pin 17 du port parallèle, et E au port 1 du PP, mais il semblerait logique d'associer R/W au port 14 ou 16 du PP plutôt au'au 24 (GND))
A+,

Message cité 1 fois
Message édité par gilou le 27-10-2011 à 18:57:39

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-10-2011 à 18:52:49    

Les 15 et 16 c'est pour le rétro- éclairage, ça ça fonctionne.
 
Pour le 5, il est connecté avec le 1 à la broche 24 ; Broche qui devrait être la masse si je me trompe pas.  :??:  
 
C'est le schéma donné pas Linux mag pour un afficheur à base de micro- contrôleur HD44780.
Mais c'est pas le même que j'ai apparemment, et effectivement en regardant le datasheet, ça à pas l'air d'être ça.
 
Si c'est juste un problème de connection c'est bien, parce-que j'ai un bout de code, que je donne tiens.
 

Code :
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include <sys/io.h>
  6.  
  7. #define PORTADDRESS 0x378
  8. #define DATA PORTADDRESS+0
  9. #define STATUS PORTADDRESS+1
  10. #define CONTROL PORTADDRESS+2
  11.  
  12. char init[10];
  13. int count;
  14. int len;
  15.  
  16. void initlcd(void) {
  17.  init[0] = 0x0F;
  18.  init[1] = 0x01;
  19.  init[2] = 0x38;
  20.  
  21.  outb(inb(CONTROL) & 0xDF, CONTROL);
  22.  
  23.  outb(inb(CONTROL) | 0x08, CONTROL);
  24.  
  25.  for (count = 0; count <= 2; count++) {
  26.    outb(init[count], DATA);
  27.    outb(inb(CONTROL) | 0x01, CONTROL);
  28.    usleep(2);
  29.    outb(inb(CONTROL) & 0xFE, CONTROL);
  30.    usleep(2);
  31.  }
  32.  outb(inb(CONTROL) & 0xF7, CONTROL);
  33. }
  34.  
  35. void sendlcd(char text[10]) {
  36.  len = strlen(text);
  37.  for (count = 0; count < len; count++)
  38.    {
  39.      outb(text[count], DATA);
  40.  
  41.      outb(inb(CONTROL) | 0x01, CONTROL);
  42.      usleep(1);
  43.      outb(inb(CONTROL) & 0xFE, CONTROL);
  44.      usleep(1);
  45.    }
  46. }
  47.  
  48. void poslcd(int pos) {
  49.  outb(inb(CONTROL) | 0x08, CONTROL);
  50.  outb(128+pos, DATA);
  51.  outb(inb(CONTROL) | 0x01, CONTROL);
  52.  usleep(2);
  53.  outb(inb(CONTROL) & 0xFE, CONTROL);
  54.  usleep(2);
  55.  outb(inb(CONTROL) & 0xF7, CONTROL);
  56. }
  57.  
  58. void main (void)
  59. {
  60.  if(ioperm(PORTADDRESS, 3, 1)) {
  61.    perror("ioperm" );
  62.    exit(1);
  63.  }
  64.  
  65.  initlcd();
  66.  sendlcd("Bonjour" );
  67.  poslcd(0x40);
  68.  sendlcd("le monde !" );
  69. }


 
 
Du coup, je la branche où la pin 5 ?
 
 
edit, correction des fautes dans le code.


Message édité par Profil supprimé le 27-10-2011 à 18:59:07
Reply

Marsh Posté le 27-10-2011 à 19:02:35    

Je t'ai répondu dans un ajout à mon post tu la branche sur la 14 ou la 16 du PP pour pouvoir y écrire, vu que quand le signal y est à 1, ca indique un mode en lecture (utile pour lire le flag et savoir quand l'afficheur est près a  accepter une nouvelle commande).
Ou bien tu la laisse comme elle est, et tu utilises un délai fixe entre chaque commande, c'est moins optimal, mais peut être plus simple.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-10-2011 à 19:02:35   

Reply

Marsh Posté le 27-10-2011 à 19:10:20    

D'abord merci Gilou. [:powa]
 

gilou a écrit :


Tel que je vois les choses, il est logique d'associer les pins 2-9 (bidirectionnels) du port parallèle à DB0-DB7, donc aux pins 7-14 de l'afficheur.


Ok, ça, c'est ce qui est fait.

gilou a écrit :


Pour RS, R/W et E on n'a besoin que de la direction en output, donc on devrait associer trois des pins 1, 14, 16 ou 17 à RS, R/W et E, donc aux pins 4, 5 et 6 de l'afficheur (tu as associé RS au pin 17 du port parallèle, et E au port 1 du PP, mais il semblerait logique d'associer R/W au port 14 ou 16 du PP plutôt au'au 24 (GND))
A+,


Ok, je vais faire ça... La pin 5 sur la broche 14 du port parallèle.
 
Après faut voir pour le code qui va avec, si on peut ajuster le code ci-dessus, ce serait pas mal.
 

Reply

Marsh Posté le 27-10-2011 à 19:15:04    

Dans le code que tu donnes (j'ai pas été vérifier la validité des commandes), les usleep(1) semblent irréaliste: attendre 1 micro-seconde?
Sur le premier site que tu as donné, il teste avec une boucle que le flag busy de l'afficheur soit OK (ou bien il attend un délai fixe, de l'ordre de 20 ms on dirait)
De toute façon, tentes plutôt d'utiliser une librairie comme celle que je t'ai indiquée (parapin), ça devrait te simplifier la tache je pense.
A+,


Message édité par gilou le 27-10-2011 à 19:21:16

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-10-2011 à 19:37:19    

Ok, je vais voir ce que je peux faire avec cette bibliothèque.
 
(J'ai perdu mon étain.)
 
Merci Gilou.

Reply

Marsh Posté le 27-10-2011 à 20:14:58    

Oui parce qu'en regardant ici: http://parapin.sourceforge.net/doc [...] onfiguring
on voit assez bien comment le code C pour le Keil C peut se transposer.
 
 

Code :
  1. void LCD_busy()
  2. {
  3.      LCD_D7   = 1;           //Make D7th bit of LCD as i/p
  4.      LCD_en   = 1;           //Make port pin as o/p
  5.      LCD_rs   = 0;           //Selected command register
  6.      LCD_rw   = 1;           //We are reading
  7.      while(LCD_D7){          //read busy flag again and again till it becomes 0
  8.            LCD_en   = 0;     //Enable H->L
  9.            LCD_en   = 1;
  10.      }
  11. }


devrait donner

Code :
  1. // défini globalement
  2. #define LCD_en LP_PIN01
  3. #define LCD_rs  LP_PIN17
  4. #define LCD_rw LP_PIN16
  5. #define LCD_DATA_PINS LP_DATA_PINS
  6. #define LCD_D0 LP_PIN02
  7. ...
  8. #define LCD_D7 LP_PIN09
  9. // Dans le main on met par défaut les valeurs en output
  10. pin_output_mode(LP_PIN01|LP_DATA_PINS|LP_PIN14|LP_PIN16|LP_PIN17);
  11. // et donc, à mes erreurs près
  12. void LCD_busy()
  13. {
  14.      set_pin(LCD_D7);
  15.      set_pin(LCD_en);
  16.      clear_pin(LCD_rs);
  17.      set_pin(LCD_rw);
  18.      pin_input_mode(LP_DATA_PINS);
  19.      while(pin_is_set(LCD_D7)){          //read busy flag again and again till it becomes 0
  20.            clear_pin(LCD_en);     //Enable H->L
  21.            set_pin(LCD_en); 
  22.      }
  23.      pin_output_mode(LP_DATA_PINS); // reset to default mode
  24. }


 
 
A+,

Message cité 1 fois
Message édité par gilou le 27-10-2011 à 20:17:30

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-10-2011 à 22:04:51    

Voilà, j'ai lu un poil de documentation sur parapin ; Soit j'ai pas compris, soit j'ai compris mais ça me parait louche donc question :  
Que dois-je faire une fois que j'ai setté mais pins ?
 
Ca va paraître sous évalué, mais voici ce que j'ai fait... plop du code C, c'est rare de ma part.
 

Code :
  1. /****************************/
  2. /* filename     : paralcd.c */
  3. /* language     : C         */
  4. /* Date         : 2011/10/27*/
  5. /* Author       : jovalise  */
  6. /* version      : 0.0.0alpha*/
  7. /****************************/
  8. /* Description  : paralcd display text from command line arguments on Xiamen Ocular GDM2004D connected to LPT1 */
  9. /****************************/
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #include <unistd.h>
  14. #include <parapin.h>
  15. #include <sys/io.h>
  16.  
  17. #define BASEPORT 0x378
  18.  
  19. int main (int argc, char * argv[])  
  20.  
  21. {
  22.  
  23.  int parapin_init_success = 0;
  24.  
  25.  if (argc == 1)
  26.    
  27.    {
  28.      
  29.      printf("Usage: paralcd prend au moins un argument. \n" );
  30.      return 1;
  31.    }
  32.  
  33.  
  34.  if(ioperm(BASEPORT, 3, 1))
  35.    
  36.    {
  37.      
  38.      perror("paralcd::ioperm" );
  39.      return 1;
  40.  
  41.    }
  42.  
  43.  
  44.  
  45.  parapin_init_success = pin_init_user(BASEPORT);
  46.  
  47.  if (parapin_init_success != 0)
  48.  
  49.    {
  50.  
  51.      printf("Echec de l'initialisation de parapin. \n" );
  52.      
  53.    }
  54.  
  55.  
  56.  pin_output_mode(LP_DATA_PINS);
  57.  
  58.  
  59.  return 0;
  60.  
  61. }


Message édité par Profil supprimé le 27-10-2011 à 22:08:43
Reply

Marsh Posté le 27-10-2011 à 22:46:16    

gilou a écrit :

Oui parce qu'en regardant ici: http://parapin.sourceforge.net/doc [...] onfiguring
on voit assez bien comment le code C pour le Keil C peut se transposer.
 
 
.../...


 
 
Merci Gilou, du coup, je comprends qu'il n'y a rien d'autre à faire qu'a setter les bon pin au bon moment.
J'ai plus à utiliser outb ?
 
 

Citation :

Code :
  1. // défini globalement
  2. #define LCD_en LP_PIN01
  3. #define LCD_rs  LP_PIN17
  4. #define LCD_rw LP_PIN16
  5. #define LCD_DATA_PINS LP_DATA_PINS
  6. #define LCD_D0 LP_PIN02
  7. ...
  8. #define LCD_D7 LP_PIN09
  9. // Dans le main on met par défaut les valeurs en output
  10. pin_output_mode(LP_PIN01|LP_DATA_PINS|LP_PIN14|LP_PIN16|LP_PIN17);
  11. // et donc, à mes erreurs près
  12. void LCD_busy()
  13. {
  14.      set_pin(LCD_D7);
  15.      set_pin(LCD_en);
  16.      clear_pin(LCD_rs);
  17.      set_pin(LCD_rw);
  18.      pin_input_mode(LP_DATA_PINS);
  19.      while(pin_is_set(LCD_D7)){          //read busy flag again and again till it becomes 0
  20.            clear_pin(LCD_en);     //Enable H->L
  21.            set_pin(LCD_en); 
  22.      }
  23.      pin_output_mode(LP_DATA_PINS); // reset to default mode
  24. }



 
Je comprends pas par contre pourquoi on mettrait LP_DATA_PINS en entrée


Message édité par Profil supprimé le 27-10-2011 à 22:53:41
Reply

Marsh Posté le 27-10-2011 à 23:34:09    

Comme je t'ai dit, tu peux essayer de reporter le code lu sur le premier site

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <parapin.h>
  5. #include <sys/io.h>
  6. #define BASEPORT 0x378
  7. // correspondances LCD PARA pin à pin
  8. // pins en output seulement
  9. #define LCD_en LP_PIN01
  10. #define LCD_rs  LP_PIN17
  11. // Si on a connecté le pin LCD 5 au pin 16 du PP et non pas au 14
  12. #define LCD_rw LP_PIN16
  13. // pins BIDI
  14. #define LCD_D0 LP_PIN02
  15. #define LCD_D1 LP_PIN03
  16. #define LCD_D2 LP_PIN04
  17. #define LCD_D3 LP_PIN05
  18. #define LCD_D4 LP_PIN06
  19. #define LCD_D5 LP_PIN07
  20. #define LCD_D6 LP_PIN08
  21. #define LCD_D7 LP_PIN09
  22. // global pins BIDI
  23. #define LCD_DATA_PINS LP_DATA_PINS
  24. void LCD_init();
  25. void LCD_busy();
  26. void LCD_senddata(unsigned char var);
  27. void LCD_sendstring(unsigned char *var);
  28. int main (int argc, char * argv[]) {
  29.   int parapin_init_success = 0;
  30.   if (argc == 1)  {
  31.       printf("Usage: paralcd prend au moins un argument. \n" );
  32.       return 1;
  33.   }
  34.  
  35.   if (ioperm(BASEPORT, 3, 1))  {
  36.       perror("paralcd::ioperm" );
  37.       return 1;
  38.   }
  39.  
  40.   parapin_init_success = pin_init_user(BASEPORT);
  41.   if (parapin_init_success != 0) {
  42.      printf("Echec de l'initialisation de parapin. \n" );
  43.   }
  44.  
  45.   pin_output_mode(LP_DATA_PINS|LP_SWITCHABLE_PINS);
  46.   LCD_init();
  47.   LCD_sendstring("Jovalise" );
  48.   clear_pin(LP_DATA_PINS|LP_SWITCHABLE_PINS);  // vu dans les exemples de parapin
  49.   return 0;
  50. }
  51. void LCD_busy()
  52. {
  53.      set_pin(LCD_D7);
  54.      set_pin(LCD_en);
  55.      clear_pin(LCD_rs);
  56.      set_pin(LCD_rw);
  57.      pin_input_mode(LP_DATA_PINS);
  58.      while(pin_is_set(LCD_D7)){          //read busy flag again and again till it becomes 0
  59.            clear_pin(LCD_en);     //Enable H->L
  60.            set_pin(LCD_en);
  61.      }
  62.      pin_output_mode(LP_DATA_PINS); // reset to default mode
  63. }
  64. void LCD_init()
  65. {
  66.   set_pin(0x38);     //Function set: 2 Line, 8-bit, 5x7 dots    Au vu du code de la lib, ça doit marcher ainsi               
  67.   clear_pin(LCD_rs);        //Selected command register                               
  68.   clear_pin(LCD_rw);        //We are writing in data register                         
  69.   set_pin(LCD_en);        //Enable H->L                                             
  70.   clear_pin(LCD_en);
  71.   LCD_busy();          //Wait for LCD to process the command   
  72.                  
  73.   set_pin(0x0F);     //Display on, Curson blinking command                     
  74.   clear_pin(LCD_rs);        //Selected command register                               
  75.   clear_pin(LCD_rw);         //We are writing in data register                         
  76.   set_pin(LCD_en);       //Enable H->L                                             
  77.   clear_pin(LCD_en);
  78.   LCD_busy();          //Wait for LCD to process the command  
  79.                  
  80.   set_pin(0x01);     //Clear LCD                                               
  81.   clear_pin(LCD_rs);        //Selected command register                               
  82.   clear_pin(LCD_rw);         //We are writing in data register                         
  83.   set_pin(LCD_en);        //Enable H->L                                             
  84.   clear_pin(LCD_en);
  85.   LCD_busy();          //Wait for LCD to process the command   
  86.                  
  87.   set_pin(0x06);     //Entry mode, auto increment with no shift               
  88.   clear_pin(LCD_rs);     //Selected command register                               
  89.   clear_pin(LCD_rw);        //We are writing in data register                         
  90.   set_pin(LCD_en);        //Enable H->L                                             
  91.   LCD_busy();
  92. }
  93. void LCD_senddata(unsigned char var)
  94. {
  95.      set_pin(var);      //Function set: 2 Line, 8-bit, 5x7 dots
  96.      set_pin(LCD_rs);        //Selected data register
  97.      clear_pin(LCD_rw);        //We are writing
  98.      set_pin(LCD_en);        //Enable H->L
  99.      clear_pin(LCD_en);
  100.      LCD_busy();          //Wait for LCD to process the command
  101. }
  102. // doit y avoir une taille max pour la string a vérifier par rapport au buffer de l'afficheur
  103. void LCD_sendstring(unsigned char *var)
  104. {
  105.      while(*var)              //till string ends
  106.        LCD_senddata(*var++);  //send characters one by one
  107. }


 
le code de parapin est tres simple et tient dans deux petits fichiers, parapin.c et parapin.h, qui devraient pouvoir être linkés directement.
Le code est SGDG a toi de voir s'il t'inspire.
 

Citation :

J'ai plus à utiliser outb ?

grosso modo, c'est ce que fait parapin, avec les bons masques
Lis le code de parapin.h et parapin.c, c'est fort compréhensible.
 
A+,


Message édité par gilou le 27-10-2011 à 23:52:52

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-10-2011 à 23:42:39    

Citation :

Je comprends pas par contre pourquoi on mettrait LP_DATA_PINS en entrée


La ligne suivante?
pin_input_mode(LP_DATA_PINS);
C'est pour lire la valeur de LCD_D7 qui est (connecté à) un des LP_DATA_PINS  (qui sont connectés à LCD_D0 ... LCD_D7)
Les LP_DATA_PINS doivent être tous simultanément en mode input ou output, d'ou le passage global en input mode.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 27-10-2011 à 23:56:24    

gilou a écrit :

Citation :

Je comprends pas par contre pourquoi on mettrait LP_DATA_PINS en entrée


La ligne suivante?
pin_input_mode(LP_DATA_PINS);
C'est pour lire la valeur de LCD_D7 qui est (connecté à) un des LP_DATA_PINS  (qui sont connectés à LCD_D0 ... LCD_D7)
Les LP_DATA_PINS doivent être tous simultanément en mode input ou output, d'ou le passage global en input mode.
A+,


 
Oui, j'ai bien compris que tu voulais lire les donnée, mais pourquoi lire des données puisque c'est moi qui écrit les données.  :??:  
 
 
Mais merci, je devrais me débrouiller.
J'espère revenir avec un code qui tourne.
Merci encore Gilou, a+

Reply

Marsh Posté le 28-10-2011 à 01:13:15    

Oui mais, busy marche pas, il sort pas de la boucle.  :heink:

Reply

Marsh Posté le 28-10-2011 à 04:31:20    

j'ai installé le serveur d'impression cups.
Du coup LCD_busy termine.
J'ai toujours pas de changement sur l'afficheur par contre.
J'ai arrêté le serveur d'impression tout de même.
J'ai fais :


insmod parport
insmod parport_pc io=0x378 irq=7


J'ai bien connecter le pin 5 à la broche 16 du port parallèle avec mon étain (oui, je l'ai retrouvé).

Reply

Marsh Posté le 28-10-2011 à 10:44:52    

Tu lis LCD_D7, s'il est a 1, ça indique que l'afficheur est busy.
 

Citation :

il sort pas de la boucle

Donc on aurait toujours LCD_D7 à 1?
J'ai pourtant juste traduit le code de  

Code :
  1. void LCD_busy()
  2. {
  3.      LCD_D7   = 1;           //Make D7th bit of LCD as i/p
  4.      LCD_en   = 1;           //Make port pin as o/p
  5.      LCD_rs   = 0;           //Selected command register
  6.      LCD_rw   = 1;           //We are reading
  7.      while(LCD_D7){          //read busy flag again and again till it becomes 0
  8.            LCD_en   = 0;     //Enable H->L
  9.            LCD_en   = 1;
  10.      }
  11. }


en code avec parapin.
 
EDIT: J'ai trouvé un projet ou cet afficheur est utilisé pour construire un altimètre. Avec des routines (en assembleur) qui me semblent bien plus correctes (au vu de la doc constructeur) que celles trouvées sur les pages web que tu avais. Je retranscris ça en C et je te le poste.  
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-10-2011 à 10:53:02    

Bonjour Gilou.
 
Ok pour le bit 8.
Oui, c'était toujours busy parce qu'en fait ça lisait pas, parce que ça settait pas, parce que c'était pas en out_mode.
Maintenant c'est bon pour le busy mais toujours pas d'affichage.
J'ai testé avec des délais u poil partout, pas mieux, j'ai déplacé les instruction  set_pin sur les DB 2 9 après le set_pin de En pas mieux.
 
J'avais vu le code de l'altimettre, j'ai même tenté de le compiler. Un code en ASM, je crois...
 
Eh !
Merci Gilou. T'as déjà fait pas mal. Si t'as du temps je suis preneur.
J'y ai passé la nuit, je sais pas pourquoi ça fonctionne pas ce matin. J'ai peut-être pas tout essayé...

Reply

Marsh Posté le 28-10-2011 à 12:17:34    

Bon, a mes erreurs de transcription du code assembleur près, ce devrait marcher j'espère:
 
C'est assez brut de décoffrage, j'ai pas trop eu le temps de me relire.
Les routines  en assembleur dont je suis parti (pour une interface avec un contrôleur PIC et non un port parallèle sont sur le site du projet d’altimètre)
 

Code :
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <parapin.h>
  5. #include <sys/io.h>
  6. #define BASEPORT 0x378
  7. // correspondances LCD PARA pin à pin
  8. #define LCD_E  LP_PIN01
  9. #define LCD_D0 LP_PIN02
  10. #define LCD_D1 LP_PIN03
  11. #define LCD_D2 LP_PIN04
  12. #define LCD_D3 LP_PIN05
  13. #define LCD_D4 LP_PIN06
  14. #define LCD_D5 LP_PIN07
  15. #define LCD_D6 LP_PIN08
  16. #define LCD_D7 LP_PIN09
  17. // Si on a connecté le pin LCD 5 au pin 16 du PP et non pas au 14
  18. #define LCD_RW LP_PIN16
  19. #define LCD_RS LP_PIN17
  20. // Peut etre que faire #define LP_CONTROL_PINS LP_SWITCHABLE_PINS suffit
  21. #define LP_CONTROL_PINS (LP_PIN01 | LP_PIN16 | LP_PIN17)
  22. //  
  23. #define LCD_CNTL LP_CONTROL_PINS
  24. // LCD_DATA peut aussi être vu comme un octet
  25. #define LCD_DATA LP_DATA_PINS
  26. // instructions du LCD
  27. #define LCD_iClearDisplay  0x01
  28. #define LCD_iReturnHome    0x02
  29. #define LCD_iEntryModeSet  0x04
  30. #define LCD_iDisplayOnOff  0x08
  31. #define LCD_iShift         0x10
  32. #define LCD_iFunctionSet   0x20
  33. #define LCD_iSetCGRAMAddr  0x40
  34. #define LCD_iSetDDRAMAddr  0x80
  35. static char LCD_DDRAM_ADDR; // adresse actuelle dans la mémoire DDRAM du LCD
  36. static char LCD_LINE; // ligne actuelle sur le LCD
  37. void set_lcd_data(unsigned char data) {
  38.     // char et non int afin d'être sur de n'écrire qu'un octet
  39.     // On utilise le fait que LCD_DATA est aussi visible comme un octet
  40.     // pour set-pin
  41.     set_pin(data);
  42. }
  43. void LCD_BusyCheck() {
  44.     pin_input_mode(LCD_DATA); // Port de données en lecture  
  45.     clear_pin(LCD_RS); // LCD en mode instruction
  46.     set_pin(LCD_RW);   // LCD en mode écriture
  47.     do {
  48.         set_pin(LCD_E);
  49.         clear_pin(LCD_E); // créneau pour lancer l'opération
  50.     } while (pin_is_set(LCD_D7)); // teste le signal busy
  51.     clear_pin(LCD_RW); // LCD en mode lecture (pour éviter les conflits de bus)  
  52.     pin_output_mode(LCD_DATA); // Port de données en écriture  
  53. }
  54. void LCD_SendCommand(unsigned char command, unsigned char data) {
  55.      LCD_BusyCheck();
  56.      clear_pin(LCD_RW|LCD_RS); // LCD en mode lecture + instruction
  57.      set_lcd_data(command|data); // On place la donnée dans le bus
  58.      set_pin(LCD_E);
  59.      clear_pin(LCD_E); // créneau pour lancer l'opération
  60. }
  61. void LCD_Init() {
  62.     // usleep(2000);  // Pour l'embarque ou on attend après la mise sous tension plus de 1.5 ms (2 ms)
  63.     clear_pin(LCD_CNTL);
  64.    
  65.     set_lcd_data(0x30);
  66.     set_pin(LCD_E);
  67.     clear_pin(LCD_E); // On envoie 0011xxxx
  68.     usleep(5000);     // attente de plus de 4.1 ms (5 ms)
  69.    
  70.     set_lcd_data(0x30);
  71.     set_pin(LCD_E);
  72.     clear_pin(LCD_E); // On envoie 0011xxxx
  73.     usleep(128000);     // attente de plus de 100 ms (128 ms)
  74.    
  75.     set_lcd_data(0x30);
  76.     set_pin(LCD_E);
  77.     clear_pin(LCD_E); // On envoie 0011xxxx
  78.     // a partir de maintenant on pourra tester le signal BUSY pour l'attente
  79.     LCD_SendCommand(LCD_iFunctionSet,
  80.                     0x18);  // Interface 8 bits, 2 lignes, caracteres 5*8 pixels
  81.     LCD_SendCommand(LCD_iDisplayOnOff,
  82.                     0x04); // Allumer l'écran
  83.     LCD_SendCommand(LCD_iEntryModeSet,
  84.                     0x06); // sens g. à d., décalage=0
  85.     LCD_SendCommand(LCD_iClearDisplay,
  86.                     0x00); // effacer l'écran
  87.     LCD_DDRAM_ADDR = 0;
  88.     LCD_LINE = 1;
  89.    
  90. }
  91. void LCD_SendChar(unsigned char c) {
  92.     LCD_BusyCheck();
  93.     clear_pin(LCD_RW); // LCD en mode lecture
  94.     set_pin(LCD_RS);   // LCD en mode données
  95.     set_lcd_data(c);   // place la donnée sur le bus
  96.     set_pin(LCD_E);
  97.     clear_pin(LCD_E); // créneau pour lancer l'opération
  98.     LCD_DDRAM_ADDR++;
  99. }
  100. void LCD_SendString(unsigned char *string)
  101. {
  102.      while(*string) {             //till string ends
  103.        LCD_SendChar(*string++);  //send characters one by one
  104.      }
  105. }
  106. int main (int argc, char * argv[]) {
  107.   int parapin_init_success = 0;
  108.   if (argc == 1)  {
  109.       printf("Usage: paralcd prend au moins un argument. \n" );
  110.       return 1;
  111.   }
  112.   if (ioperm(BASEPORT, 3, 1))  {
  113.       perror("paralcd::ioperm" );
  114.       return 1;
  115.   }
  116.   parapin_init_success = pin_init_user(BASEPORT);
  117.   if (parapin_init_success != 0) {
  118.      printf("Echec de l'initialisation de parapin. \n" );
  119.   }
  120.   pin_output_mode(LP_DATA_PINS|LP_CONTROL_PINS);
  121.   LCD_Init();
  122.   LCD_SendString("Jovalise" );
  123.   clear_pin(LP_DATA_PINS|LP_CONTROL_PINS);  // vu dans les exemples de parapin
  124.   return 0;
  125. }


EDIT à 14:10 remplacé une erreur de copier coller pour la dernière commande du LCD_INIT: LCD_iEntryModeSet -> LCD_iClearDisplay
A+,


Message édité par gilou le 28-10-2011 à 14:11:51

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-10-2011 à 15:08:17    

C'est pas ça encore.
Ca affichait rien. J'ai déplacé quelque commande et j'ai ajouté des délais d'attente. Ca à fini par réagir un poil.
 
Quand je dis un poil, durant l'initialisation, avant même le premier LCD_SendCommand, ça affiche des caractère plein à moitier sur les deux première ligne et les 2 ligne suivante complètes.
J'ai changé d'afficheur entre temps, c'est le même modèle, mais comme j'avais peur d'avoir grillé le premier j'en ai soudé un autre... C'est pour quoi la longueur de ma réponse.
 
Je vais passer quelque temps dessus, je vais cherché, si tu vois des erreur....
A+

Reply

Marsh Posté le 28-10-2011 à 15:51:30    

Ca devrait être bon.
A tout hasard, fais un essai avec LCD_INIT() ou le code commence après la ligne  
// a partir de maintenant on pourra tester le signal BUSY pour l'attente
et en supprimant ce qui est avant
car c'est ainsi qu'est la routine d'initialisation sur Rickey's World , sans la partie complexe avant.
 
Si tu peux aussi tester ceci:

Code :
  1. void LCD_Init() {
  2.     // usleep(2000);  // Pour l'embarque ou on attend après la mise sous tension plus de 1.5 ms (2 ms)
  3.     clear_pin(LCD_CNTL);
  4.    
  5.     set_lcd_data(0x30);
  6.     { //Test
  7. pin_input_mode(LCD_DATA);
  8. printf("\nData Pin Status: " );
  9. printf("%s", pin_is_set(LCD_D7)?"1":"0" );
  10. printf("%s", pin_is_set(LCD_D6)?"1":"0" );
  11. printf("%s", pin_is_set(LCD_D5)?"1":"0" );
  12. printf("%s", pin_is_set(LCD_D4)?"1":"0" );
  13. printf("%s", pin_is_set(LCD_D3)?"1":"0" );
  14. printf("%s", pin_is_set(LCD_D2)?"1":"0" );
  15. printf("%s", pin_is_set(LCD_D1)?"1":"0" );
  16. printf("%s", pin_is_set(LCD_D0)?"1":"0" );
  17. printf("\n" );
  18. printf("Expected: 00110000\n" );
  19. pin_output_mode(LCD_DATA);
  20. exit 1;
  21.     }
  22. }

Juste pour tester que set_lcd_data fait bien son boulot.
A+,


Message édité par gilou le 28-10-2011 à 16:17:00

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-10-2011 à 16:56:38    

Gilou, alors en fait, j'ai un problème récurent qui disparait sous certaine condition, j'ai appelé ça un problème système.
En fait le buzy tourne en boucle sauf si avant j'arrive à initialiser avec l'imprimante, j'en voie du texte sur lp0 et j'arrête cups, normalement je m'assure avaec la commande "modprobe parport_pc io=0x378 irq=7". parfois ça marche, le boucle termine normalement.
 
Après, avec aucune des deux modif, j'ai réussi à démarrer.
Et pas d'éffet non plus sur l'afficher, qui commençais à clignoter.  :D  
17heure déjà.

Reply

Marsh Posté le 28-10-2011 à 17:04:08    

Pour la deuxieme modif, ça ta bien affiché la même chose pour les valeurs trouvée et celles attendues?
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-10-2011 à 17:07:14    

Si le busy tourne en boucle tu peux essayer de le remplacer par un délai d'attente fixe de 200 ms par exemple. Ça devrait être suffisant.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-10-2011 à 17:09:16    

Je connais pas cet opérateur, semble- t- il très intéressant ma fois.Ca m'affichet ça :

void:/home/root/paralcd# ./paralcd a
 
Data Pin Status: 11111111
Expected: 00110000

Reply

Marsh Posté le 28-10-2011 à 17:19:24    

Et sans le busy déjà, le programme plante pas dans la boucle, il sert à quoi ce teste buzy, busy, c'est occupé de mémoire.
Donc, en fait c'est la mouise quand mee non.
Rien ne s'affiche en tout cas, sa clignote même pas une fois.
 
Je remet mais délais aussi, j'ai oublié que pour que ça clgnote, j'ai déplacé du code et ajouté des délais.


Message édité par Profil supprimé le 28-10-2011 à 17:20:27
Reply

Marsh Posté le 28-10-2011 à 17:21:58    

Damned: Je viens de voir ici que sur le port // pin 14 est "hardware inverted" comme le pin 1 et le 17, MAIS PAS LE 16!
Donc c'est le pin 14 qu'il va falloir associer au pin LCD 5 et non pas le 16!
Va falloir que tu joues avec la soudure.
Avec un peu de chance, c'est ça qui fait tout foirer, car le flag RW est a 1 quand il devrait être à 0, systématiquement, je pense.
J’espère que cette histoire de "hardware inverted" fait pas que tout est à l'envers au niveau des signaux de contrôle.
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-10-2011 à 17:30:56    

gilou a écrit :

Damned: Je viens de voir ici que sur le port // pin 14 est "hardware inverted" comme le pin 1 et le 17, MAIS PAS LE 16!
Donc c'est le pin 14 qu'il va falloir associer au pin LCD 5 et non pas le 16!
Va falloir que tu joues avec la soudure.
Avec un peu de chance, c'est ça qui fait tout foirer, car le flag RW est a 1 quand il devrait être à 0, systématiquement, je pense.
J’espère que cette histoire de "hardware inverted" fait pas que tout est à l'envers au niveau des signaux de contrôle.
A+,


 
A zut, j'ai pouratnt regardé avant de changé, t'avais l'air de vouloir le mettre sur le 16, je me suis dis, je vais pas le contrarier.
:/
 
Juste une soudure.


Message édité par Profil supprimé le 28-10-2011 à 17:33:18
Reply

Marsh Posté le 28-10-2011 à 18:02:05    

Faudra changer  
#define LCD_RW LP_PIN16
par
#define LCD_RW LP_PIN14
dans le code.
 
A+,


---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-10-2011 à 18:29:02    

J'ai retester sur les deux afficheur, aucun des deux ne fonctionne.
J'ai testé l'imprimante, ça imprime.
Je suis confus, j'ai que deux afficheurs.
 
Tà pas d'autre teste, et pourquoi le port est busy ?
 [:panzani gino]
Oups, pour un fois il l'est pas.
 
Je refais les testes précédant pardon, je m'emportais.


Message édité par Profil supprimé le 28-10-2011 à 18:33:51
Reply

Marsh Posté le 28-10-2011 à 18:38:26    

void:/home/root/paralcd# ./paralcd a
 
Data Pin Status: 11111111
Expected: 00110000
 
C'est le même résultat.  [:dawa_neowen]

Reply

Marsh Posté le 28-10-2011 à 18:49:52    

Moi dejà je croyais que qu'un unsigned char était un 7bits.

Reply

Marsh Posté le 28-10-2011 à 19:13:04    

Non non, un unsigned char c'est 8 bits.
 
si tu essayes cette version modifiée du test, ça donne quoi?

Code :
  1. void LCD_Init() {
  2.     // usleep(2000);  // Pour l'embarque ou on attend après la mise sous tension plus de 1.5 ms (2 ms)
  3.     clear_pin(LCD_CNTL); // si ca colle toujours pas, essayer en inversant: set_pin(LCD_CNTL); pour voir
  4.  
  5.     set_lcd_data(0x30);
  6.     { //Test
  7. printf("\nData Pin Status: " );
  8. printf("%s", (LCD_DATA & LCD_D7)? "1":"0" );
  9. printf("%s", (LCD_DATA & LCD_D6)? "1":"0" );
  10. printf("%s", (LCD_DATA & LCD_D5)? "1":"0" );
  11. printf("%s", (LCD_DATA & LCD_D4)? "1":"0" );
  12. printf("%s", (LCD_DATA & LCD_D3)? "1":"0" );
  13. printf("%s", (LCD_DATA & LCD_D2)? "1":"0" );
  14. printf("%s", (LCD_DATA & LCD_D1)? "1":"0" );
  15. printf("%s", (LCD_DATA & LCD_D0)? "1":"0" );
  16. printf("\n" );
  17. printf("Expected: 00110000\n" );
  18. pin_output_mode(LCD_DATA);
  19. exit 1;
  20.     }
  21. }


Message édité par gilou le 28-10-2011 à 19:17:34

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le 28-10-2011 à 19:29:49    

Encore le même résultat.
 
 

void:/home/root/paralcd# ./paralcd a
 
Data Pin Status: 11111111
Expected: 00110000

Reply

Marsh Posté le 28-10-2011 à 19:43:34    

De toute façon, je fatigue, la, car c'était idiot cette modif du test.
 

Code :
  1. void LCD_Init() {
  2.     // usleep(2000);  // Pour l'embarque ou on attend après la mise sous tension plus de 1.5 ms (2 ms)
  3.     clear_pin(LCD_CNTL);
  4.     clear_pin(LCD_DATA);
  5.     set_lcd_data(0x30);
  6.     set_pin(LCD_E);
  7.     clear_pin(LCD_E);
  8.     usleep(200000);
  9.     { //Test
  10. pin_input_mode(LCD_DATA);
  11. printf("\nData Pin Status: " );
  12. printf("%s", pin_is_set(LCD_D7)?"1":"0" );
  13. printf("%s", pin_is_set(LCD_D6)?"1":"0" );
  14. printf("%s", pin_is_set(LCD_D5)?"1":"0" );
  15. printf("%s", pin_is_set(LCD_D4)?"1":"0" );
  16. printf("%s", pin_is_set(LCD_D3)?"1":"0" );
  17. printf("%s", pin_is_set(LCD_D2)?"1":"0" );
  18. printf("%s", pin_is_set(LCD_D1)?"1":"0" );
  19. printf("%s", pin_is_set(LCD_D0)?"1":"0" );
  20. printf("\n" );
  21. printf("Expected: 00110000\n" );
  22. pin_output_mode(LCD_DATA);
  23. exit 1;
  24.     }
  25. }


Ca devrait être le bon code. J'ai rajouté un clear_pin(LCD_DATA); à tout hasard.
et  
set_pin(LCD_E);
clear_pin(LCD_E);
car il faut un strobe envoyé au LCD, sinon, ca risque pas d'être lu.
 
A tout hasard, si tu remplaces le
clear_pin(LCD_CNTL);
par
set_pin(LCD_CNTL);
ça donne quoi?
 
Parce que la, je vois pas quoi trop tenter d'autre:
j'envoie une valeur au LCD, et je voudrais juste vérifier qu'il l'a reçue(je suppose qu'il garde ses pins en l'état après réception), et la, on dirait pas...
A+,


Message édité par gilou le 28-10-2011 à 19:53:21

---------------
There's more than what can be linked! --    Iyashikei Anime Forever!    --  AngularJS c'est un framework d'engulé!  --
Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed