J'ai tellement galéré pour réussir à faire fonctionner cet écran , que je me devais de faire un petit tuto, pour partager mes erreurs et solutions si jamais quelqu'un tomberai sur les mêmes problématiques que moi.
Je n'ai pas la prétention de vous expliquer la communication l'I²C voici un excellent document très bien écrit :
Je vous propose juste un programme qui fonctionne bien chez moi . Je remercie au passage Paulfjujo qui m'a quasiment fournit le code clef en main, et qui à su être patient pour m'aider .
Configuration :
- PIC18F45K22
- IDE : MikroC Pro for PIC Version 6.6.2
- Compilateur : Mikro prog suite fo PIC V 2.32
- Plaque Easy PIC V7
- Utilisation des connecteurs MikroBus pour relier l'i²C
Attention!! Les pièges à éviter :
- Il faut mettre des Résistances de pull-Up sont les broches RC3 et RC4 ( SDA et SCL) de votre PIC, entre 4.7k et 10k feront l'affaire. Elles sont INDISPENSABLES pour établir la communication I²C.
- Vous devez aussi mettre les broches RC3 et RC4 en entrées grâce au registre TRIS. afin de les configurer en collecteur ouvert indispensable pour que le maitre prenne la communication.
- La configuration du contraste est primordiale, n'évitez pas cette étape.
- Vérifiez que que votre écran est actif avec le registre "display_ctl" il s'agit du bit2 de ce registre qui doit être à "1" pour l'activer.
Les conseils :
- Attention l'alimentation est en 3V et non en 5V.
- Soyez sûr et certain de l'Adresse I²C de votre équipement , sous peine de vous voir refaire toutes vos test ! Faire clignoté une LED pour vérifier votre adresse I²C, si elle clignote pas c'est que l'I²C est bloqué donc mauvaise adresse.
- Le compteur est un integer , donc sur 5 caractères ( int va de 0 à 65535), donc sur l’écran il faut réserver 5 caractères et faire attention pour que cela n'écrase pas du texte.
Code : Tout sélectionner
/*##################################################################################
############################## Variable / Constante ##########################
###################################################################################*/
#define LCD_ADR 0x74; // Adresse de l'esclave I2C en constante
char ligne,colonne, position ; // Déclaration variable
unsigned int i,compteur; // Variable
sbit LED_RA4 at LATA4_bit ; // Déclaration de la led sur RA4
char *text; // Création d'un pointeur nommé text
char variable[6]; // Création du tableau pour stockage variable en string
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 ligne, char colonne, char *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 = 0 ; // On éteint la LED
TRISC = 0b11111111 ; // ATTENTION en I²C les pattes SDA et SCL doivent être misent en entrée( collecteur ouvert)
ANSELC = 0 ; // 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 (compteur, variable); // On transforme la variable en string pour affichage
affiche_txt (2,11, variable); // Sur la 2 ligne, colonne 12 on va affiché le compteur
compteur = compteur++; // On incrémente le compteur
LED_RA4 = 1 ; // J'allume la LED pour vérifier que le programme tourne
delay_ms (50); // Une marque une pause
LED_RA4 = 0 ; // On éteint la LED
delay_ms (50); // Une marque une pause
}
}
/*##################################################################################
########################### AFFICHAGE DU TEXTE ###############################
##################################################################################*/
void affiche_txt (char ligne, char colonne, char *text) // Fonction avec paramètres d'entrées (voir tuto sur fonctions)
{
if (ligne==1) position = 0x80 + colonne; // On détermine la position sur la ligne 1
if (ligne==2) position = 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_Wr( 0x80 + 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 = 0 ; // 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
}
Astuces perso :
- Étant novice j'aime bien faire clignoter une LED pour voir l'état de mon programme .
Le résultat en vidéo:
http://www.dailymotion.com/video/x36m35h