Initialisation LCD avec pic16f877
Répondre à la discussion
Affichage des résultats 1 à 7 sur 7

Initialisation LCD avec pic16f877



  1. #1
    Fernando_86

    Initialisation LCD avec pic16f877


    ------

    Bonjour,

    C'est la première fois que j'écris un message sur ce forum. Je pense que ce type de problème (voir titre) et pour vous quelque chose de commun. J'ai trouvé de nombreux sujet sur des forums parlant de l'initialisation d'un LCD avec un pic16f877 mais je n'arrive pas à trouver le problème de mon code.
    LCD: NewHaven display NHD-C0220AZFSW-FTW
    Je programme sous mplab avec comme compilateur c: hi-tech.
    Je pose mon code complet. Si vous pouviez m'aider car le problème est que le LCD n'affiche rien. J'ai vérifié les branchements (je suis en 4 bits, sur 2 lignes ...)

    Code:
    #include <htc.h>
    #include "delay.h"
    
    #include "pic16f877.h"
    
    
    #define PIC_CLK 20 /*fréquence en MHz (4 MHz)*/
    
    
    //-------------------------------Déclaration de fonction-------------------------
    void init_PIC(void);
    void LCD_INIT(void); // Fonction d'initialisation du LCD en mode 4 bits, LCD 2x16, matrice caractère 5x8
    void lcd_write(unsigned char data); // Fonction qui prend en paramettre les données sur 8bits et les écrits en mode 4bits dans le LCD
    void write_at(const char* texte, char at); // Ecrit la chaine "texte" à l'emplacement "at"
    void LCD_STROBE(void);
    void DelayTicks( int ticks);
    void ClearLcd();
    
    
    
    //-------------------------------Définition des I/O------------------------------
    
    #define LED_POWER RA3
    #define POUSS_01 RD5
    #define POUSS_02 RD6
    
    #define LCD_D4 RB4
    #define LCD_D5 RB5
    #define LCD_D6 RB6
    #define LCD_D7 RB7
    
    
    #define LCD_RS RB3
    #define LCD_EN RB2
    
    
    
    void LCD_STROBE(void)
    {
    	LCD_EN=1;
    	DelayUs(2);
    	LCD_EN=0;
    }
    
    
    void main(void)
    {
    	init_PIC();
    	 // Temps d'attente pendant le démarrage du LCD
    	DelayMs(2000);
    	
    	LCD_INIT();
    
    
    	LED_POWER=0;
    
    
    	for (;;)
    	{
    		LED_POWER=1;
    		write_at("Romain :", 0x00);
    		DelayMs(2000);
    		LED_POWER=0;
    		DelayMs(2000);
    	}
    
    
    }
    
    
    
    
    
     
    void DelayMs(unsigned char cnt) 
    { 
    	unsigned char i; 
     	do 
     	{ 
     		i=4; 
    	 	do
     		{
     			DelayUs(250); 
     		}
     	while(--i); 
     	} 
     while(--cnt); 
    }
    
    
    
    void init_PIC(void)
    {
    
    	PORTA = 0;
    	TRISA = 0b00000000; 
    
    	PORTB = 0;
    	TRISB = 0b00000000;
    
    	PORTC = 0;
    	TRISC = 0b01000000; 
    
    	PORTD = 0;
    	TRISD = 0b11110000; 
    
    
    //gestion du PWM
     	TRISC=0x80;       // Port C en sortie sauf C7 ( RX de l'UART )
     	PR2=77;           // définit la période du signal PWM ( 25µS à 12 Mhz )
     	CCP1CON=0x0C;     // CCP1CON.5:4 = bits de poids fort du cycle = 0 , mode PWM
     	CCPR1L=38;        // au départ la valeur du signal à 1 dans le cycle est égale à 38 ( 50% )
                       // modifiez cette valeur pour modifier le rapport cyclique
     	T2CON=0x04;       // prescaler et postscaler =1 , timer 2 on
    }
    
    
    
    
    // Fonction d'initialisation du LCD en mode 4 bits, LCD 2x16, matrice caractère 5x8
    void LCD_INIT() 
    {
        DelayTicks( 10000);
      
    	LCD_RS=0;
    
    	LCD_D5=1;
    	LCD_D4=0;
    	LCD_STROBE;	// init!	
    	DelayTicks( 1000);
        
    	
    	lcd_write(0x28);
           DelayTicks( 1000);
           lcd_write(0x0C);
           DelayTicks( 1000);
        
           ClearLcd();
           lcd_write(0x02);
           DelayTicks( 1000);
      
    	LCD_RS=1;
    
    	lcd_write(0x48);
            lcd_write(0x65);
            lcd_write(0x6C);
            lcd_write(0x6C);
            lcd_write(0x6F);
    
    
    }
    
    
    void DelayTicks( int ticks)
    {
        int ctr;
        for( ctr=0; ctr<ticks; ctr++);
    }
    
    
    void ClearLcd()
    {
        // Clear display
        LCD_RS=0;
    	lcd_write(0x01);
        DelayTicks( 1000);  
    }
    
    
    
    
    // Fonction qui prend en paramettre les données sur 8bits et les écrits en mode 4bits dans le LCD
    void lcd_write(unsigned char data) 
    {
    /*
    	LCD_DATA = ( ( data >> 4 ) & 0x0F ); // On sélectionne les 4 bits de poids fort
    	LCD_STROBE();
    	Delay250Us();
    	LCD_DATA = ( data & 0x0F ); // Puis on sélectionne les 4 bits de poids faible
    	LCD_STROBE();
    	Delay250Us();
    */
    
    
    	if(data & 0x80) LCD_D7=1; else LCD_D7=0;
    	if(data & 0x40) LCD_D6=1; else LCD_D6=0;
    	if(data & 0x20) LCD_D5=1; else LCD_D5=0;
    	if(data & 0x10) LCD_D4=1; else LCD_D4=0;
    	LCD_STROBE;
    	DelayMs(1);
    	if(data & 0x08) LCD_D7=1; else LCD_D7=0;
    	if(data & 0x04) LCD_D6=1; else LCD_D6=0;
    	if(data & 0x02) LCD_D5=1; else LCD_D5=0;
    	if(data & 0x01) LCD_D4=1; else LCD_D4=0;
    	LCD_STROBE;	
    	DelayMs(1);	
    
    }
    
    
    // Ecrit le caractère "caractere" à l'emplacement "at"
    void write_char_at(char caractere, char at) 
    {
    	LCD_RS = 0;
    	lcd_write(0b10000000 | at); // Set DDRAM address : Emplacement "at"
    
    	LCD_RS = 1;
    	lcd_write(caractere);	// Affichage du caractère "caractere"
    }
    
    
    void lcd_puts(const char * s)
    {
    	LCD_RS = 1;	// write characters
    
    	while(*s) lcd_write(*s++);
    }
    
    
    
    // Ecrit le caractère "caractere" à l'emplacement actuel du curseur
    void write_char(char caractere) 
    {
    	LCD_RS = 1;
    	lcd_write(caractere);	// Affichage du caractère "caractere"
    }
    
    
    // Efface l'écran
    void clear()
    {
    	LCD_RS = 0;
    	lcd_write(1);	// Efface
    	//DelayMs(1);
    	//DelayMs(1);
    	//DelayUs(1000);
    	//DelayUs(1000);
    }
    
    
    
    // Ecrit la chaine "texte" à l'emplacement "at"
    void write_at(const char* texte, char at) 
    {
    	char i =0;
    
    	LCD_RS = 0;
    	lcd_write(0b10000000 | at); // Set DDRAM address : Emplacement "at"
    
    	LCD_RS = 1;
    
    	do
    	{
    		lcd_write(texte[i]);	// Affichage le caractère i de la chaine texte
    		i++;
    	}
    	while(texte[i]!='\0');
    }
    Merci d'avance

    -----

  2. #2
    grosmatou75001

    Re : Initialisation LCD avec pic16f877

    Bonjour et bienvenue sur fs.

    Première question obligatoire: Tu vires le PIC (ou tu le laisses en reset) et tu alimentes l'afficheur. Est-ce que tu as bien la première ligne tout en noir?

    #define PIC_CLK 20 /*fréquence en MHz (4 MHz)*/
    Tu es sûr qu'il faut donner la fréquence en MHz et non en Hz? Je ne connais pas le PIC, mais si je fais une recherche rapide Google me sort plein de résultats ou la valeur est en Hz comme chez Atmel... Et puis si tu as 4MHz pourquoi tu écrits 20?

    Vérifie déjà si tes fonctions délai fonctionnent bien (à l'oscillo ou à défaut d'un tel en faisant clignoter une LED) et ensuite on véra.

    Ah oui, ce genre de bricolages
    Code:
    void DelayTicks( int ticks)
    {
        int ctr;
        for( ctr=0; ctr<ticks; ctr++);
    }
    il y a de très fortes chances que le compilateur vire toute la boucle... Utilises les fonctions delay fournies par le fabricant du compilateur!

  3. #3
    Fernando_86

    Re : Initialisation LCD avec pic16f877

    Oui j alimente le pic. Pour le délai, c est un autre problème. Effectivement la boucle délai est du bricolage mais elle fonctionne (clignotement de les) mais pas avec les temps indiqués. Sur la carte que j'ai recuperé le quartz est en externe et il fait 20mgz. Pour les boucles delay du fabricant je ne vous pas ou les trouver ?

  4. #4
    Fernando_86

    Re : Initialisation LCD avec pic16f877

    Mais je n ai effectivement pas les lignes noires qui s affichent ...

  5. A voir en vidéo sur Futura
  6. #5
    grosmatou75001

    Re : Initialisation LCD avec pic16f877

    Citation Envoyé par Fernando_86 Voir le message
    Oui j alimente le pic.
    Non, je disais bien alimenter que l'afficheur NON branché au PIC ou alors avec le PIC tenu en reset pour voir si tu as une ligne noire. Si cela n'est déjà pas le cas inutile de se pencher sur le programme... Vérifie le contraste (broche 2 d'après ce machin)!

    Effectivement la boucle délai est du bricolage mais elle fonctionne (clignotement de les)
    étrange, le compilateur ne doit pas optimiser à fond...

    mais pas avec les temps indiqués.
    Aha! Donc elle ne fonctionne PAS (pour moi une fonction délai qui ne produit pas le délai demandé ne fonctionne pas). Premier problème à régler (après la vérif du contraste) avant de chercher plus loin.

    Sur la carte que j'ai recuperé le quartz est en externe et il fait 20mgz.
    Je veux bien, possible, mais est-tu sûr qu'il faut écrire #define PIC_CLK 20 et non #define PIC_CLK 20000000(UL) ? Enfin, si tu n'utilises pas des fonctions fournies avec le compilo tel les fonctions de délai ça ne doit pas faire de différence mais quand même...

    Pour les boucles delay du fabricant je ne vous pas ou les trouver ?
    Dans la doc? Je ne connais pas les PIC mais demande donc à un moteur de recherche (ou même la recherche interne du forum, on avait pas le même soucis il y a peu de temps?).

    Mais je n ai effectivement pas les lignes noires qui s affichent ...
    Pas bon, voir en haut.

  7. #6
    Fernando_86

    Re : Initialisation LCD avec pic16f877

    Rebonjour,

    Désolé de répondre aussi tard mais j'avance le soir sur mon projet avec mon PIC et mon LCD quand je trouve le temps. Donc d'après vos conseils, j'ai utilisé les fonctions __delay_us et __delay_ms du fabricant. J'ai également vérifié les temporisations avec un oscilloscope sur une LED que j'allumais 500ms et j'éteignais le même temps. Tout cela fonctionne et parait plus sain que le bricolage que j'avais avant. Par contre, mon LCD s'allume mais m'affiche toujours rien. Je n'ai vraiment plus de piste ....
    Avez vous des idées ?

    Merci

  8. #7
    grosmatou75001

    Re : Initialisation LCD avec pic16f877

    Citation Envoyé par grosmatou75001 Voir le message
    Vérifie le contraste (broche 2 d'après ce machin)!
    (ah tiens, si on mets qu'une citation le message est trop court...)

    Je répète: LCD alimenté et SANS actions de la part du µC tu dois voir une ligne noire.

Discussions similaires

  1. Initialisation LCD avec PIC18F2550
    Par bakualufu dans le forum Électronique
    Réponses: 1
    Dernier message: 15/05/2013, 10h35
  2. mot de pass avec pic16f877
    Par invite9b43d387 dans le forum Électronique
    Réponses: 3
    Dernier message: 14/03/2012, 20h24
  3. Pb initialisation oscillateur avec PIC24F
    Par kronanberg dans le forum Électronique
    Réponses: 7
    Dernier message: 19/05/2009, 09h04
  4. conversion avec un pic16F877
    Par invite817b2e6f dans le forum Électronique
    Réponses: 4
    Dernier message: 06/12/2006, 21h55
  5. débuter avec PIC16f877
    Par sdow dans le forum Électronique
    Réponses: 3
    Dernier message: 03/12/2006, 15h56
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...