Bienvenue aux nouveaux arrivants sur FantasPic !

- Pensez à lire les règles durant votre visite, il n'y en a pas beaucoup, mais encore faut-il les respecter .
- N’hésitez pas à faire des remarques et/ou suggestions sur le Forum, dans le but de l'améliorer et de rendre vos prochaines visites plus agréables.
- Vous pouvez regarder votre "panneau de l'utilisateur" afin de configurer vos préférences.
- Un passage par "l'utilisation du forum" est recommandé pour connaître les fonctionnalités du forum.

--- L’équipe FantasPic ---
Forum général sur le langage C !

Modérateur : Jérémy

LCD en I²C
Jérémy
Administrateur du site
Administrateur du site
Messages : 2727
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#71 Message par Jérémy » mer. 9 sept. 2015 20:11

C'est ce que je pensais , en fait quand l’écran est effacé, il indique d'origine les petites flèches .

En fait, effacer l’écran reviens à remplir la DDRAM du code de ces flèches. Sur la Data-sheet en page 32, il y a une indication que je n'ai pas trop compris .

Voici mon code test, je ne crois pas avoir fais d'erreur. Peut être que Paulfjujo sera me répondre !

Code : Tout sélectionner

I2C1_Start();
     I2C1_Wr(LCD_ADR);
     I2C1_Wr(0x00);         // J'envoie une instruction
     I2C1_Wr(0x08);         // J'envoie l'extinction du LCD
        Delay_ms(5);
     I2C1_Wr(0x01);         // Instruction pour effacer
        Delay_ms(5);
     I2C1_Wr(0x0C);        // Je réactive l'ecran
        delay_ms (500);
     I2C1_Stop();
C'est en faisant des erreurs, que l'on apprend le mieux !!!

LCD en I²C avec driver PCF2119
Jérémy
Administrateur du site
Administrateur du site
Messages : 2727
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#72 Message par Jérémy » sam. 12 sept. 2015 10:43

Incompréhensible !!!!!

Bonjour à tous,

Après quelques déboires d'ordre matériels ( en enlevant mon scotch pou r tenir le LCD j'ai enlève par inadvertance l'OSC) , J'ai mis au propre mon programme afin de sortir un petit Tuto explicatif sur ce driver .

Je remets tout bien comme il faut , et patatras, ça ne fonctionne plus comme avant !!!

Suivant si j’éteins ou non ma plaque ça fonctionne ou pas . Un truc de fou qui dois ce passer à l'allumage.
Voici mon programme:

Code : Tout sélectionner

/*##################################################################################
##############################     Variable / Constante    ##########################
###################################################################################*/
char LCD_ADR 0x74;             // Adresse de l'esclave I2C
char ligne,colonneposition ;   // Déclaration variable

unsigned int i,compteur,variable;// Variable
sbit LED_RA4 at LATA4_bit ;      // Déclaration de la led sur RA4

char *text;                      // Création d'un pointeur nommé text

void efface_ecran();             // Déclaration de la fonction pour effacer l'écran
void Display_init();             // Déclaration de la fonction pour initialiser l'écran
void affiche_txt(char lignechar colonnechar *text);// Déclaration de la fonction pour afficher le texte

/*##################################################################################
############################   PROGRAMME PRINCIPAL    ##############################
##################################################################################*/
void main ()
{
  
TRISA 0b11101111 ;    // RA4 en sortie  pour la led
  
ANSELA=0;               // Configure le PORTA en digital
  
LED_RA4 ;           // On eteint la LED

  
TRISC 0b11111111 ;    // ATTENTION en I²C les pattes SDA et SCL doivent être misent en entrée( collecteur ouvert)
  
ANSELC ;            // Configure le PORTC en digital

  
I2C1_Init(100000);      // Initialisation de l'I2C
  
Delay_ms(100);          // Pause de 100 ms

  
Display_init();        // Initialise et configure l'écran

  
efface_ecran();        // Efface l'écran ( remplit l'écran avec des blanks)

  
affiche_txt (1,0,"Hello World !!!"); // Sur la 1 ligne, colonne 0 on écrit le texte
  
affiche_txt (2,0,"Compteur : ");    // Sur la 2 ligne, colonne 0 on écrit le texte

  
compteur 0;          // Initialisation du compteur à 0

//##########################    BOUCLE INFINIE    ##################################
  
while(1)
  {

    
WordToStr (compteurvariable); //
    
affiche_txt (2,11variable);   // Sur la 2 ligne, colonne 12 on écrit le texte
    
compteur compteur++;

    
LED_RA4 ;                  // J'allume la LED pour vérifier que le programme tourne
    
delay_ms (50);                 // Une marque une pause
    
LED_RA4 ;                  // On éteint la LED
    
delay_ms (50);                 // Une marque une pause
  
}
}

 
/*##################################################################################
###########################    AFFICHAGE DU TEXTE    ###############################
##################################################################################*/
void  affiche_txt (char lignechar colonnechar *text)   // Fonction avec paramètres d'entrées
    
{
        if (
ligne==1position 0x80 colonne;  // On détermine la position sur la ligne 1
        
if (ligne==2position 0xC0 colonne;  // On détermine la position sur la ligne 2

        
I2C1_Start();                // Ouverture d'une Com I2C
        
I2C1_Wr(LCD_ADR);            // Envoi de l'adresse esclave
        
I2C1_Wr(0x00);               // Byte de contrôle pour envoyer une instruction
        
I2C1_Wr(position);           // INSTRUC : position de l'ADDR du curseur 1ere ligne de 80 à 8F
        
I2C1_Repeated_Start();       // Répétition de l'ouverture de la com I2C
        
I2C1_Wr(LCD_ADR);            // Envoi de l'adresse esclave
        
I2C1_Wr(0x40);               // Byte de contrôle pour envoyer une DATA

         
i=0;                        // Raz de i
         
while (  text[i] != '\0' )  // Temps qu'on est pas la fin du texte on continue
          
{
            
I2C1_Wr0x80 text[i++] );    // Écriture de la lettre ou pointe le pointeur
          
}

         
Delay_ms(10);                      // Pause de 10ms
        
I2C1_Stop();                        // Fin de l'I2C
      
}


/*##################################################################################
#########################     INITIALISATION DE L’ÉCRAN    #########################
##################################################################################*/
void Display_init()
    {
        
Delay_ms(500);        // Une marque une pause

        
I2C1_Start();         // Ouverture de la com I²C

        
I2C1_Wr(LCD_ADR);     // Adresse de l'esclave

        // CONTROL_Mode       // bit7 -> 0=last control byte, 1=another control byte
                              // bit6 -> 0=registre inst , 1=registre Data
        
I2C1_Wr(0x00);        // bit5à0 -> 0
                              // 0b00000000 = 0x00

        // function_set       // bit7 à 5 valeurs fixes : 001
                              // bit4: 0:2x4bit, 1:8 bits
        
I2C1_Wr(0x34);        // bit3: 0 Non utilisé
                              // bit2: 0: 1ligne/32char, 1: 2lignes/16char
                              // bit1: 0: 1/18 multiplex, 1: 1/9 multiplex
                              // bit0: 0: standard instr., 1: extended instr.
                              // 0b00110100 = 0x34

        // display_ctl        // bit7 à  valeur fixe : 00001
                              // bit2: 0:display off, 1:display On
        
I2C1_Wr(0x0C);        // bit1: 0:cursor off, 1:cursor On
                              // bit0: 0:clignotement off, 1:On
                              // 0b00001100 = 0x0C

        // Entry_mode_set     // bit7à 2: valeur fixe : 000001
                              // bit1: 0:Décrémente l'adresse , 1:Incrémente (curseur vers la droite)
        
I2C1_Wr(0x06);        // bit0: 0:No shift , 1: Shift display
                              // 0b00000110 = 0x06

        // Extended instructions
        
I2C1_Wr(0x35);        // DL: 8 bits, M: 16 by two line, SL: 1:18, H: extended instruction set

        // Disp_config        // bit7à 2: valeur fixe : 000001
        
I2C1_Wr(0x05);        // bit1 : 0=left to right, 1=Right to left
                              // bit0 : 0=top to bottom  1=bottom to t

        // VLCD_SET           // Réglage du contraste  ##### OBLIGATOIRE #######
                              // bit7 : valeur fixe : 1
        
I2C1_Wr(0x98);        // bit6: 0=registre VA ; 1=registre VB
                              // bit5à 0: 000000 jusqu’à 111111 pour le contraste

        // Normal instruction
        
I2C1_Wr(0x34);        // DL: 8 bits, M: two line, SL: 1:18, H: normal instruction set

        
I2C1_Wr(0x80);        // DDRAM Address set to 00hex

        
I2C1_Wr(0x02);        // return home

        
I2C1_Stop();          // Fin de l'I2C
    
}
/*##################################################################################
##############################    EFFACE L’ÉCRAN    ################################
##################################################################################*/
void efface_ecran()
  {
      
char i ;          // Variable temporaire dans la fonction

      
I2C1_Start();         // Ouverture d'une Com I2C
      
I2C1_Wr(LCD_ADR);     // Envoi de l'adresse esclave
      
I2C1_Wr(0x00);        // Byte de contrôle pour envoyer une instruction
      
I2C1_Wr(0x80);        // INSTRUC : positionne le curseur à l'ADDR : 1ere ligne de 80 à 8F
      
I2C1_Repeated_Start();// Répétition de l'ouverture de la com I2C
      
I2C1_Wr(LCD_ADR);     // Envoi de l'adresse esclave
      
I2C1_Wr(0x40);        // Byte de contrôle pour envoyer une DATA
        
for ( i=0;i<=15;i++)// Boucle pour répéter 16 fois l'action sur la première ligne
       
{
        
I2C1_Wr(0xA0);      // Envoie d'un caractère "vide"
       
}

      
I2C1_Repeated_Start();// Répétition de l'ouverture de la com I2C
      
I2C1_Wr(LCD_ADR);     // Envoi de l'adresse esclave
      
I2C1_Wr(0x00);        // Byte de contrôle pour envoyer une instruction
      
I2C1_Wr(0xC0);        // INSTRUC : position de l'ADDR du curseur 2ieme ligne de C0 à CF
      
I2C1_Repeated_Start();// Répétition de l'ouverture de la com I2C
      
I2C1_Wr(LCD_ADR);     // Envoi de l'adresse esclave
      
I2C1_Wr(0x40);        // Byte de contrôle pour envoyer une DATA
        
for ( i=0;i<=15;i++)// Boucle pour répéter 16 fois l'action sur la deuxième ligne
       
{
        
I2C1_Wr(0xA0);      // Envoie d'un caractère "vide"
       
}

    
I2C1_Stop();            // Fin de l'I2C
   


J'allume ma plaque easyPIC7 , je charge le programme sans problème.
- "Hello World" et "Compteur :" sont bien affichés mais pas de compteur qui tourne , même pas de chiffre allumé pourtant ma led clignotte bien.

Sans éteindre ma plaque easyPIC7 je place en commentaires seulement la ligne qui affiche "compteur : "
- "Hello World" est affiché jusqu'à la c'est normal et je vois mon compteur tourné normalement :oops: .

J'éteins ma plaque et je la rallume sans rien programmé :
- "Hello World" est affiché, mais mon compteur ne s'affiche plus ( ma led clignote bien). :?:

En laissant ma plaque allumée , j’enlève les commentaires sur le texte "compteur : " et je reprogramme sans éteindre :
- - "Hello World" et "Compteur :" sont bien affichés mais pas de compteur qui tourne , même pas de chiffre allumé pourtant ma led clignotte bien.

Je ne comprends vraiment pas ! avez vous une idée ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

LCD en I²C avec driver PCF2119
Jérémy
Administrateur du site
Administrateur du site
Messages : 2727
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#73 Message par Jérémy » sam. 12 sept. 2015 18:32

Je pense avoir trouvé mon soucis .

Il s'agit en faite de la déclaration de la variable "variable" .

J'ai finis par créer un tableau de 6 colonnes ( 5pour le chiffre de int et une pour le caractère de fin) . Je viens donc placé mon compteur , dans ce tableau qui sera ensuite affiché comme du texte avec le pointeur .

Ca fonctionne Impeccable, même après un redémarrage.

Je vais pouvoir sortir mon tuto .

Code : Tout sélectionner

char variable[16];                // Création du tableau pour stockage variable en string 
C'est en faisant des erreurs, que l'on apprend le mieux !!!

LCD en I²C avec driver PCF2119
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2598
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#74 Message par paulfjujo » lun. 14 sept. 2015 15:29

Bonjour,

Ce post pour denoncer
un piege qui n'est surtout pas démontré par les exemples fournis par MikroE ..
les problemes apparaissant à partir d'une certaine taille de code (et don d'usage RAM).

Code : Tout sélectionner

char *text;                      // Création d'un pointeur nommé text    


Attention, il y a un risque potentiel d'ecrasement memoire avec l'usage d'un pointeur
non initialisé sur une table (un espace memoire defini)
dans ton code , le risque est actuellemnt null, car usage de chaine de caracteres dans le code..
mais avec l'usage de partie variable il serait judicieux d'initialiser
le pointeur txt sur une zone de TEXTE tel que:

Code : Tout sélectionner


char TEXTE
[17];   // string jusqu'à 16 car + zero terminateur
char *txt


initialiser le pointeur dans le main

Code : Tout sélectionner

txt=&TEXTE[0];


MikroC consomme de la RAM, meme si on met le texte en direct dans le programme.
ce qui occasione de nombreux deboires avec les PIC ayant peu de RAM.
Ce n'est pas le cas avec ce PIC, mais une bonne approche, passe partout,
est de copier le Texte ecrit "en dur" dans le programme , ou texte defini en Flash ROM
dans une zone RAM bien definie (table TEXTE[]) en utilisant :

Code : Tout sélectionner

// --- Copie le texte depuis ROM vers RAM
void strConstRamCpy(char *dest, const char *source) 
{
  while(*source) *dest++ = *source++ ;
  *dest = 0 ;    // terminateur
}

exemple d'usage
     strConstRamCpy(txt,"Mesure ANA  ADC0");
     LCD_Write_Text(1,txt);


La taille RAM occupée pour afficher n'importe quel texte en dur de 16 car
ne depassera jamais la partie reservee par la table TEXTE[17]
alors que si on utilise 20 fois un affichage avec le texte en dur dans l'instruction
on utilise 20x16 bytes en RAM.

ce qui à terme peut engendrer des effets indesirable.
Le compilateur compilant le tout avec Zero erreur et message compilation reussie ..
mais avec un warning 102, si les warnings sont activsés !, qui fait toute la difference..
voir les nombreux posts à ce sujet sur Mikro C pro Fourum.

Une alternative est de definir une fonction specifique pour TEXTE residant dans le code
simplement en modifiant le type passé pour la variable pointeur de texte
rajout de const => stockage en FLASH au lieu de RAM

Code : Tout sélectionner

void  affiche_CText(char ligne, char colonne,const  char *text)  
{
..
 etc 
} ;


nota: c'est ce que je fait avec ma fonction

Code : Tout sélectionner

   UART1_Write_CText(" Init Display LCD2119\r\n");

prevue pour l'UART (RS232)
au lieu de la fonction original MikroC UART1_Write_Text(txt);


d'autres solutions existent:
utiliser l'EEPROM du PIC ,
utiliser la zone FLASH ROM
pour stocker les textes à afficher
Aide toi, le ciel ou FantasPic t'aidera

LCD en I²C avec driver PCF2119
Pat
Débutant
Débutant
Messages : 43
Enregistré en : juillet 2015

#75 Message par Pat » lun. 14 sept. 2015 19:25

Normalement ces syntaxes n'utilisent pas de RAM pour le texte.

const char *text = "text";
const char text[] = "text";

car c est en mémoire programme
Le texte ne peut donc pas être modifié

dans le cas du pointeur il peut être modifier, mais le texte sera perdu si avant on a pas sauver le contenu du pointeur.

LCD en I²C avec driver PCF2119
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2598
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#76 Message par paulfjujo » dim. 20 sept. 2015 19:54

bonsoir,

En pleine evolution ...

je re poste ici, ayant retrouvé ce sujet LCD2119...!
Vraiment bizarre, tout à l'heure je ne voyais que partielement le site .. sans la partie en C !
peut etre à cause de mise à jour .

Ce LCD a un jeu de characteres 'R' en ROM ..
la ROM 'A' serait mieux appropriée ,avec reference PFC2119-AU au lieu de RU
et permettrait une relation adresse -> charactere bien mieux comprehensible et logique :
carcatere 'A' => adresse 65 (= code ascii de A)

De plus la fonction efface ecran ,incluse dans les fonctions du driver
efface avec le bon caractere 0x20 = 32 = caractere Blanc avec la version ROM 'A'
alors que le version ROM 'R' efface avec des caracteres chevrons >>>
ce qui oblige à creer une routine speciale pour effacer l'ecran avec le code 0xA0 = Blanc

Test rajout de 8 caracteres en CGRAM :
Boof ! trop de limitation !
j'envisageais de creer un jeu de 8 caracteres 8x8 pixels pour faire un bargraf horizontal contigu
(sans trou) .. hors on ne peut pas definir la ligne du bas ... réservée pour le curseur
et en largeur on ne peut pas definir les bits 7 et 6 .. qui genere donc un TROU entre les caracteres.

Memme le jeu en ROM ne le permet pas ..car les memes limitations
voir la tentative ci-jointe.

Bargraf_Rom.jpg
Bargraf_EA1_H.jpg



Affiche_8cars_CGRAM.jpg
Affiche_8cars_CGRAM.jpg






L'usage d'un tel LCD en mode ASCII (imprimable) seulement peut etre justifié
surtout avec sa liaison I2C , mais je prefere de loin un
simple afficheur nokia 8 lignes de 16 cars .. qui permet aussi du grafisme
et de faire un bargraphe horizontal sur 96 points.
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

LCD en I²C avec driver PCF2119
Jérémy
Administrateur du site
Administrateur du site
Messages : 2727
Âge : 45
Enregistré en : juillet 2015
Localisation : Dans le sud
Contact :

#77 Message par Jérémy » dim. 20 sept. 2015 20:04

Salut Paul,

Dans l'histoire du transfert les photos on sautées ? pourrait tu les remettre ?

Verrait-tu un inconvénient à ce que je duplique ton post à la suite de mon tuto pour ce driver ?

Je suis rassuré pour la fonction d'effacement, car j'avais aussi que des flèches ouf !!!!

En tout cas très joli test et très bon retour d’expérience ! Merci !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

LCD en I²C avec driver PCF2119
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2598
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#78 Message par paulfjujo » lun. 21 sept. 2015 20:45

bonsoir,

Verrait-tu un inconvénient à ce que je duplique ton post à la suite de mon tuto pour ce driver ?


Non,
like you want

les photos
Bargraf_EA1_H.jpg

Affiche_8cars_CGRAM.jpg

Bargraf_Rom.jpg


dans la serie des avantages de ce LCD2116
- Cde 2 fils (bus I2C)
- fonctionne OK sous 3,3V
- consomme tres peu
- consommation back light faible ( en mettant >= 220 ohms en serie !) mais tres suffisante
au niveau luminosité/contraste


Aucue documentation sur les straps J1 à J7 situes sur le circuit imprimé...
peut etre servent -ils à la configuration ( choix de ROM ? ou autre).
mais ou degoter cette info ?
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Aide toi, le ciel ou FantasPic t'aidera

LCD en I²C avec driver PCF2119
CamilleBC
Membre
Membre
Messages : 1
Enregistré en : septembre 2016

#79 Message par CamilleBC » ven. 23 sept. 2016 12:23

Bonjour messieurs, merci pour cette discussion enrichissante. Je suis un petit nouveau sur les forums, même s'il m'est arrivé de consulter quelques discussions. Alors bonjour !

Je me pose tout de même une question, après avoir épluché différents forums, anglophones comme francophones, je n'arrive pas à piger comment utiliser le bit CO du control byte. Je regarde vos codes et ne le vois jamais passer à 1, quand je lis l'exemple de comm' I2C sur la datasheet du PCF2119x (p.64-65), ça me donne l'impression qu'ils ne l'utilisent que juste avant de faire un read, et quand je lis la section 11.2.2 (fig31-32 p.46), j'ai l'impression qu'il faut toujours commencer par un Control byte avec CO à 1.

Help, ce n'est pas clair du tout (J'ai un code qui fonctionne pour ce que je veux faire, mais cherchant à créer un driver soft plus générique pour des utilisations futures, votre aide me serait précieuse !).

Désolé pour le nécro, mais je ne voyais pas l’intérêt de refaire un thread juste pour ça.

Merci et bonne journée !

LCD en I²C avec driver PCF2119
paulfjujo
Avatar de l’utilisateur
Expert
Expert
Messages : 2598
Âge : 73
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#80 Message par paulfjujo » mar. 27 sept. 2016 10:37

bonjour,

CamilleBC a écrit : ....
Je me pose tout de même une question, après avoir épluché différents forums, anglophones comme francophones, je n'arrive pas à piger comment utiliser le bit CO du control byte. Je regarde vos codes et ne le vois jamais passer à 1, quand je lis l'exemple de comm' I2C sur la datasheet du PCF2119x (p.64-65), ça me donne l'impression qu'ils ne l'utilisent que juste avant de faire un read, et quand je lis la section 11.2.2 (fig31-32 p.46), j'ai l'impression qu'il faut toujours commencer par un Control byte avec CO à 1.
Help, ce n'est pas clair du tout (J'ai un code qui fonctionne pour ce que je veux faire, mais cherchant à créer un driver soft plus générique pour des utilisations futures, votre aide me serait précieuse !)....


+1 Bonne remarque.

Table 10. Control byte bit description
7 CO 0 last control byte
1 another control byte follows after data/command

Effectivement ce mode n'a pas été utilisé,
probablement utile si on empile des commandes controle et data successives.
Je ne l'ai pas testé pour l'instant ..

avec ce bit 7 CO à 0 , (fig 33) on pourrait se passer d'envoyer ce byte de control (qui semble donc memorisé) pour ecrire des datas.
et ne le mettre à 1 que si on change ce mode de controle..
mais bon ..

D'ailleurs dans la mesure ou on l'utilise systematiquement, il serait peut etre preferable de le mettre toujours à 1
de sorte d'etre sur du controle byte utilisé
reste à pratiquer / tester pour verifier l'usage et l'efficacité de ce bit.
Je le re-testerai des que je pourrai revenir sur mon projet GSM2 ..utilisant le LCD2119
Aide toi, le ciel ou FantasPic t'aidera


Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 96 invités