PIC18f1320 avec un afficheur LCD - Page 2
Répondre à la discussion
Page 2 sur 2 PremièrePremière 2
Affichage des résultats 31 à 58 sur 58

PIC18f1320 avec un afficheur LCD



  1. #31
    invitefa96bd8f

    Re : PIC18f1320 avec un afficheur LCD


    ------

    Il y a une raison particulière pour laquelle tu n'utilsies pas MPLABX ?

    je ne vois nulle part tes déclarations en volatile.

    -----

  2. #32
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    Oui, j'ai toujours utilisé ce logiciel.
    Parce que je ne les ai pas mises dans le code que je vous ai envoyé, j'ai juste mis les interruptions ^^

    Code:
    volatile unsigned int cnt, tour;
    
    //sous prog d'int
    void Interrupt_B0(void);
    void Interrupt_Timer(void);
    
    // on déclare que lors d'une interruption
    #pragma code highVector=0x08
    void atInterrupthigh(void)
    {
    // on doit éxecuter le code de la fonction MyHighInterrupt
    _asm GOTO Interrupt_B0 _endasm		
    }
    #pragma code // retour à la zone de code
    
    
    #pragma code lowVector=0x18
    void atInterruptlow(void)
    {
    // on doit éxecuter le code de la fonction MyHighInterrupt
    _asm GOTO Interrupt_Timer _endasm		
    }
    #pragma code // retour à la zone de code
    
    
    // ************************
    // ****  Interruptions ****
    // ************************
    #pragma interrupt Interrupt_B0
    #pragma interrupt Interrupt_Timer
    
    void Interrupt_B0(void)
    {
                     if(INTCONbits.INT0IF==1){             // Si une interruption du port B0 est détectée
                                        tour++;            // incrémenter la variable de tour
                                        }                  // fin if
    }          
    
    void Interrupt_Timer(void)
    {
    			if (INTCONbits.TMR0IF)
    					{
    						cnt++;
    						INTCONbits.TMR0IF = 0;
    					}
    
    }
    J'ai réglé le problème du c018.O.

    Maintenant quand je compile, j'ai l'impression que tour s'incrémente comme il faut, mais le cnt ne s'incrémente jamais. On dirait que le programme ne rentre jamais dans l'interruption du Timer

  3. #33
    invitefa96bd8f

    Re : PIC18f1320 avec un afficheur LCD

    Fais voir le reste du programme alors...
    et passe à MPLABX (temps d'adaptation <1 journée), temps gagné par semaine >2h
    C'est vite rentabilisé

    UNIQUE limitation (mais rien ne t'empeche de garder les deux installés):
    Le pickit2 n'est (apparemment ?) pas reconnu : Donc plus d'analyseur logique possible

  4. #34
    paulfjujo

    Re : PIC18f1320 avec un afficheur LCD

    Citation Envoyé par gautyy5 Voir le message
    ..............Qu'est-ce que ça signifie?
    Ou sont declarées les variables cnt et tour ?
    Montre tout le code . avec le main()..

  5. #35
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    Citation Envoyé par paulfjujo Voir le message
    Ou sont declarées les variables cnt et tour ?
    Montre tout le code . avec le main()..
    D'accord, voilà tout le code:

    Code:
    /*********************************************************************************************************
    *     Tachymètre (compte-tour) numérique à base de capteur à effet Hall                                  *
    *     Quartz 20Mhz         PIC 18F1320                                                                   *
    *                                                                                                        *
    *     Formule de calcul du timer0 :                                                                      *
    *     Temps=(256-valeur Décimale chargée TMR0) * 4 * (prescaler OPTION_REG) * 1/Oscillateur en Hz        *
    *     Ce qui donne:                                                                                      *
    *     T=(256-0)*4*64*(1/20000000)= 0,0032768  >> pour avoir 0,999424 seconde  à multiplier par cnt=305   *
    *     0,999424 étant pour ce quartz  la valeur la plus proche de 1 seconde avec le timer0                *
    *                                                                                                        *
    *     Le capteur Hall connecté sur RB0 déclenche une interruption à chaque passage de l'aimant           *
    *********************************************************************************************************/
    
    #include <p18f452.h>	 // d?claration SFR pour ICD2
    #include <delays.h>	 // d?claration prototype fonctions delay
    
    #define	FOREVER	 while(1)
    
    // D?finir des nouveaux types donn?es
    
    typedef unsigned char BYTE;
    typedef unsigned int WORD;
    
    // **** configuration du circuit *************
    
    // configuration avec quartz
    #pragma config OSC = HS, OSCS = OFF
    #pragma config PWRT = OFF, BOR = OFF
    #pragma config WDT = OFF
    #pragma config CCP2MUX = OFF
    #pragma config STVR = ON
    #pragma config LVP = OFF
    #pragma config DEBUG = ON
    #pragma config CP0 = OFF, CP1 = OFF, CP2 = OFF, CP3 = OFF, CPB = OFF, CPD = OFF
    #pragma config WRT0 = OFF, WRT1 = OFF, WRT2 = OFF, WRT3 = OFF
    #pragma config WRTB = OFF, WRTC = OFF, WRTD = OFF
    #pragma config EBTR0 = OFF, EBTR1 = OFF, EBTR2 = OFF, EBTRB = OFF 
    
    // d?finitions LCD
    
    
    #define LCD_D4	PORTBbits.RB4 // data afficheur bit ? bits
    #define LCD_D5	PORTBbits.RB1 // data afficheur bit ? bits
    #define LCD_D6	PORTBbits.RB2 // data afficheur bit ? bits
    #define LCD_D7	PORTBbits.RB3 // data afficheur bit ? bits
    
    #define LCD_D4_DIR TRISBbits.TRISB4 // data direction afficheur bit ? bits
    #define LCD_D5_DIR TRISBbits.TRISB1 // data direction afficheur bit ? bits
    #define LCD_D6_DIR TRISBbits.TRISB2 // data direction afficheur bit ? bits
    #define LCD_D7_DIR TRISBbits.TRISB3 // data direction afficheur bit ? bits
    
    #define LCD_E	PORTAbits.RA1 // cde afficheur E
    //#define LCD_RW	PORTAbits.RA2 // cde afficheur RW
    #define LCD_RS	PORTAbits.RA3 // cde afficheur RS
    
    
    #define LCD_E_DIR TRISAbits.TRISA1 // cde direction afficheur E
    //#define LCD_RW_DIR TRISAbits.TRISA2 // cde direction afficheur RW
    #define LCD_RS_DIR TRISAbits.TRISA3 // cde direction afficheur RS
    
    
    
    
    
    
    //*****	variables globales ********************
    unsigned char u=0; // caractere incremente pour defilement table de caracteres
    
    //*****	prototypes de fonctions ********************
    unsigned int temp,compteur,i;
    unsigned char rotation_brute;
    unsigned short int seconde,sequence;
    void Affiche_Compteur (void);
    void w_cde_nibble( unsigned char ); // ?crit le quartet fort du char x en mode cde
    void w_cde_octet( unsigned char ) ;// ?crit le quartet fort du char x en mode cde puis le quartet faible
    void w_data_octet( unsigned char ) ;// ?crit le quartet fort du char x en mode data puis le quartet faible
    
    
    
    volatile unsigned int cnt, tour;
    
    //sous prog d'int
    void Interrupt_B0(void);
    void Interrupt_Timer(void);
    
    // on déclare que lors d'une interruption
    #pragma code highVector=0x08
    void atInterrupthigh(void)
    {
    // on doit éxecuter le code de la fonction MyHighInterrupt
    _asm GOTO Interrupt_B0 _endasm		
    }
    #pragma code // retour à la zone de code
    
    
    #pragma code lowVector=0x18
    void atInterruptlow(void)
    {
    // on doit éxecuter le code de la fonction MyHighInterrupt
    _asm GOTO Interrupt_Timer _endasm		
    }
    #pragma code // retour à la zone de code
    
    
    // ************************
    // ****  Interruptions ****
    // ************************
    #pragma interrupt Interrupt_B0
    #pragma interrupt Interrupt_Timer
    
    void Interrupt_B0(void)
    {
                     if(INTCONbits.INT0IF==1){             // Si une interruption du port B0 est détectée
                                        tour++;            // incrémenter la variable de tour
                                        }                  // fin if
    }          
    
    void Interrupt_Timer(void)
    {
    			if (INTCONbits.TMR0IF==1)
    					{
    						cnt++;
    						INTCONbits.TMR0IF = 0;
    					}
    
    }
    
    //fin interruption
    //*************	Programme principal *******************/
    void main(void)
    {
    
    //*****	init variables ****************************
     INTCON=0b10010000;                // activer detection interruption front montant RB0 avec INTE et GIE
     T0CON = 0b00000101;    		   // Config T0CON pour avoir prescaler 64 et le timer sur 16bits.
     ADCON0=0;                         // ADC désactivé
     TRISA=0;                          // PORTA configuré en sortie
     TRISB=0b00000001;                 // PORTB configuré en sortie sauf port0
     compteur=0;
     temp=0;
     seconde=0;
     tour=0;
     cnt=0;
    //*****	init Ports ****************************
    
    
    // LCD
    ADCON1=0x0E;	 // RA1,2,3 en logique (port A analogique par d?faut)
    LATA=0xF1;	 // RA1,2,3 ? 0 force par le LATCH (pour pas de glitch sur E !)
    PORTA=0xF1;	 // RA1,2,3 ? 0 force par le port (pour pas de glitch sur E !) par securit? ! bof !
    LCD_E_DIR=0;	 // ports en sortie
    // LCD_RW_DIR=0;	 // ports en sortie
    LCD_RS_DIR=0;	 // ports en sortie
    LCD_D4_DIR=0;	 // ports en sortie
    LCD_D5_DIR=0;	 // ports en sortie
    LCD_D6_DIR=0;	 // ports en sortie
    LCD_D7_DIR=0;	 // ports en sortie
    
    //*****	init LCD      ****************************
    w_cde_nibble( 0x30 ); // 3 control
    Delay10KTCYx(150);	// delay = 15mS
    w_cde_nibble( 0x30 ); // 3 control
    Delay10KTCYx(50);	// delay = 5mS
    w_cde_nibble( 0x30 ); // 3 control
    Delay10TCYx(50);	// delay = 100?S
    w_cde_nibble( 0x20 ); // 2 mode 4 bits
    
    w_cde_octet( 0x28 ) ;// fonction set attention si 2F il ecrit en bas a droite ? l'envers avec  4 caracteres de masques (affiche a partir du 5eme car ecrit !)
      w_cde_octet( 0x0F ) ;// display on
    w_cde_octet( 0x06 ) ;// mode d'entree
    w_cde_octet( 0x01 ) ;// clear display (facultatif)
    w_cde_octet( 0x80 ) ;// DDRAM 0000 (facultatif)
    w_cde_octet( 0x02 ) ;// home (facultatif)
    Delay1KTCYx(250);	// delay = 5mS INDISPENSABLE pour CDE HOME !
    
    w_cde_octet( 0x83 )  ;// 4eme case de la 1ère ligne
    w_data_octet( 0x54 ) ;// T
    w_data_octet( 0x41 ) ;// A
    w_data_octet( 0x43 ) ;// C
    w_data_octet( 0x48 ) ;// H
    w_data_octet( 0x59 ) ;// Y
    w_data_octet( 0x4D ) ;// M
    w_data_octet( 0x45 ) ;// E
    w_data_octet( 0x54 ) ;// T
    w_data_octet( 0x52 ) ;// R
    w_data_octet( 0x45 ) ;// E
    
    w_cde_octet( 0xC0 ) ;// passage seconde ligne
    w_cde_octet( 0xC8 ) ;// passage milieu seconde ligne
    
    w_data_octet( 0x54 ) ;// T
    w_data_octet( 0x52 ) ;// R
    w_data_octet( 0x2F ) ;// /
    w_data_octet( 0x4D ) ;// M
    w_data_octet( 0x4E ) ;// N
    
    //*****	init Interrupt ****************************
    TMR0L=0;
    TMR0H=0;
    T0CONbits.TMR0ON = 1; // Timer 0 marche (debut du comptage)
    INTCONbits.TMR0IE = 1; // Autorisation source d'interruption
    INTCONbits.GIE = 1; // Autorisation globale des interruptions
    
    //*****	boucle forever ****************************
    FOREVER	 // boucle forever
    {
    
    	Affiche_Compteur();               // Fonction d'affichage sur LCD
    
    }
    }
    
     //***** ecriture des fonctions ****************************
    
    void Affiche_Compteur (void) // fonction d'affichage de nombre sur plusieurs digits
    
    	{           
    		unsigned int temp;
    		unsigned char rotation_brute;
    
           if(cnt==305){                         // lorsque l'on compte 1 seconde (voir commentaire entête)
                      compteur= tour*60;         // Multiplier le nombre de tour/seconde par 60 (pour tour/min)
                      i=tour;
                      cnt=0;                     // RAZ variable cnt
                      tour=0;
                      INTCONbits.INT0IE = 1;     // Activer RB0/INT interruption
                      seconde++;
            }                                    // Fin if
    
    		rotation_brute = (compteur/1000)+48;
    		temp = compteur % 1000;
    		w_cde_octet( 0xC0 ) ;						   // passage seconde ligne
    		w_cde_octet( 0xC3 )	;						   // passage à la 4eme case de la seconde ligne
    		w_data_octet( rotation_brute ) ;			   // Afficher les milliers
    		rotation_brute = (temp/100)+48;
    		temp = temp % 100;
    		w_data_octet( rotation_brute ) ;//             // Afficher les centaines
    		rotation_brute = (temp/10)+48;
    		w_data_octet( rotation_brute ) ;//             // Afficher les dizaines
    		rotation_brute = (temp % 10)+48;
    		w_data_octet( rotation_brute ) ;//             // Afficher les unités
    	
    	}
    
    
    void w_cde_nibble( unsigned char x) // écrit le quartet fort du char x en mode cde
        {
            LCD_RS=0;   // mode cde
            LCD_E=1;    // monte enable
            if (x&0x80)  LCD_D7=1; else LCD_D7=0;   // écriture des bits
            if (x&0x40)  LCD_D6=1; else LCD_D6=0;   // écriture des bits
            if (x&0x20)  LCD_D5=1; else LCD_D5=0;   // écriture des bits
            if (x&0x10)  LCD_D4=1; else LCD_D4=0;   // écriture des bits
            LCD_E=0;    // descends enable
            Delay10TCYx(50); // delay = 100µS
        }
    
    
    void w_cde_octet( unsigned char x) // écrit le quartet fort du char x en mode cde puis le quartet faible
        {
            LCD_RS=0;   // mode cde
            LCD_E=1;    // monte enable
            if (x&0x80)  LCD_D7=1; else LCD_D7=0;   // écriture des bits
            if (x&0x40)  LCD_D6=1; else LCD_D6=0;   // écriture des bits
            if (x&0x20)  LCD_D5=1; else LCD_D5=0;   // écriture des bits
            if (x&0x10)  LCD_D4=1; else LCD_D4=0;   // écriture des bits
            LCD_E=0;    // descends enable
            Delay10TCYx(5); // delay = 10µS
            LCD_E=1;    // monte enable
            if (x&0x08)  LCD_D7=1; else LCD_D7=0;   // écriture des bits
            if (x&0x04)  LCD_D6=1; else LCD_D6=0;   // écriture des bits
            if (x&0x02)  LCD_D5=1; else LCD_D5=0;   // écriture des bits
            if (x&0x01)  LCD_D4=1; else LCD_D4=0;   // écriture des bits
            LCD_E=0;    // descends enable
            Delay10TCYx(50); // delay = 100µS
        }
    
    void w_data_octet( unsigned char x ) // écrit le quartet fort du char x en mode data puis le quartet faible
    
        {
            LCD_RS=1;   // mode data
            LCD_E=1;    // monte enable
            if (x&0x80)  LCD_D7=1; else LCD_D7=0;   // écriture des bits
            if (x&0x40)  LCD_D6=1; else LCD_D6=0;   // écriture des bits
            if (x&0x20)  LCD_D5=1; else LCD_D5=0;   // écriture des bits
            if (x&0x10)  LCD_D4=1; else LCD_D4=0;   // écriture des bits
            LCD_E=0;    // descends enable
            Delay10TCYx(5); // delay = 10µS
            LCD_E=1;    // monte enable
            if (x&0x08)  LCD_D7=1; else LCD_D7=0;   // écriture des bits
            if (x&0x04)  LCD_D6=1; else LCD_D6=0;   // écriture des bits
            if (x&0x02)  LCD_D5=1; else LCD_D5=0;   // écriture des bits
            if (x&0x01)  LCD_D4=1; else LCD_D4=0;   // écriture des bits
            LCD_E=0;    // descends enable
            Delay10TCYx(50); // delay = 100µS
        }

  6. #36
    paulfjujo

    Re : PIC18f1320 avec un afficheur LCD

    relit la datasheet et en particulier la figure en 9-1 Interrupt logic
    pour comprendre pourqoui le timer0 ne reponds pas..( evolution de cnt)

  7. #37
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    Citation Envoyé par paulfjujo Voir le message
    relit la datasheet et en particulier la figure en 9-1 Interrupt logic
    pour comprendre pourqoui le timer0 ne reponds pas..( evolution de cnt)
    J'ai indiqué précedemment que j'ai changé de PIC, je n'utilise plus le 18f1320, mais maintenant j'utilise le 18f452

  8. #38
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    J'ai changé les priorités d'interruptions, en fait le programme ne va que dans celle qui est à l'adresse 0x08, et jamais dans 0x18 et je ne vois pas comment faire pour que les 2 soient prises en compte.
    Car je dois faire en même temps:
    1 interruption pour le timer qui incrémente "cnt"
    1 interruption sur le port B0 qui incrémente "tour"

    Il faudrait qu'elles fonctionnent en parallèle, en même temps pour le bon fonctionnement du système..

  9. #39
    paulfjujo

    Re : PIC18f1320 avec un afficheur LCD

    Il faudrait qu'elles fonctionnent en parallèle, en même temps pour le bon fonctionnement du système..
    ça n'existe pas ! a moins d'avoir un systeme multi processeurs !

    dans l'interrupt High level tu mets les 2 interrupts à traiter
    RB0 et Timer0
    Code:
    if ((...TMR0IE==1) && (INTCONbits.TMR0IF ==1))
    {
    	cnt++;
    	INTCONbits.TMR0IF = 0;
    }
     
    {
       // syntaxe à corriger !!!
     if (( bit enable IT RB0==1) && (INTCONbits.INT0IF==1))  
    {             // Si une interruption du port B0 est détectée
                 tour++;            // incrémenter la variable de tour
          NTCONbits.INT0IF=0;
     }

  10. #40
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    Citation Envoyé par paulfjujo Voir le message
    ça n'existe pas ! a moins d'avoir un systeme multi processeurs !

    dans l'interrupt High level tu mets les 2 interrupts à traiter
    RB0 et Timer0
    Code:
    if ((...TMR0IE==1) && (INTCONbits.TMR0IF ==1))
    {
    	cnt++;
    	INTCONbits.TMR0IF = 0;
    }
     
    {
       // syntaxe à corriger !!!
     if (( bit enable IT RB0==1) && (INTCONbits.INT0IF==1))  
    {             // Si une interruption du port B0 est détectée
                 tour++;            // incrémenter la variable de tour
          NTCONbits.INT0IF=0;
     }
    Merci!
    Mais j'ai l'impression qu'on atteint pas les 305 au bout d'une seconde. Parce que la valeur de "tour" n'est pas bonne quand cnt est à 305.
    Soit ça vient de la détection des fronts sur RB0 qui est mauvaise, soir le timer ne déborde pas aux 0,0032768s voulues (T=(256-0)*4*64*(1/20000000)= 0,0032768)


    Interruption:

    Code:
    volatile unsigned int cnt, tour;
    
    //sous prog d'int
    void Interrupt_B0(void);
    
    // on déclare que lors d'une interruption
    #pragma code highVector=0x08
    void atInterrupthigh(void)
    {
    // on doit éxecuter le code de la fonction MyHighInterrupt
    _asm GOTO Interrupt_B0 _endasm		
    }
    #pragma code // retour à la zone de code
    
    
    
    // ************************
    // ****  Interruptions ****
    // ************************
    #pragma interrupt Interrupt_B0
    
    void Interrupt_B0(void)
    {
    
    				 if (INTCONbits.INT0IF==1) 
    				{             // Si une interruption du port B0 est détectée
    				             tour++;            // incrémenter la variable de tour
    				 			 INTCONbits.INT0IF=0;
     				}
    
                     if (INTCONbits.TMR0IF==1)
    				{
    							cnt++;
    							INTCONbits.TMR0IF = 0;
    				
    
    							if (cnt=305)
    							{
    									    compteur= tour*60;         // Multiplier le nombre de tour/seconde par 60 (pour tour/min)
    						                i=tour;
    						                cnt=0;                     // RAZ variable cnt
    						                tour=0;
    					                    INTCONbits.INT0IE = 1;     // Activer RB0/INT interruption
    					                    seconde++;
    										INTCONbits.TMR0IF = 0;
    							}						
     				}
    }          
    
    
    //fin interruption
    Main:

    Code:
    void main(void)
    {
    
    //*****	init variables ****************************
     INTCON=0b10010000;                // activer detection interruption front montant RB0 avec INTE et GIE
     T0CON = 0b00000101;    		   // Config T0CON pour avoir prescaler 64 et le timer sur 16bits.
     ADCON0=0;                         // ADC désactivé
     TRISA=0;                          // PORTA configuré en sortie
     TRISB=0b00000001;                 // PORTB configuré en sortie sauf port0
     compteur=0;
     temp=0;
     seconde=0;
     tour=0;
     cnt=0;
    //*****	init Ports ****************************
    
    
    // LCD
    ...
    ...
    
    //*****	init LCD      ****************************
    ...
    ...
    
    //*****	init Interrupt ****************************
    TMR0L=0;
    TMR0H=0;
    T0CONbits.TMR0ON = 1; // Timer 0 marche (debut du comptage)
    INTCONbits.TMR0IE = 1; // Autorisation source d'interruption
    INTCONbits.GIE = 1; // Autorisation globale des interruptions
    
    //*****	boucle forever ****************************
    FOREVER	 // boucle forever
    {
    
    	Affiche_Compteur();               // Fonction d'affichage sur LCD
    
    }
    }
    Fonction affichage:

    Code:
    void Affiche_Compteur (void) // fonction d'affichage de nombre sur plusieurs digits
    
    	{           
    		unsigned int temp;
    		unsigned char rotation_brute;
    
    		rotation_brute = (compteur/1000)+48;
    		temp = compteur % 1000;
    		w_cde_octet( 0xC0 ) ;						   // passage seconde ligne
    		w_cde_octet( 0xC3 )	;						   // passage à la 4eme case de la seconde ligne
    		w_data_octet( rotation_brute ) ;			   // Afficher les milliers
    		rotation_brute = (temp/100)+48;
    		temp = temp % 100;
    		w_data_octet( rotation_brute ) ;//             // Afficher les centaines
    		rotation_brute = (temp/10)+48;
    		w_data_octet( rotation_brute ) ;//             // Afficher les dizaines
    		rotation_brute = (temp % 10)+48;
    		w_data_octet( rotation_brute ) ;//             // Afficher les unités
    	
    	}

  11. #41
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    Ce qui est bizarre, c'est que quand je mets 1Hz, je dois donc voir 60tr/mn, et c'est le cas!
    Mais quand je mets 10Hz sur le port RB0, je dois donc voir 600tr/mn, mais je vois 480tr/mn, idem si je mets 100Hz -> 4980tr/mn.

  12. #42
    paulfjujo

    Re : PIC18f1320 avec un afficheur LCD

    pas bien,le test !


    Code:
    if (cnt=305)
    {
    compteur= tour*60;         // Multiplier le nombre de tour/seconde par 60 (pour tour/min)
    i=tour;
    cnt=0;                     // RAZ variable cnt
     tour=0;
    INTCONbits.INT0IE = 1;     // Activer RB0/INT interruption
    seconde++;
    INTCONbits.TMR0IF = 0;
    }

    Code:
    if (cnt==305)
    si compteur, seconde sont utilisés ailleurs, les déclarer aussi en volatile

    Valider les interruption via GIE=1; qu'apres l'init complete des variables et du LCD..
    juste avant la boucle sans fin.

  13. #43
    paulfjujo

    Re : PIC18f1320 avec un afficheur LCD

    calcul tempo timer0 pour 1 seconde ???
    soir le timer ne déborde pas aux 0,0032768s voulues (T=(256-0)*4*64*(1/20000000)= 0,0032768)

    à quoi correspond la valeur 305 ?
    à 20Mhz
    init timer0 à 0x0000
    init timer0 sur 16 bits !
    prescaler=1/64
    il faut deja 838mS pour faire un tour !
    s'il faut attendre 305 tours ?


    avec init à 26472 soit TMRH=0x67 et TMRL=0x68
    et prescaler=128 => 1000,03mS

  14. #44
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    J'ai changé ça je m'en suis rendu compte!
    J'ai un prescaler de 4 avec mon Timer, donc j'utilise cnt==19!

    Ca marche nikel la modification quand je suis en mode Debugger, en revanche quand je passe en programmer ça ne fait pas la même chose...

  15. #45
    paulfjujo

    Re : PIC18f1320 avec un afficheur LCD

    soit 1 interrupt toutes les 52.43mS


    Dans la mesure ou tu geres 2 sources d'interruption imbriquees
    il vaut mieux utiliser le prescaler du Timer0
    comme je te l'ai preconisé,

    avec init à 26472 soit TMRH=0x67 et TMRL=0x68
    et prescaler=128 => 1000,03mS
    car tu n'as dans ce cas, qu'une seule interruption par seconde au lieu de 19 !
    qui viennent , eventuellement, pertuber celle de RB0...

  16. #46
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    Alors verdict avec ces réglages:
    Lorsque j'ai 10Hz par exemple, il m'affiche 1020tr/mn en debugger, et 5580tr/mn en programmer... (au lieu de 600)

  17. #47
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    Et bizarrement en programmer, quand je me met en plus haute fréquence, ça me donne les résultats attendus.
    Exemple: pour 100Hz, j'ai bien les 6000tr/mn (6060 exactement, mais à ce stade on va pas être tatillon ^^), et pour 150Hz, j'ai bien 9000 aussi...
    Tandis que pour 10Hz, j'ai 3180 et pour 15Hz, j'ai 3360 ...

  18. #48
    paulfjujo

    Re : PIC18f1320 avec un afficheur LCD

    J'ai faits des test avec un PIC18F26K22 at 16MHz
    et le timer0 calé sur 1 seconde


    resultat sur terminal , SANS le multiplicateur par 60 pour lire en Hz !
    SANS DEBUGER

    avec 2Hz
    11:38:31.140> Seconde=00156 Compteur=00002
    11:38:31.640> Seconde=00156 Compteur=00002
    11:38:32.203> Seconde=00157 Compteur=00002
    11:38:32.703> Seconde=00157 Compteur=00002
    11:38:33.203> Seconde=00158 Compteur=00002

    avec 50Hz
    11:39:31.625> Seconde=00216 Compteur=00050
    11:39:32.125> Seconde=00216 Compteur=00050
    11:39:32.687> Seconde=00217 Compteur=00050
    11:39:33.187> Seconde=00217 Compteur=00050
    11:39:33.687> Seconde=00218 Compteur=00050

    avec 1000Hz
    11:40:25.750> Seconde=00269 Compteur=01002
    11:40:26.296> Seconde=00270 Compteur=01002
    11:40:26.859> Seconde=00270 Compteur=01002
    11:40:27.421> Seconde=00271 Compteur=01001
    11:40:28.046> Seconde=00271 Compteur=01001
    11:40:28.609> Seconde=00272 Compteur=01002

    AVEC DEBUGER ON
    1:51:11.312> Seconde=00008 Compteur=00997
    11:51:11.875> Seconde=00009 Compteur=00997
    11:51:12.437> Seconde=00009 Compteur=00997
    11:51:13.000> Seconde=00010 Compteur=00997
    11:51:13.562> Seconde=00010 Compteur=00997
    11:51:14.125> Seconde=00011 Compteur=00998

    On voit que le debugger , utilisant des ressources du MCU, altere le resultat..
    C'est NORMAL...

    Code:
    //declarations
    volatile unsigned int  tour;
    volatile unsigned int compteur,seconde;
    //.. etc ..
    
    
    dans interrupt high level
    ... etc ....
      
      if ((INTCONbits.INT0IE==1)&&(INTCONbits.INT0IF==1)) 
    	{      // Si une interruption du port B0 est détectée
    		tour++;            // incrémenter la variable de tour
    		INTCONbits.INT0IF=0;
     	}
    
     
      if((INTCONbits.TMR0IE == 1)&&(INTCONbits.TMR0IF==1))
      {
    	    INTCONbits.TMR0IF = 0;
    	    TMR0H=0x85;   // 34286   0x85EE  at 16Mhz  ou  0x6768 at 20Mhz
    	    TMR0L=0xEE; 
    	    compteur= tour;    //    *60;         // Multiplier le nombre de tour/seconde par 60 (pour tour/min)
    	    tour=0;
    	    seconde++;
       }	  
    
    ...  etc ..
    Code:
    void  main()
    {
    
    OSCCON=0x70;     // 16Mhz	
    
    .. etc..
    
    PORTB = 0;
    LATB=0;
    ANSELB=0;
    TRISB = 0xFF ; 
    INTCON2bits.RBPU = 0;  // enable PORTB internal pullups
    WPUBbits.WPUB0 = 1;   // enable pull up on RB0
    
    ... etc..
    
    compteur=0;
    seconde=0;
    tour=0;
    
    INTCON=0; 
    
    Init_UART1();
    Put_RS('*');
    CRLF();
    Put_RS('#');
    CRLF();
    Put_RS(CLS);   // clear  Vbray terminal Screen
    Tempo(100000L);
    
    T0CON=0;
    
    T0CONbits.T0PS2=1;// prescaler = 1/128
    T0CONbits.T0PS1=1;
    T0CONbits.T0PS0=0;
    
    TMR0H=0x85;   // 34286   at 16Mhz  
    TMR0L=0xEE; 
    //TMR0H=0x67; // at 20Mhz  prescaler=128   26472 => 1000,03 mS
    //TMR0L=0x68; 
    T0CONbits.TMR0ON = 1; // Timer 0 marche (debut du comptage)
    
    RCONbits.IPEN=0;
    INTCON2bits.INTEDG0=1; // front montant RB0
    INTCON2bits.TMR0IP=1; // high level
    INTCON2bits.RBIP=0; 
    INTCONbits.PEIE = 1; 
    RCSTA1bits.CREN= 1 ;
    PIE1bits.RC1IE = 1;
    INTCONbits.INT0IF=0; 
    INTCONbits.INT0IE=1;  // autorise RB0 interrupt
    INTCONbits.TMR0IE = 1; // Autorise TMR0 interrupt
    INTCONbits.PEIE = 1;   // autorisation des IT des périphériques
    
    INTCONbits.GIE = 1;    // active global interrupt
    
    CRLF();
    while(1)
     {
     k=fprintf(_H_USART,"Seconde=%05u Compteur=%05u \r\n",seconde,compteur);
     Tempo(150000);
     }
    }

    Il y a quelques variantes de code du au type de PIC different
    Le timer0 etant sur une seconde, il n'y a pas besoin de comptabiliser le nb d'interruption
    pour y arriver.

    nota: j'ai en plus l'interruption UART1 activée.. No problemo
    Dernière modification par paulfjujo ; 22/05/2014 à 11h03.

  19. #49
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    Code:
    //*****	prototypes de fonctions ********************
    unsigned int temp,i;
    unsigned char rotation_brute;
    unsigned short int sequence;
    void Affiche_Compteur (void);
    void w_cde_nibble( unsigned char ); // ?crit le quartet fort du char x en mode cde
    void w_cde_octet( unsigned char ) ;// ?crit le quartet fort du char x en mode cde puis le quartet faible
    void w_data_octet( unsigned char ) ;// ?crit le quartet fort du char x en mode data puis le quartet faible
    
    
    volatile unsigned int  tour;
    volatile unsigned int compteur,seconde;
    
    //sous prog d'int
    void Interrupt_B0(void);
    
    // on déclare que lors d'une interruption
    #pragma code highVector=0x08
    void atInterrupthigh(void)
    {
    // on doit éxecuter le code de la fonction MyHighInterrupt
    _asm GOTO Interrupt_B0 _endasm		
    }
    #pragma code // retour à la zone de code
    
    
    
    // ************************
    // ****  Interruptions ****
    // ************************
    #pragma interrupt Interrupt_B0
    
    void Interrupt_B0(void)
    {
    
    				 if ((INTCONbits.INT0IE==1) && (INTCONbits.INT0IF==1)) 
    				{             // Si une interruption du port B0 est détectée
    				             tour++;            // incrémenter la variable de tour
    				 			 INTCONbits.INT0IF=0;
     				}
    
                     if ((INTCONbits.TMR0IE==1) && (INTCONbits.TMR0IF ==1))
    				{
    
    									    compteur = (tour); // *60;         // Multiplier le nombre de tour/seconde par 60 (pour tour/min)
    										TMR0H=0x67;
    										TMR0L=0x68;
    						                tour=0;
    					                    INTCONbits.INT0IE = 1;     // Activer RB0/INT interruption
    					                    seconde++;
    										INTCONbits.TMR0IF = 0;
    											
     				}
    }
    
    
    //fin interruption
    Code:
    void main(void)
    {
    
    //*****	init variables ****************************
     TRISA=0;                          // PORTA configuré en sortie
     TRISB=0b00000001;                 // PORTB configuré en sortie sauf port0
     compteur=0;
     temp=0;
     seconde=0;
     tour=0;
    //*****	init Ports ****************************
    
    
    // LCD
    ... ... ...
    
    //*****	init LCD      ****************************
    ... ... ...
    
    //*****	init Interrupt ****************************
    T0CON = 0b00000110;    		   // Config T0CON pour avoir prescaler 128 et le timer sur 16bits.
    TMR0H=0x67;
    TMR0L=0x68;
    T0CONbits.TMR0ON = 1; // Timer 0 marche (debut du comptage)
    RCONbits.IPEN=0;
    INTCON2bits.INTEDG0=1; // front montant RB0
    INTCON2bits.TMR0IP=1; // high level
    INTCON2bits.RBIP=0; 
    
    INTCONbits.PEIE = 1; 
    INTCONbits.INT0IF=0; 
    INTCONbits.INT0IE=1;  // autorise RB0 interrupt
    INTCONbits.TMR0IE = 1; // Autorise TMR0 interrupt
    INTCONbits.PEIE = 1;   // autorisation des IT des périphériques
    
    INTCONbits.GIE = 1;    // active global interrupt
    
    //*****	boucle forever ****************************
    FOREVER	 // boucle forever
    {
    
    	Affiche_Compteur();               // Fonction d'affichage sur LCD
    
    }
    }
    J'ai bien suivi vos conseils donc pour le programme comme vous pouvez voir, mais je suis désolé je maintiens ma position, je ne sais pas pourquoi en programmer il me donne des résultats faussés dès que je passe en dessous des 100Hz.
    30Hz -> affiche 62Hz
    40Hz -> affiche 68Hz
    60Hz -> affiche 78Hz
    80Hz -> affiche 87Hz
    100Hz -> affiche 103Hz
    700Hz -> affiche 703Hz

  20. #50
    paulfjujo

    Re : PIC18f1320 avec un afficheur LCD

    Tu es sur de ton affichage.?
    teste en dur avec une valeur compteur fixée et definie ..

    pourquoi ne pas utiliser
    itoa Convert a 16-bit signed integer to a string.

    Code:
    // declarer un buffer :
    char txt[16];
    
    void Affiche_resultat()
    {
    int i,k;
    itoa(compteur,txt);
    k=strlen(txt);
    w_cde_octet( 0xC3 )	; // seconde ligne 4em position
    for (i=0;i<k;i++)
    {
    w_data_octet( txt[i] );
    } 
    }
    Peux-tu aussi montrer la bouille du signal d'entree à F=30Hz et a 1000Hz
    C'est bien un signal carré 0V à 5V qui entre en direct sur RB0...

    moi , j'ai une R de 2,7K entre RB0 et 0V, pour bien fixer le 0V

  21. #51
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    Citation Envoyé par paulfjujo Voir le message
    Tu es sur de ton affichage.?
    teste en dur avec une valeur compteur fixée et definie ..

    pourquoi ne pas utiliser
    itoa Convert a 16-bit signed integer to a string.

    Code:
    // declarer un buffer :
    char txt[16];
    
    void Affiche_resultat()
    {
    int i,k;
    itoa(compteur,txt);
    k=strlen(txt);
    w_cde_octet( 0xC3 )	; // seconde ligne 4em position
    for (i=0;i<k;i++)
    {
    w_data_octet( txt[i] );
    } 
    }
    Peux-tu aussi montrer la bouille du signal d'entree à F=30Hz et a 1000Hz
    C'est bien un signal carré 0V à 5V qui entre en direct sur RB0...

    moi , j'ai une R de 2,7K entre RB0 et 0V, pour bien fixer le 0V
    La je peux plus l'envoyer aujourd'hui je suis pas au boulot.
    Mais oui j'avais déjà testé avec une valeur définie pour vérifier l'affichage, ça marchait très bien pourtant.

    Qu'est ce qu'un iota? Je n'ai jamais vu cela et je ne comprends pas le code alors :/

    Pour ce qui est du signal je fais rentrer un signal carré de 0 à 5V directement sur RB0 sans résistance.

  22. #52
    paulfjujo

    Re : PIC18f1320 avec un afficheur LCD

    Qu'est ce qu'un iota? pas qu'un peu ! itoa
    MPLAB® C18 C Compiler Libraries
    2005 Microchip Technology Inc.
    DS51297F-page 121
    4.3 DATA CONVERSION FUNCTIONS

  23. #53
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    Quand je donne une valeur brut à "compteur", elle s'affiche correctement sur le LDC. Ca ne vient donc pas de l'affichage.

    Alors avec le itoa, cela ne résout pas le problème, lorsque je suis en programmer ça m'affiche les mêmes valeurs lorsque je passe sous les 100Hz.
    Ca rajoute même un autre problème: si je passe de 4 chiffres à 3 chiffres sur l'afficheur, le 4ème chiffre reste affiché, il n'est pas effacé.

  24. #54
    paulfjujo

    Re : PIC18f1320 avec un afficheur LCD

    bonjour

    en programmer
    mode release pour la compilation?
    en Debugger
    mode debug pour la compilation ?

    La plupart du temps on a plutot des probleme avec des frequences rapides ...
    20Hz c'est relativement tres lent !
    N'y aurait-il pas un probleme de Watchdog
    visible que pour les basses frequences , vu que la periode est longue...

    Post ta configuration complete
    #pragma config ... etc...

    est-ce que ton programme tourne tout le temps dans la boucle FOREVER..
    A verifier en affichant un compteur sur une autre ligne du LCD







    : si je passe de 4 chiffres à 3 chiffres sur l'afficheur, le 4ème chiffre reste affiché, il n'est pas effacé
    Cette fonction ne cadre pas le resultat..
    en voici une autre qui assure aussi le positionnement à ligne colonne du LCD
    les chiffres non significatif en amont sont remplaces par des blans..
    (nota: on pourrait aussi mettre des zeros)

    Code:
    #define LCD_LINE1 0x80      // 0x00 + bit D7=1 
    #define LCD_LINE2 0xC0      // 0x40 + bit D7=1 
    #define LCD_LINE3 0x94      // 0x14 + bit D7=1 
    #define LCD_LINE4 0xD4      // 0x54 + bit D7=1 
    
    
      // entier cadre sur 5 digits completé par des blancs a gauche
    void Write_Word_2_LCD(unsigned int M,int line,int col)   
    {
     unsigned int i,k;
     switch (line)
     {
     case 1: { w_cde_octet((LCD_LINE1+col,1); break; };    
     case 2: { w_cde_octet((LCD_LINE2+col,1); break; };   
     case 3: { w_cde_octet((LCD_LINE3+col,1); break; };
     case 4: { w_cde_octet((LCD_LINE4+col,1); break; };   
     }
     itoa(M,txt);
     k=strlen(txt);
     for (i=k;i<4;i++) 
     { 
     w_data_octet('  ' );
     } 
     for (i=0;i<k;i++)
    {
      w_data_octet(txt[i] );  
     } 
    }
    
    et dans le main() ....
    
    
    //variable à declarer  !
    unsigned int Cpt;
    
    Cpt=0;
    
    FOREVER	 // boucle forever
    {
    Write_Word_2_LCD(Cpt,LCD_LINE_3,3);  
    Write_Word_2_LCD(compteur,LCD_LINE_4,3);  
    Cpt++;
    }
    
    }
    Dernière modification par paulfjujo ; 23/05/2014 à 10h16.

  25. #55
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    Est-il possible d'incrémenter ma valeur "tour" lors d'un front montant ET descendant?

  26. #56
    paulfjujo

    Re : PIC18f1320 avec un afficheur LCD

    Citation Envoyé par gautyy5 Voir le message
    Est-il possible d'incrémenter ma valeur "tour" lors d'un front montant ET descendant?
    oui, mais cela va changer quoi ?

    il suffit d'inverser à chaque fois , dans l'interrupt , le bit designant le type de front
    de detection montant ou descendant.
    tu auras donc le double de la frequence.



    Code:
    // dans l'interrupt RB0
    INTCON2bits.INTEDG0=INTCON2bits.INTEDG0 ^ 1; // avec un XOR
    Mais je ne vois pas en quoi cela changerait ton probleme ...
    RB0 peut compter jusqu'à 1HZ ( 1 coup par seconde)

    donne les elements demandés , si tu veux continuer à avoir de l'aide...

    Rappel:


    montre la bouille du signal 20Hz à l'entree RB0 (oscilloscope)
    au cas ou tu aurait 2 fronts montant si le signal carré est fortement differencié...(deformé).

    La plupart du temps on a plutot des probleme avec des frequences rapides ...
    20Hz c'est relativement tres lent !
    N'y aurait-il pas un probleme de Watchdog
    visible que pour les basses frequences , vu que la periode est longue...

    Post ta configuration complete
    #pragma config ... etc...

    est-ce que ton programme tourne tout le temps dans la boucle FOREVER..
    A verifier en affichant un compteur sur une autre ligne du LCD
    Dernière modification par paulfjujo ; 23/05/2014 à 13h09.

  27. #57
    invite56c261eb

    Re : PIC18f1320 avec un afficheur LCD

    J'ai testé le programme directement sur le moteur, et plus par un GBF et ça marche correctement!
    Je vous remercie pour votre aide qui m'a été précieuse!

    J'aurais une dernière question par rapport à cela: est-il possible d'enregistrer les valeurs du compte tour sur une application de l'ordi?
    Je m'explique: il va bien falloir rouler avec la moto. Est-ce que je peux enregistrer toutes les valeurs du compte sur un intervalle de temps voulu? On avait pour idée d'acheter un mini PC pour réaliser cela.

    Suppression de l'image hébergée hors du site Cram 64.

  28. #58
    invite728b013d

    Re : PIC18f1320 avec un afficheur LCD

    Bonjour, je viens de supprimer l'image du post précédent, suis cette procédure :

    http://forums.futura-sciences.com/el...-sabonner.html

    pour la modération, Cram 64.

Page 2 sur 2 PremièrePremière 2

Discussions similaires

  1. Piloter un afficheur avec un pic
    Par invite9702c63e dans le forum Électronique
    Réponses: 21
    Dernier message: 28/04/2010, 09h49
  2. compteur decompteur avec afficheur
    Par invite00671cf1 dans le forum Électronique
    Réponses: 17
    Dernier message: 28/09/2007, 19h57
  3. afficheur LCD avec clavier
    Par invite412b515c dans le forum Électronique
    Réponses: 3
    Dernier message: 19/04/2007, 18h24
  4. Problème avec afficheur LCD
    Par invite890ff058 dans le forum Électronique
    Réponses: 5
    Dernier message: 20/12/2005, 18h00
  5. Gestion d'un afficheur avec un PIC
    Par invitee1ad6ffc dans le forum Électronique
    Réponses: 3
    Dernier message: 08/12/2005, 21h28
Dans la rubrique Tech de Futura, découvrez nos comparatifs produits sur l'informatique et les technologies : imprimantes laser couleur, casques audio, chaises gamer...