Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% ont trouvé ce document utile (0 vote)
353 vues7 pages

Utilisation Des Interruptions Avec Le PIC

Télécharger au format doc, pdf ou txt
Télécharger au format doc, pdf ou txt
Télécharger au format doc, pdf ou txt
Vous êtes sur la page 1/ 7

Utilisation des interruptions avec le PIC

Claude Barbaud 10 janvier 2011

Principe:
Le fonctionnement par interruptions sur un microcontrôleur permet à celui-ci
d'exécuter une tâche(programme principal) qui peut être interrompue par un
événement. Le processeur doit alors exécuter une tâche(sous-programme)
associée à cette source d'interruption. Quand la tâche est exécutée, le processeur
revient à sa tâche principale.

On peut faire une analogie avec quelqu'un qui fait la cuisine tranquillement: il
peut être interrompu par plusieurs sources: la sonnette de la maison, le téléphone,
la minuterie de ses appareils de cuisson, le détecteur de fumée. Il doit traiter
l'événement avant de revenir à sa tâche principale. Le traitement de ces
évènements peut lui-même être interrompu par un événement jugé plus important.

De la même façon, avec un système ordiné, on doit souvent définir des priorités
dans les interruptions:
 Le traitement d'une interruption peut être interrompu par une interruption
qui lui est prioritaire.
 Le traitement d'une interruption ne doit pas être interrompu par une
interruption de niveau inférieur.
 Le traitement d'une interruption ne peut être interrompu par aucune autre.

Sources d'interruptions
Les interruptions peuvent être causées par des sources externes ou par des sources
internes

Sources externes:
 broches parallèles (Exemples: clavier, alarme)
 ports séries

Sources internes
 Timer
 Convertisseur A-N
 Reset

19-1
Exemple[PIC]: Interruption avec une source externe:
RB0
// Claude Barbaud 24 janvier 2005
//----------------------------------------------------------------
// INT_EXT.C
//
// Exemple d'utilisation de l'interruption externe.
// Chaque fois qu'il y a une interruption on fait
// clignoter le led temoin.
// la source d'interruption est un front descendant sur RB0
//----------------------------------------------------------------
#include "16F876.H"
#fuses HS,NOWDT,PUT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use RS232(Baud=19200,Xmit=PIN_C6,Rcv=PIN_C7, bits=8, errors)

#define LED PIN_A5 // Led temoin


void cligne(int x); // prototype de la fonction cligne()
//------------------------------------------------------//
// Sous programme de traitement de l'interruption //
// externe //
//------------------------------------------------------//
#int_ext // Cette directive indique que la fonction
// suivante est la tache de l'interruption
rb_ext( ) // fonction sans parametres
{
cligne(2);
}

//-------------------- Programme principal -----------------------


void main(void)
{
ext_int_edge(H_TO_L); // Front descendant
enable_interrupts(INT_EXT); // Valide l'interruption sur RB0
enable_interrupts(GLOBAL); // Valide les interruptions
cligne(4);

while(1); // ce programme ne fait rien


}

//---------------------------------------------------//
// void cligne(int x) //
// //
// Clignotement de la led verte x fois a //
// intervalle de 200 ms. //
//-------------------------------------------------- //
void cligne(int x)
{
int i;
for (i=0; i<x; ++i)
{
output_low(led);
delay_ms(80);
output_high(led);

19-2
delay_ms(80);
}
}

Source de l'interruption
La source de l'interruption est indiquée au début du sous-programme d'interruption par la
directive #int_ext . Cette directive identifie RB0 comme source de l'interruption.

Autre directive concernant les sources externes:


#int_rb changement sur B4-B7

Seules les broches définies en entrée peuvent déclencher une interruption. Ces directives
ne discriminent pas quelle entrée est la source, mais on peut utiliser bit_test()

Validation de l'interruption
L'interruption ne peut être active que si elle est validée
enable_interrupts(INT_EXT); // Valide l'interruption sur RB0
enable_interrupts(GLOBAL); // validation globale

L'interruption doit être validée individuellement (INT_EXT) et globalement.

On peut interdire une interruption par l'instruction disable_interrupt() Les paramètres sont
les mêmes:
disable_interrupts(INT_EXT);
disable_interrupts(GLOBAL);

 Gestion des priorités des interruptions

Exemple[PIC]: Interruption externe par B4-B7


// Claude Barbaud 24 janvier 2005
//----------------------------------------------------------------
// INT_RB.C
//
// Exemple d'utilisation de l'interruption externe.
// Chaque fois qu'il y a une interruption on fait
// clignoter le led temoin.
// la source d'interruption est un changement sur B4_B7
//----------------------------------------------------------------
#include "16F876.H"
#fuses HS,NOWDT,PUT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use RS232(Baud=19200,Xmit=PIN_C6,Rcv=PIN_C7, bits=8, errors)

#byte port_b = 6 // adresse du port B

#define LED PIN_A5 // Led temoin


void cligne(int x); // prototype de la fonction cligne()
//------------------------------------------------------//
// Sous programme de traitement de l'interruption //
// externe //
//------------------------------------------------------//

19-3
#int_rb
rb_ext( )
{
int lecture;
disable_interrupts(GLOBAL); // Evite de s'interrompre soi-meme
lecture = port_b & 0xF0; // isole les 4 bits d'en haut
if(bit_test(lecture, 4)) // on peut tester les bits pour
// decider des actions

cligne(4);

if(bit_test(lecture, 7))
cligne(7);
enable_interrupts(GLOBAL);
}

//-------------------- Programme principal -----------------------


void main(void)
{
set_tris_b(0xFF); // port_b en entree
enable_interrupts(INT_RB); // Valide l'interruption sur B4-B7
enable_interrupts(GLOBAL); // Valide les interruptions
cligne(4);

while(1); // ce programme ne fait rien


}

//---------------------------------------------------//
// void cligne(int x) //
// //
// Clignotement de la led verte x fois a //
// intervalle de 200 ms. //
//-------------------------------------------------- //
void cligne(int x)
{
int i;
for (i=0; i<x; ++i)
{
output_low(led);

delay_ms(200);
output_high(led);
delay_ms(200);
}
}

19-4
Exemple[PIC]: Interruption de source interne: Timer 1
// Isidore Lauzier 10/3/02 - CCS C
//----------------------------------------------------------------//
// Timer1.c //
// Démonstration de l'utilisation du timer1 //
// Le timer est programmé en tranches de 100 ms. On affiche //
// l'heure, les minutes et les secondes. //
//----------------------------------------------------------------//
#include <16F876.H>
#device ADC=10
#device PIC16F876 *=16
#fuses HS,NOWDT,PUT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use RS232(Baud=19200,Xmit=PIN_C6,Rcv=PIN_C7, bits=8, errors)

#bit TMR1IF = 0x0C.0 // Indicateur d'int. du timer1


#define TEMOIN PIN_A5

void cligne(int x);

//------------------ Variables globales --------------------------


int ms_100;
short sec;

//----------------------------------------------------------------
// #int_timer1
// Gestion des interruptions pour le chronométrage avec le
// timer1. Il est nécessaire de recharger le compteur à nouveau
// à chaque interruption. Il faut ajouter le temps de latence,
// soit le contenu du timer1 et le délai causé par la lecture
// et le chargement de cette valeur.
//----------------------------------------------------------------
#int_timer1 // Cette fonction est appelée à chaque
clock_isr1() { // 8 débordements du timer1 (65535->0).
long int cycles;
setup_timer_1(T1_DISABLED); // Arrêt pour le chargement
cycles = get_timer1(); // Temps de latence
cycles = cycles + 3038; // (65535-62500)=3035+(25/div8)=3038
set_timer1(cycles);
setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 ); // tranche de 100 ms
--ms_100;
if (!ms_100) {
sec=TRUE;
ms_100=10;
}
}

//---------------------- Programme principal ----------------------

main() {
int i, min;
cligne(1); // Témoin

19-5
ms_100=10;
i=0;
min=0;
sec=FALSE;
set_timer1(3035); // 65535-62500 = 100 ms avec
setup_timer_1( T1_INTERNAL | T1_DIV_BY_8 ); // un cristal de 20
mHz.
TMR1IF=0; // Reset de l'indicateur d'int. du
timer1
enable_interrupts(int_timer1);
enable_interrupts(GLOBAL);
do {
if (sec) {
i++;
if (i==60) {
i=0;
++min;
if (min==60) min=0;
}
printf("\r%2u:%2u",min,i);
sec=FALSE;
}
} while (TRUE);

disable_interrupts(int_timer1); // avec un crystal de 20 mHz.


}

//---------------------------------------------------//
// void cligne(int x) //
// //
// Clignotement de la led témoin x fois à //
// intervalle de 200 ms. //
//-------------------------------------------------- //
void cligne(int x) {
int i;
for (i=0;i<x;i++) {
output_high(TEMOIN);
delay_ms(100);
output_low(TEMOIN);
delay_ms(100);
}
}

19-6
Exemple: utilisation des changements sur RB7-RB5
//------------------------------------------------------//
// Claude Barbaud 25 janvier 2005 //
// Ce programme montre l'utilisation des changements de //
// B5 - B7 comme source d'interruption //
//------------------------------------------------------//

#include <16F876.H>

#fuses HS,NOWDT,NOPROTECT
#use delay(clock=20000000)

#use RS232(Baud=19200,Xmit=PIN_C6,Rcv=PIN_C7, bits=8, errors)

#byte port_b = 6
#define in 0xe0;

int last_b; // memorisation de l'ancienne valeur du port


int cmpt1, cmpt2, cmpt3;

//-------sous-programme de traitement de l'interruption--------//


#int_rb
rb_isr( ) {
byte changes;
output_low(PIN_B0);

delay_ms(100); // anti-rebond
changes = port_b & 0xe0; // RB7, RB6, RB5
if (bit_test(changes,5) != bit_test(last_b,5)) cmpt1= cmpt1+1;
if (bit_test(changes,6) != bit_test(last_b,6)) cmpt2= cmpt2+1;
if (bit_test(changes,7) != bit_test(last_b,7)) cmpt3= cmpt3+1;
last_b = changes;
printf("\n\rB5 = %u B6 = %u B7 = %u",cmpt1, cmpt2,cmpt3);
output_high(PIN_A5);
}

Main() {
set_tris_b(0xe0);
cmpt1=cmpt2=cmpt3=0;
last_b = port_b & 0xe0;
disable_interrupts(GLOBAL);
enable_interrupts(RB_CHANGE); // RB_CHANGE = INT_RB
enable_interrupts(GLOBAL);

for (;;) ;

19-7

Vous aimerez peut-être aussi