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

Comprendre les bases de la programmation PIC
djviper16
Débutant
Débutant
Messages : 60
Enregistré en : décembre 2020

#21 Message par djviper16 » mar. 15 déc. 2020 22:19

Ah j'y crois pas ! :lol: Merci encore une fois tu m'apportes la solution.

Mon programme fonctionne en fait, c'est juste que j'avais des délais trop longs. J'ai remplacé par 20ms et ma led clignote.
J'avais mis des délais pour avoir le temps de voir la led clignoter, le timer0 est trop rapide sinon.

En mettant des délais de 65ms ça fonctionne, avec des délais de 70ms ça ne fonctionne plus. Encore un mystère pour moi. :?

Lorsqu'il y a interruption, mon programme sort-il de la boucle "while(1)" ? Ça expliquerait le phénomène, je ne vois pas autre chose.

Comprendre les bases de la programmation PIC
satinas
Expert
Expert
Messages : 1498
Enregistré en : novembre 2015

#22 Message par satinas » mar. 15 déc. 2020 22:22

Je suis perdu, si tu fais de l'interruption, je ne pourrais pas suivre, CCS est trop complexe, il faut être dedans, et je suis dehors :)
Il y a plein d'exemples sur le net.

Je comprends pas ton set_TRIS_B(0x50), c'est plutôt
set_TRIS_B(0b11011111)
set_TRIS_B(0xdf);

Comprendre les bases de la programmation PIC
djviper16
Débutant
Débutant
Messages : 60
Enregistré en : décembre 2020

#23 Message par djviper16 » mar. 15 déc. 2020 22:38

Ah oui tu as complètement raison pour set_tris_B ! Je me suis emmêlé les pinceaux, j'aurais du prendre un crayon et un papier :oops:
Je corrige de suite.

On est pas obligé d'activer les interruptions pour utiliser le timer ?
enable_interrupts(INT_TIMER0); //active le bit T0IE
bit 5 T0IE: TMR0 Overflow Interrupt Enable bit

Edit : je m'auto répond, visiblement non donc je vais pouvoir éclaircir mon programme.

Comprendre les bases de la programmation PIC
satinas
Expert
Expert
Messages : 1498
Enregistré en : novembre 2015

#24 Message par satinas » mar. 15 déc. 2020 22:41

NON
les débutants vont trop vite dans les interruptions, alors que c'est compliqué, et pas obligatoire.
TOIF fait sa vie de façon autonome, indépendamment de l'interrupt timer.
Modifié en dernier par satinas le mar. 15 déc. 2020 22:42, modifié 1 fois.

Comprendre les bases de la programmation PIC
djviper16
Débutant
Débutant
Messages : 60
Enregistré en : décembre 2020

#25 Message par djviper16 » mar. 15 déc. 2020 22:42

Oui j'ai confondu interruption et flag. Je pensais que ça marchait ensemble.
D'où l'intérêt de passer du temps pour comprendre ce qui fait quoi.

Comprendre les bases de la programmation PIC
satinas
Expert
Expert
Messages : 1498
Enregistré en : novembre 2015

#26 Message par satinas » mar. 15 déc. 2020 22:43

Ce sont des event flags :)
Activer une interruption, comme son nom l'indique, c'est prévoir l'interuption du programme vers une routine d'interruption (ISR), dès qu"un event flag passe à 1.

Comprendre les bases de la programmation PIC
djviper16
Débutant
Débutant
Messages : 60
Enregistré en : décembre 2020

#27 Message par djviper16 » mer. 16 déc. 2020 00:53

Entendu, ma prochaine étape est de faire clignoter ma led en utilisant le Timer1, des variables, et pouvoir définir des temps d'état haut et bas sans utiliser de delay.
Ensuite j'essayerai de faire ça avec des interruptions, pour ne pas encombre mon main.

J'ai revu ma copie, et réalisé 2 programmes utilisants le Timer0, l'un avec les commandes CCS, l'autre sans.

Code : Tout sélectionner

#include <16F628.h> 

#use delay(clock=4000000)                    //fréquence de l'oscillateur interne : 4MHz
#fuses INTRC_IO,NOWDT,NOPUT,NOBROWNOUT,NOMCLR,NOPROTECT,NOLVP,NOCPD    //il faut tous les mettre sinon ça marche pas
#use fast_io(B)                                // permet d'utiliser set_tris_X(), sinon CCS affecte automatiquement les ports.
#bit T0IF = 0x0B.2                                //adresse du bit flag du Timer0


void main()

{

set_TRIS_B(0xDF);                            //définit RB5 en sortie
SETUP_TIMER_0(RTCC_INTERNAL|RTCC_8_BIT|RTCC_DIV_256);    //active le Timer0 + paramètrage sur horloge interne et prédiviseur réglé à 256
//enable_interrupts(GLOBAL);                    //active les interruptions, pas besoin !
//enable_interrupts(INT_TIMER0);                //active le bit T0IE, pas besoin on n'utilise pas les interruptions ici !

T0IF=0;

set_timer0(0);                                //on remet le timer à 0

    while(1)
    {
        if (T0IF==1)                        //si flag du timer0 levé
                                            
        
{
            output_low(pin_b5);                //on éteint la led
            delay_ms(20);                    //on attend 20ms
            set_timer0(0);                  //on remet le timer à 0
            T0IF=0;                            //on remet le flag à 0
        }
        else                                 //sinon
            output_high(pin_b5);            //on allume la led
            delay_ms(20);                    //on attend 20ms
    }
}





Code : Tout sélectionner

#include <16F628.h> 

#use delay(clock=4000000)                    //fréquence de l'oscillateur interne : 4MHz
#fuses INTRC_IO,NOWDT,NOPUT,NOBROWNOUT,NOMCLR,NOPROTECT,NOLVP,NOCPD    //il faut tous les mettre sinon ça marche pas
#use fast_io(B)                                // permet d'utiliser set_tris_X(), sinon CCS affecte automatiquement les ports.

//////TMR0 REGISTER////// adresse 01h
#byte TMR0 = 0x01

//////INTCON REGISTER////// adresse 0Bh
#bit RBIF = 0x0B.0
#bit INTF = 0x0B.1
#bit T0IF = 0x0B.2    
#bit RBIE = 0x0B.3
#bit INTE = 0x0B.4
#bit T0IE = 0x0B.5
#bit PEIE = 0x0B.6
#bit GIE = 0x0B.7

//////OPTION REGISTER////// adresse 81h
#bit PS0 = 0x81.0
#bit PS1 = 0x81.1
#bit PS2 = 0x81.2
#bit PSA = 0x81.3
#bit T0SE = 0x81.4
#bit T0CS = 0x81.5
#bit INTEDG = 0x81.6
#bit RPBU = 0x81.7




void main()

{

set_TRIS_B(0xDF);                            //définit RB5 en sortie

//////INTCON REGISTER//////
RBIF=0;                                        //RB Port Change Interrupt Flag bit
INTF=0;                                        //RB0/INT External Interrupt Flag bit
T0IF=0;                                        //TMR0 Overflow Interrupt Flag bit
RBIE=0;                                        //RB Port Change Interrupt Enable bit
INTE=0;                                        //RB0/INT External Interrupt Enable bit
T0IE=0;                                        //TMR0 Overflow Interrupt Enable bit
PEIE=0;                                        //Peripheral Interrupt Enable bit
GIE=0;                                        //Global Interrupt Enable bit

//////OPTION REGISTER//////
PS0=1;                                        //Prescaler Rate Select bits
PS1=1;                                        //ici prédiviseur à 256
PS2=1;                                        //
PSA=0;                                        //Prescaler Assignment bit : 1=WatchDog, 0=Timer0
T0SE=0;                                        //TMR0 Source Edge Select bit (utile pour utilisation horloge externe sur RA4)
T0CS=0;                                        //TMR0 Clock Source Select bit : 1=RA4, 0=interne CLKOUT
INTEDG=0;                                    //Interrupt Edge Select bit : 1=interruption sur front montant, 0=interruption sur front descendant
RPBU=0;                                        //PORTB Pull-up Enable bit : ???1=portB en haute impédance, 0=potentiels pull-up ????

//////TMR0 REGISTER//////
TMR0=0x00;                                    //on remet le timer à 0



    while(1)
    {
        if (T0IF==1)                        //si flag du timer0 levé
                                            
        
{
            output_low(pin_b5);                //on éteint la led
            delay_ms(20);                    //on attend 20ms
            TMR0=0x00;                         //on remet le timer à 0
            T0IF=0;                            //on remet le flag à 0
        }
        else                                 //sinon
            output_high(pin_b5);            //on allume la led
            delay_ms(20);                    //on attend 20ms
    }
}




Comprendre les bases de la programmation PIC
satinas
Expert
Expert
Messages : 1498
Enregistré en : novembre 2015

#28 Message par satinas » mer. 16 déc. 2020 06:37

Hello
l'horloge du pic est à 4 MHz. Il lui faut 4 coups d'horloge pou exécuter une instruction, soit 1 us.
Idem pour le timer qui s'incrémente toutes les us.
Le prescaler est à 256 -> 256
C'est un timer 8 bits -> 256*256
incrémentation chaque us -> 256*256*1us soit 65,5ms

Si tu fais SetTimer(127) la durée sera de la moitié soit 33ms
Si tu fais SetTimer(200) la durée sera de 256 * (256-200) * 1us soit 14ms
C'est ainsi qu'on remplace les délais, c'est moins simple, par contre c'est pas bloquant pour le programme.
On attend par boucle que T0IF passe à 1 ou on demande à ce qu'une ISR démarre.

Comprendre les bases de la programmation PIC
djviper16
Débutant
Débutant
Messages : 60
Enregistré en : décembre 2020

#29 Message par djviper16 » jeu. 17 déc. 2020 00:10

Hello,

Merci pour les explications. Je n'ai pas eu le temps de continuer, je reviendrai poster l'avancement de mon réapprentissage.
Je me dis que mes exemples peuvent toujours servir à d'autres...

Comprendre les bases de la programmation PIC
djviper16
Débutant
Débutant
Messages : 60
Enregistré en : décembre 2020

#30 Message par djviper16 » ven. 18 déc. 2020 21:15

Bonsoir,

Toujours pour faire clignoter ma led, mais sans utiliser les "delay" cette fois. On compte le nombre de fois que le bit "T0IF" est passé à 1.
N'y a t-il pas moyen de travailler directement avec "RB5" plutôt que de passer par la variable "etat" ?

Code : Tout sélectionner

#include <16F628.h> 

#use delay(clock=4000000)                    //fréquence de l'oscillateur interne : 4MHz
#fuses INTRC_IO,NOWDT,NOPUT,NOBROWNOUT,NOMCLR,NOPROTECT,NOLVP,NOCPD    //il faut tous les mettre sinon ça marche pas
#use fast_io(B)                                // permet d'utiliser set_tris_X(), sinon CCS affecte automatiquement les ports.

//////TMR0 REGISTER////// adresse 01h
#byte TMR0 = 0x01

//////INTCON REGISTER////// adresse 0Bh
//#bit RBIF = 0x0B.0
//#bit INTF = 0x0B.1
#bit T0IF = 0x0B.2    
//#bit RBIE = 0x0B.3
//#bit INTE = 0x0B.4
//#bit T0IE = 0x0B.5
//#bit PEIE = 0x0B.6
//#bit GIE = 0x0B.7


//////OPTION REGISTER////// adresse 81h
#bit PS0 = 0x81.0
#bit PS1 = 0x81.1
#bit PS2 = 0x81.2
#bit PSA = 0x81.3
#bit T0SE = 0x81.4
#bit T0CS = 0x81.5
#bit INTEDG = 0x81.6
#bit RPBU = 0x81.7

//////VARIABLES//////
int i;                                        //variable 0 à 255 -> pour compter le nombre de flag levés
short etat;                                    //variable 0 ou 1 -> pour indiquer l'état de la sortie RB5


void main()

{
//////PORTS E/S//////
set_TRIS_B(0xDF);                            //définit RB5 en sortie

//////INTCON REGISTER//////
//RBIF=0;                                    //RB Port Change Interrupt Flag bit
//INTF=0;                                    //RB0/INT External Interrupt Flag bit
T0IF=0;                                        //TMR0 Overflow Interrupt Flag bit
//RBIE=0;                                    //RB Port Change Interrupt Enable bit
//INTE=0;                                    //RB0/INT External Interrupt Enable bit
//T0IE=0;                                    //TMR0 Overflow Interrupt Enable bit
//PEIE=0;                                    //Peripheral Interrupt Enable bit
//GIE=0;                                    //Global Interrupt Enable bit

//////OPTION REGISTER//////
PS0=1;                                        //Prescaler Rate Select bits
PS1=1;                                        //ici prédiviseur à 256
PS2=1;                                        //
PSA=0;                                        //Prescaler Assignment bit : 1=WatchDog, 0=Timer0
T0SE=0;                                        //TMR0 Source Edge Select bit (utile pour utilisation horloge externe sur RA4)
T0CS=0;                                        //TMR0 Clock Source Select bit : 1=RA4, 0=interne CLKOUT
INTEDG=0;                                    //Interrupt Edge Select bit : 1=interruption sur front montant, 0=interruption sur front descendant
RPBU=0;                                        //PORTB Pull-up Enable bit : ???1=portB en haute impédance, 0=potentiels pull-up ????

//////TMR0 REGISTER//////
TMR0=0x00;                                    //on remet le timer à 0

//////VALEURS VARIABLES//////
i=0;
etat=0;

    while(1)
    {

        if (T0IF==1)                        //si flag du timer0 levé                                    
        {
        i++;
        T0IF=0;
        }

        if (i==8)
        {
        etat=!etat;
        output_bit(PIN_B5,etat);
        i=0;
        }


    }
}





Retourner vers « Langage C »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité