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
Pat
Débutant
Débutant
Messages : 43
Enregistré en : juillet 2015

#11 Message par Pat » mar. 25 août 2015 09:36

CGRAM Adresse 0000
I2C1_Wr( 0b01000000 ); // Envoi d'un byte control pour écrire les graphiques

DDRAM adresse 0000
I2C1_Wr( 0b10000000 ); // Envoi d'un byte control pour écrire des données

paragraphe
10.2.27

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

#12 Message par Jérémy » mar. 25 août 2015 09:45

Bonjour Pat,

Après lecture de la DS, sur le point que tu indique, je ne comprends pas ce que tu essaye de me dire . Certainement car je ne sais pas la différence entre la CGRAM et la DDRAM .

Que voudrais-tu que je fasse au juste ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

LCD en I²C
paulfjujo
Avatar de l’utilisateur
Maître
Maître
Messages : 3260
Âge : 75
Enregistré en : juillet 2015
Localisation : 01800
Contact :

#13 Message par paulfjujo » mar. 25 août 2015 15:15

bonjour,


En effet, il fallait elaguer au maximum le code d'exemple..

Peut-tu connecter un terminal RS232 sur ton appli ?
pour l'utiliser en mode debugger en ligne..
il faut un PC avec une COM ou un convertissuer RS232/USB
et soit un MAX232 si tu es en 5V ou un MAX332 si tu es en 3,3V
ou un simple interface à 2 transistors (qui peut couvrir les 2 cas de figure)
cela est plus facile qu'avec une led , meme si à peine plus compliqué
vu que dans ce cas on ne gere pas la Reception UART , ni interruption.



Code : Tout sélectionner



void check_device
(unsigned short dev_address)
{
I2C1_Start();
 if (I2C1_Wr(dev_address))
 {
  sprintf(txt,"Device at adresse %02X  is not found",dev_address);
 }
 else
 
{
  sprintf(txt,"Device at adresse %02X found OK",dev_address);
   }
   UART1_Write_Text(txt);  
  I2C1_Stop
();
  
 UART1_Write(13);UART1_Write(10); // =  CRLF();  
}

   
   I2C1_Init
(100000);
   UART1_Write_CText("test presence LCD: \r\n");
  check_device(LCD_ADR)  ;
  UART1_Write(13);UART1_Write(10);
  
  
// reponse found confirme si le LCD est bien à cette adresse

 




pour ECRIRE un charactere sur le LCD,
I2C_Write est nettement insuffisant!
A mon avis, il faut une sequence d'ecriture sililaire à celle-ci
void LCD_putch(unsigned char d)

la problematique est qu'on ne sait pas encore si LE PCF gere en interne les meme bits de commande et data
qu'un classique LCD standard.
Je n'ai pas le courage (et le temps) de potasser cette D.S.
(trop de LCD differents deja vu)



Code : Tout sélectionner


void LCD_putch
(unsigned char d)
{
  unsigned char lcddata;
  // Put the Upper 4 bits data
  lcddata = (& 0xF0)|LCD_BL|LCD_RS;
  status=I2C1_Wr(addr,lcddata | LCD_EN);
  Delay_uS(5);     
  
// Write Enable Pulse E: Hi -> Lo
  status=I2C1_Wr(addr,lcddata & ~LCD_EN);
  Delay_uS(5);      
  
// Put the Lower 4 bit data
  lcddata = ((<< 4) & 0xF0)|LCD_BL|LCD_RS;
  status=I2C1_Wr(addr,lcddata | LCD_EN);
  Delay_uS(5);       
  
// Write Enable Pulse E: Hi -> Lo
  status=I2C1_Wr(addr,lcddata & ~LCD_EN);
  Delay_uS(5);   
}

char cx;
int status;
sbit LED at LATE0_bit;
sbit LED_Direction at TRISE0_bit;


......
LED_Direction=0;
LED=0;
 cx=32;
 while(1)
  {
    LCD_putch('P');         // Affiche la lettre "P"
   LCD_putch('H');         // Affiche la lettre "H"
   LCD_putch(cx');         // Affiche tous les car imprimable de 32 à 96
   LED=1;             // Pour vérifier que le programme tourne
    delay_ms(500);          // Je fais clignoter une led sur PORTE RE0
   LED=0;
    delay_ms(500);
    cx++;
    if (cx>96) cx=3;
  }



Aide toi, le ciel ou FantasPic t'aidera

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

#14 Message par Jérémy » mar. 25 août 2015 16:46

Peut-tu connecter un terminal RS232 sur ton appli ?

Sur ma plaque easyPIV V7 je pense que c'est intégrer

un convertissuer RS232/USB

Oui j'ai un câble comme ça !

J'ai toutes les leds de branchées sur ma carte , se serait plus simple non? Genre allumée une led quand le signal est bon . Et je resserre l’étau en faisant des test , plein de test ; je pense qu'au final je gagnerais du temps . l'adresse sur 7 bits donc 128 adresse a tester !

Bon je dis ça je dis rien ;

J'essaye vos lignes ce soir !
C'est en faisant des erreurs, que l'on apprend le mieux !!!

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

#15 Message par Pat » mar. 25 août 2015 17:31

DDRAM c est la mémoire des caractères affichés
et la CGRAM ce sont les dessins des caractères programmables

Pour voir les caractères c est la DDRAM !

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

#16 Message par Pat » mar. 25 août 2015 17:35

normalement en I2C on finit par un stop.
Sur le datasheet il y a un P , je ne sais pas si c est un stop.
Mais dans ta séquence il n'a pas de stop ...

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

#17 Message par Jérémy » mar. 25 août 2015 18:21

Pat a écrit :Source du message normalement en I2C on finit par un stop.
Sur le datasheet il y a un P , je ne sais pas si c est un stop.


Je crois il faut que je le retrouve , que le STOP n'est pas obligatoire .

Ps: @paulfjujo, je dispose d'un analyseur pour I²C , être plus pratique pour vérifier la liaison I²C ?

Si j'ai compris ton programme, dans ton premier programme on cherche la bonne adresse I²C , mais je ne vois pas d'incrémentation de celle ci ?
C'est en faisant des erreurs, que l'on apprend le mieux !!!

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

#18 Message par Jérémy » mar. 25 août 2015 19:23

Bon avant de passer au chose serieuses ( quand les enfants seront couchés) , j'ai fais un petit test vite fait en arrivant à la maison .

Avec mon programme tout pourris , j'ai seulement reduis les tempo pour bien les voir à l'analyseur .

On voir l'I2C et la courbe rouge il s'agit de la led temoin .

on voit que l'I2C c'est pas top quand même je n'arrive même pas à decoder un caractere envoyé .

Code : Tout sélectionner

#define LCD_ADDR 0x74           // 0b0111 0100
#define LCD_CLEAR 0x01          // 0b0000 0001
#define LCD_HOME  0x02          // 0b0000 0010
#define Control_byte 0x00       // 0b0000 0000
#define Function_set 0x20       // 0b0010 0000
#define Display_ctl 0x0E        // 0b0000 1110
#define Entry_mode_set 0x06     // 0b0000 0110


void Ecran_init()              // routine d'initialisation page 64 de la DS
{
  Delay_ms(50);                // Attente apres l'allumage
  I2C1_Start();
  I2C1_Wr( LCD_ADDR );          // Envoie l'adresse de l'esclave
  Delay_ms(5);
  I2C1_Wr( Control_byte );      // Envoi byte control pour ecrire des fonctions
  Delay_ms(5);
  I2C1_Wr( Function_set );      // Envoi d'un byte function_set
  Delay_ms(5);
  I2C1_Wr( Display_ctl );       // Envoi d'un byte control
  Delay_ms(5);
  I2C1_Wr( Entry_mode_set );    // Envoi d'un Entry_mode_set
  Delay_ms(5);
  I2C1_Start();
  Delay_ms(5);
  I2C1_Wr( LCD_ADDR );
  Delay_ms(5);
  I2C1_Wr( 0b01000000 );      // Envoi d'un byte control pour écrire des données
  Delay_ms(5);
 }

void main()
{
  ANSELB  = 0;                // Configure les broches en digital
  ANSELC  = 0;
  ANSELE  = 0;
  
  PORTB 
= 0;                 // PORTB en sortie
  PORTC = 0;
  PORTE = 0;
  
  TRISB 
= 0;                 // Mise a 0 du port B
  TRISC = 0;
  TRISE = 0;

  Delay_ms(150);         // Attente pour stabilisation

  I2C1_Init(100000);     // Initialisation de l'I2C

  Ecran_init();          // Initialisation du LCD


  while(1)
  {
    I2C1_Wr(0x50 );         // Affiche la lettre "P"
    I2C1_Wr(0x48 );         // Affiche la lettre "H"
    
    PORTE 
= 0;              // Pour verifier que le programme tourne
    delay_ms(50);          // Je fais clignoter une led
    PORTE = 1;
    delay_ms(50);


  }
}


Image

Image
C'est en faisant des erreurs, que l'on apprend le mieux !!!

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

#19 Message par Jérémy » mar. 25 août 2015 20:45

Le hic paulfjujo , c'est que je ne peux pas debugger tes proposition car ,je ne comprends pas ce que tu fais !

j'ai essayer d’écrire ceci , mais j'ai une erreur de compilation
[spoil]

Code : Tout sélectionner

#define LCD_ADDR 0x74           // 0b0111 0100
#define LCD_CLEAR 0x01          // 0b0000 0001
#define LCD_HOME  0x02          // 0b0000 0010
#define Control_byte 0x00       // 0b0000 0000
#define Function_set 0x20       // 0b0010 0000
#define Display_ctl 0x0E        // 0b0000 1110
#define Entry_mode_set 0x06     // 0b0000 0110

void LCD_putch(unsigned char d)
{
  
unsigned char lcddata;
  
// Put the Upper 4 bits data
  
lcddata = (0xF0)|LCD_BL|LCD_RS;
  
status=I2C1_Wr(addr,lcddata LCD_EN);
  
Delay_uS(5);
  
// Write Enable Pulse E: Hi -> Lo
  
status=I2C1_Wr(addr,lcddata & ~LCD_EN);
  
Delay_uS(5);
  
// Put the Lower 4 bit data
  
lcddata = ((<< 4) & 0xF0)|LCD_BL|LCD_RS;
  
status=I2C1_Wr(addr,lcddata LCD_EN);
  
Delay_uS(5);
  
// Write Enable Pulse E: Hi -> Lo
  
status=I2C1_Wr(addr,lcddata & ~LCD_EN);
  
Delay_uS(5);
}

char cx;
int status;
sbit LED at LATE0_bit;
sbit LED_Direction at TRISE0_bit;


void Ecran_init()              // routine d'initialisation page 64 de la DS
{
  
Delay_ms(50);                // Attente apres l'allumage
  
I2C1_Start();
  
I2C1_WrLCD_ADDR );          // Envoie l'adresse de l'esclave
  
Delay_ms(5);
  
I2C1_WrControl_byte );      // Envoi byte control pour ecrire des fonctions
  
Delay_ms(5);
  
I2C1_WrFunction_set );      // Envoi d'un byte function_set
  
Delay_ms(5);
  
I2C1_WrDisplay_ctl );       // Envoi d'un byte control
  
Delay_ms(5);
  
I2C1_WrEntry_mode_set );    // Envoi d'un Entry_mode_set
  
Delay_ms(5);
  
I2C1_Start();
  
Delay_ms(5);
  
I2C1_WrLCD_ADDR );
  
Delay_ms(5);
  
I2C1_Wr0b01000000 );      // Envoi d'un byte control pour écrire des données
  
Delay_ms(5);
 }

void main()
{
  
ANSELB  0;                // Configure les broches en digital
  
ANSELC  0;
  
ANSELE  0;
  
  
PORTB 0;                 // PORTB en sortie
  
PORTC 0;
  
PORTE 0;
  
  
TRISB 0;                 // Mise a 0 du port B
  
TRISC 0;
  
TRISE 0;

  
Delay_ms(150);         // Attente pour stabilisation

  
I2C1_Init(100000);     // Initialisation de l'I2C

  
Ecran_init();          // Initialisation du LCD


  
LED_Direction=0;
LED=0;
 
cx=32;
 while(
1)
  {
    
LCD_putch('P');         // Affiche la lettre "P"
   
LCD_putch('H');         // Affiche la lettre "H"
   
LCD_putch('cx');         // Affiche tous les car imprimable de 32 à 96
   
LED=1;             // Pour vérifier que le programme tourne
    
delay_ms(500);          // Je fais clignoter une led sur PORTE RE0
   
LED=0;
    
delay_ms(500);
    
cx++;
    if (
cx>96cx=3;
  }
[/spoil]

D'apres la DS sans même affiché de caractere , a l'initialisation je devrais voir le curseur clignoter en début de ligne .
Comme je ne l'ai pas, j'en deduis que mon initialisation ne se fait pas , ou mal.
C'est en faisant des erreurs, que l'on apprend le mieux !!!

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

#20 Message par Jérémy » mar. 25 août 2015 23:14

Et be c'est la galère !!

Après trois heures de test et de modifs, toujours rien !!!

Il y as quand même du mieux au niveau de l'analyseur logique .

J'ai donc bien toute mes trames I²C qui partent , mais pourquoi mon curseur ne clignote pas , pourquoi !!!! :cry:

Image

Image

J'ai essayé de faire fonctionner tes codes paulfjujo , mais je n'ai pas réussis !.

Vraiment je vois plus quoi faire d'autre !

Code : Tout sélectionner

#define LCD_ADDR 0x74           // 0b0111 0100
#define LCD_CLEAR 0x01          // 0b0000 0001
#define LCD_HOME  0x02          // 0b0000 0010
#define Control_byte 0x00       // 0b0000 0000
#define Function_set 0x24       // 0b0010 0000
#define Display_ctl 0x0E        // 0b0000 1110
#define Entry_mode_set 0x06     // 0b0000 0110


/*################################################################################*/
/*#########################     INITIALISATION     ###############################*/
/*################################################################################*/
void Ecran_init()              // routine d'initialisation page 64 de la DS
{

  
I2C1_Start();

  
I2C1_Wr(LCD_ADDR);          // Envoie l'adresse de l'esclave  0b0111 0100 = 0x74

  
I2C1_Wr(Control_byte);      // Envoi byte control pour mettre RS à 0
                              // Rs=0 -> envoi de données

  // Envoi d'un function_set  // bit 7:5 valeur fixe : 001
                              // bit4: 0:2x4bit, 1:8 bits
  
I2C1_Wr(Function_set);      // bit3: 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.
                              // 0b00100100 = 0x24

  // Envoi d'un byte control  // bit 7:3 valeur fixe : 00001
                              // bit2: 0:display off, 1:display On
  
I2C1_Wr(0b00001110);        // bit1: 0:cursor off, 1:cursor On
                              // bit0: 0:clignotement off, 1:On

  // Envoi d'un mode_set      // bit 7:2 valeur fixe : 000001
                              // bit1: 0:Decremente l'adresse , 1:Incremente (curseur vers la droite)
  
I2C1_Wr(Entry_mode_set);    // bit0: 0:No shift , 1: Shift display

  
I2C1_WrLCD_ADDR );        // Envoie l'adresse de l'esclave  0b0111 0100 = 0x74

  
I2C1_Wr0b01000000 );      // 0x40 Envoi d'un byte control pour écrire des données

 
}
/*################################################################################*/
/*######################     PROGRAMME PRINCIPAL     #############################*/
/*################################################################################*/
void main()
{
  
ANSELB  0;                // Configure les broches en digital
  
ANSELC  0;
  
ANSELD  0;
  
  
PORTD 0;
 
  
TRISD 0;

  
I2C1_Init(100000);     // Initialisation de l'I2C
  
Delay_ms(100);         // Attente  pour stabilisation apres l'allumage

/*################################################################################*/
/*#########################     BOUCLE INFINIE     ###############################*/
/*################################################################################*/
  
while(1)
  {
    
PORTD 1;          // aAllume led test
    
Ecran_init();       // Va faire l'initialisation de l'écran
    
delay_ms(5);        // petite pause

    
I2C1_Wr(LCD_HOME);  // renvoie du curseur au depart
    
I2C1_Wr(0x50 );     // Affiche la lettre "P"
    
I2C1_Wr(0x48 );     // Affiche la lettre "H"

    
I2C1_Stop();        // Fin de l'I2C
    
PORTD 0;          // Pour verifier que le programme tourne
    
delay_ms(100);      // Je fais clignoter une led

  
}
C'est en faisant des erreurs, que l'on apprend le mieux !!!


Retourner vers « Langage C »

Qui est en ligne

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