PIC en C - Fonctions
PIC en C - Fonctions
PIC en C - Fonctions
Sommaire
Sommaire ............................................................................................................................ 2 Introduction .......................................................................................................................... 3 Structure de ce document .................................................................................................... 4 Le matriel ncessaire ......................................................................................................... 4 La platine d'essai ................................................................................................................. 4 Les fonctions........................................................................................................................ 5 Gnralits ....................................................................................................................... 5 Fonction sans paramtres ................................................................................................ 6 Fonction avec paramtres d'entre .................................................................................. 8 Fonction avec paramtres de sortie ............................................................................... 11 Fonction avec paramtres d'entre et de sortie ............................................................. 12 Les interruptions ................................................................................................................ 13 Gnralits ..................................................................................................................... 13 Le PIC 16F84 ................................................................................................................. 13 Exemples ....................................................................................................................... 15
Page 2/17
Introduction
Les microcontrleurs PIC de la socit Microchip sont depuis quelques annes dans le "hit parade" des meilleures ventes. Ceci est en partie d leur prix trs bas, leur simplicit de programmation, les outils de dveloppement que l'on trouve sur le NET.
Aujourd'hui, dvelopper une application avec un PIC n'a rien d'extraordinaire, et tous les outils ncessaires sont disponibles gratuitement. Voici l'ensemble des matriels qui me semblent les mieux adapts. Ensemble de dveloppement (diteur, compilateur, simulateur) : MPLAB de MICROCHIP http://www.microchip.com Logiciel de programmation des composants: IC-PROG de Bonny Gijzen http://www.ic-prog.com Programmateur de composants: PROPIC2 d'Octavio Noguera voir notre site http://electronique-facile.com
Pour la programmation en assembleur, beaucoup de routines sont dj crites, des didacticiels trs complets et gratuits sont disponibles comme par exemple les cours de BIGONOFF dont le site est l'adresse suivante http://abcelectronique.com/bigonoff.
Les fonctions que nous demandons de raliser nos PIC sont de plus en plus complexes, les programmes pour les raliser demandent de plus en plus de mmoire. L'utilisateur est ainsi la recherche de langages "volus" pouvant simplifier la tche de programmation. Depuis l'ouverture du site http://electronique-facile.com, le nombre de questions sur la programmation des PIC en C est en constante augmentation. Il est vrai que rien n'est aujourd'hui disponible en franais.
Mon exprience dans le domaine de la programmation en C due en partie mon mtier d'enseignant, et ma passion pour les PIC, m'a naturellement amen l'criture de ce didacticiel. Celui-ci se veut accessible tous ceux qui possdent une petite exprience informatique et lectronique (utilisation de Windows, connaissances minimales sur les notions suivantes : la tension, le courant, les rsistances, les LEDs, les quartz, l'criture sous forme binaire et hexadcimale.). Ce cinquime fascicule vous permettra de programmer de faon plus structure grce aux fonctions. Vous pourrez enfin utiliser au mieux le PIC 16F84 grce aux interruptions.
Page 3/17
Structure de ce document
Ce document est compos de chapitres. Chaque chapitre dpend des prcdents. Si vous n'avez pas de notion de programmation, vous devez raliser chaque page pour progresser rapidement. Le type gras sert faire ressortir les termes importants. Vous trouverez la dfinition de chaque terme nouveau en bas de la page o apparat pour la premire fois ce terme. Le terme est alors en italique. La couleur bleue est utilise pour vous indiquer que ce texte est taper exactement sous cette forme. La couleur rouge indique des commandes informatiques utiliser.
Le matriel ncessaire
Les deux logiciels utiliss lors du premier fascicule. Un programmateur de PIC comprenant un logiciel et une carte de programmation. Vous trouverez tout ceci sur notre site. Un PIC 16F84, un quartz de 4MHz, deux condensateurs de 22pF, 4 leds rouges, 4 rsistances de 470 ohms, 4 interrupteurs, 4 rsistances de 10 Kohms. Une platine d'essai sous 5 volts.
La platine d'essai
Pour tester les programmes proposs, il est possible : -utiliser le simulateur comme prsent dans le premier manuel; -programmer un composant et tester physiquement la ralisation; -utiliser un mulateur. Nous utiliserons dans ce didacticiel le test physique. Il est ainsi ncessaire de raliser sur une platine de type LAB par exemple le montage ci-contre.
Page 4/17
Les fonctions
Gnralits
La plupart des langages de programmation nous permettent de subdiviser nos programmes en sous-programmes plus simples et plus compacts : les fonctions. A l'aide de ces structures nous pouvons modulariser nos programmes pour obtenir des solutions plus lgantes et plus efficaces. Une fonction peut en appeler une autre grce des instructions particulires. A la suite d'un appel, la fonction appelante s'arrte et la fonction appele se met en excution jusqu' ce qu'elle appelle une autre fonction ou se termine. Lors de la fin de son excution, la fonction appelante reprend son fonctionnement depuis son arrt. Une fonction peut envoyer les donnes la fonction qu'elle appelle au moment de son appel. Une fonction peut envoyer des donnes la fonction qui l'a appele au moment du retour. Une fonction appele doit toujours tre dfinie avant la fonction qui l'appelle. Elle est soit crite, soit dclare avant la fonction qui l'appelle. Il est possible d'imbriquer jusqu' 8 fonctions au maximum cause de la structure du PIC 16F84. Chaque fonction peut tre appele plusieurs fois si ncessaire. Lors du lancement du programme, la fonction "main" s'excute en premier. C'est pour cela que nous avons crit avant la premire instruction qu'excutera le PIC : "void main(void) {". Nous avons ainsi dclar la fonction main. Vous comprendrez l'utilit des "void" plus tard. Un programme en C aura donc la structure suivante: Fonction X { Instruction en C } Fonction Y { Instruction en C, appel de la fonction X si ncessaire} Dclaration de la fonction Z Fonction main { Instruction en C, appel des fonctions X, Y et Z si ncessaire} Fonction Z { Instruction en C, appel des fonctions X et Y si ncessaire} Les fonctions permettent : Meilleure lisibilit Diminution du risque d'erreurs Possibilit de tests slectifs. Dissimulation des mthodes Lors de l'utilisation d'une fonction il faut seulement connatre son effet, sans devoir s'occuper des dtails de sa ralisation. Rutilisation d'une fonction dj existante Il est facile d'utiliser des fonctions que l'on a crites soi-mme ou qui ont t dveloppes par d'autres personnes. Simplicit de l'entretien Pour la suite du didacticiel, nous ne parlerons que du C pour CC5X. Le fond restera valable pour tous les langages C, mais des diffrences peuvent exister d'un langage l'autre ( obligation de positionner les fonctions aprs main, types de donnes non compatibles ).
Page 5/17
Page 6/17
Explications de la ligne : if (inter1) { ++action; antirebond(); while (inter1); antirebond(); } A chaque fois que inter1 passe 1 on ralise : incrmentation de "action" car on a une fois de plus enclench le bouton poussoir. ralisation de "anti-rebond" pour attendre que le contact soit immobilis l'tat 1. attente que le bouton poussoir soit relch grce l'instruction while(inter1);. ralisation de anti-rebond pour attendre que le contact soit immobilis l'tat 0;. Si le programme comptabilise mal, augmenter la dure de l'anti-rebond.
Page 7/17
Page 8/17
Page 9/17
L'instruction if (++equipe1==5) fin(1); ralise les oprations suivantes: Incrmentation de equipe1. Comparaison de "equipe1" aprs incrmentation avec 5 pour raliser fin(1) en cas d'galit. Fin(1) claire la led1 afin de signaler que l'quipe 1 a gagn. La fonction affichage est identique celle du programme prcdent la diffrence qu'on lui fournit le nombre afficher. Nous remarquons que "equipe1", "equipe2", "equipe3", "equipe4" de type char sont tout fait compatibles avec quipe de type char aussi. Il est possible d'utiliser comme paramtre de fonction un nom de variable dj utilis. Le compilateur utilisera alors la dernire variable temporaire cre pour la fonction. Exemple : Nous allons utiliser la variable "equipe1" en tant que paramtre pour la procdure affiche. Voici les modifications a apporter.
//-------------------------------Dclaration de fonction------------------------void affichage(char equipe1);
//-------------------------------Fonction affichage------------------------------void affichage(char equipe1) { sortie=0; // affichage des points if (equipe1>0) led1=1; if (equipe1>1) led2=1; if (equipe1>2) led3=1; if (equipe1>3) led4=1; }
Il pourrait y avoir ambigut avec la variable globale appele aussi "equipe1". Pourtant le programme fonctionne de faon identique au programme initial. Il a donc bien utilis la variable temporaire dans la fonction et non pas la variable globale. Ceci permet par exemple de crer plusieurs fonctions, qui ralisent des calculs mathmatiques diffrents tout en utilisant des noms de paramtres identiques tels que "multiplicateur", "multiplicande", "resultat" Ayez, s'il vous plat, une pense mue pour l'auteur. Les trois dernires parties ont pris une trentaine d'heures pour tre rdiges. Si vous trouvez qu'elles ne sont pas assez claires, prenez des pincettes pour m'en informer, je peux devenir violent.
Page 10/17
Exemple de programme : un d lectronique Le bouton poussoir 1 permet d'afficher de faon alatoire une led. Nous allons alors crire une fonction qui fournira un nombre entre 1 et 4. Cette fonction sera appele chaque fois que le bouton poussoir1 sera enclench. // Attention de respecter les majuscules et minuscules //---------------------------------E/S et variable-------------------------------char sortie @ PORTB; bit inter1 @ RA0; bit led1 @ RB0; bit led2 @ RB1; bit led3 @ RB2; bit led4 @ RB3;
Page 11/17
La programmation des PIC en C Les fonctions, les interruptions char a; char resultat; // variable tampon // chiffre afficher
//---------------------------------Fonction hasard------------------------------char hasard(void) { do {a=a+1; if (a==5) a=1;} while (TMR0>0); return (a); } //-------------------------------Fonction principale-----------------------------void main(void) { sortie = 0; // Initialisation du microcontrleur TRISB = 0b11110000; OPTION = 0b11000111; // prdiviseur 256 entre : clock/4 for(;;) { if (inter1) { resultat=hasard(); sortie=0; if (resultat==1) led1=1; if (resultat==2) led2=1; if (resultat==3) led3=1; if (resultat==4) led4=1; } } } La fonction "hasard" ne ncessite aucun paramtre en entre, par contre elle fournit un chiffre entre 1 et 4. Pour obtenir ce chiffre, nous allons incrmenter une variable 'a' de 1 4 et recommencer jusqu' ce que le timer ait atteint la valeur 0. La fonction principale rcupre cette valeur dans "rsultat" afin d'afficher la bonne led.
Page 12/17
Les interruptions
Gnralits
Ca y est, nous y sommes, nous entamons la notion qui va changer votre vie de programmateur. Jusqu'ici, les fonctions taient appeles par le programme lui-mme. Une interruption est une fonction qui se ralise lorsque un vnement se produit, et non lorsque le programme le dcide. Les vnements conduisant une interruption dpendent du microcontrleur. Au moment de l'appel de l'interruption, le programme s'arrte. Le microcontrleur sauvegarde l'adresse de la dernire instruction excute ainsi que les registres importants. L'excution de l'interruption commence. A la fin de sa ralisation, les registres importants reprennent les tats qu'ils avaient avant l'appel, le programme reprend l'endroit o il s'tait arrt.
Le PIC 16F84
Chaque microcontrleur fonctionne diffremment lors d'une interruption. De plus, chaque langage C est diffrent face ces mmes interruptions. Nous allons donc assez rapidement analyser le comportement du PIC 16F84, et voir comment grer cette ressource avec le C que nous utilisons depuis le dbut. Le PIC 16F84 possde 4 sources d'interruption : Changement d'tat des pattes RB4 RB7; Dbordement du timer (passage de 0XFF 00); Front sur la patte INT (Cette patte est aussi la patte RB0). Le sens du front est dtermin par certains bits du registre option; Fin d'criture dans la EEprom du PIC (partie de la mmoire qui ne s'efface pas en cas de coupure d'alimentation). La gestion des interruptions passe par 3 oprations: dclaration du fichier utile la gestion des interruptions; configuration des interruptions; criture de l'interruption; La dclaration du fichier utile la gestion des interruptions est indispensable pour utiliser les instructions de sauvegarde des registres important au moment de l'interruption. Elle passe par l'criture de la ligne ci-dessous placer en dbut de fichier : #include "int16CXX.h" La configuration des 4 interruptions se fait l'aide de bits des registres INTCON (INTerrupt CONfiguration) et OPTION, le plus souvent au dbut de la fonction main. RBIE (RB Interrupt Enable) : mis 1, il autorise les interruptions dues au changement d'tat des pattes RB4 RB7. T0IE (Timer 0 Interrupt Enable) : mis 1, il autorise les interruptions dues au timer. INTE : (INTerrupt Enable) : mis 1, il autorise les interruptions dues un front sur la patte RB0/INT. INTEDG : (INTerrupt EDGe) : un 1 valide les fronts montants comme source d'interruption sur RB0/INT, un 0 valide les fronts descendants.
Page 13/17
La programmation des PIC en C Les fonctions, les interruptions EEIE (EEprom Interrupt Enable) : un 1 valide la fin d'criture dans la EEprom comme source d'interruption. GIE (General Interrupt Enable) : mis 1, il permet aux interruptions de s'excuter selon les bits prcdents. Au dbut de l'interruption, ce bit est mis 0 automatiquement. A la fin de l'interruption, ce bit est mis 1 automatiquement. Registre INTCON 7 6 GIE EEIE
Reset 0 0
5 T0IE
0
4 INTE
0
3 RBIE
0
L'criture de l'interruption est plus subtile qu'il n'y parat. Lors de la mise sous tension du microcontrleur, le programme excute en premier l'instruction l'adresse 0 du programme. Le compilateur place cette adresse l'instruction en assembleur "goto main". Ce qui signifie aller la fonction "main". Lorsqu'une interruption se produit, le microcontrleur sauvegarde son environnement et saute l'adresse 0X4 du programme. Il est donc indispensable d'crire l'interruption partir de cette adresse, puis d'crire les autres fonctions. Ainsi les adresses 0X1, 0X2, 0X3 restent vides. La structure prend la forme suivante : #pragma origin 4 interrupt nom_de_l'interruption(void) { int_save_registers Corps de l'interruption int_restore_registers } #progma origin 4 indique au compilateur d'crire partir de l'adresse 4. interrupt nom_de_l'interruption(void) indique que cette fonction est une interruption et lui donne un nom. int_save_register est une instruction qui sauvegarde l'tat des registres importants. int_restore_registers est une instruction qui restitue l'tat des registres importants. Le corps de l'interruption passe en premier par la dtection de la source d'interruption. Pour cela, nous utiliserons certains bits du registre INTCON comme suit : RBIF (RB Interrupt Flag ) : mis 1 par le systme, ce bit indique un changement d'tat des pattes RB4 RB7. Ce bit doit tre remis 0 manuellement avant la fin de l'interruption. TOIF (Timer 0 Interrupt Flag ) : mis 1 par le systme, ce bit indique un dbordement du timer. Ce bit doit tre remis 0 manuellement avant la fin de l'interruption. INTF (INTerrupt Flag ) : mis 1 par le systme, ce bit indique l'arrive d'un front sur la patte RB0/INT. Ce bit doit tre remis 0 manuellement avant la fin de l'interruption. Registre INTCON 7 6
Reset
2 T0IF
0
1 INTF
0
0 RBIF
U U = Unknown
Page 14/17
Exemples
Notre premier exemple sera trs original puisque nous allons faire clignoter la led1 et mettre en fonction la led 4 si le bouton poussoir 4 est enclench. // Attention de respecter les majuscules et minuscules #include "int16CXX.h" //---------------------------------E/S et variable-------------------------------char sortie @ PORTB; bit inter4 @ RB5; bit led1 @ RB0; bit led4 @ RB3; char temps; //variable de gestion du temps gale 15 au bout d'une seconde //--------------------------------Interruption------------------------------------#pragma origin 4 interrupt timer_et_RB5(void) { int_save_registers if (T0IF) { ++temps; if (temps == 15) { led1=!led1; temps = 0; } T0IF = 0;} if (RBIF) { led4=inter4; RBIF = 0;} int_restore_registers }
// changement de inter4
//-------------------------------Fonction principale-----------------------------void main(void) { sortie = 0; // Initialisation du microcontrleur TRISB = 0b11110000; TMR0 = 0; INTCON = 0b10101000; // autorisation des interruptions par le timer et RB4 RB7 OPTION = 0b11000111; // prdiviseur 256 entre : clock/4 for(;;) { nop(); }} La deuxime ligne du fichier inclue le fichier servant aux interruptions. La premire fonction est prcde d'une commande ordonnant au compilateur d'crire partir de l'adresse 0X4, qui est l'adresse de saut en cas d'interruption. La premire fonction est donc l'interruption. Lors d'une interruption, il est ncessaire de sauvegarder les registres importants, tester la source d'interruption, ragir face cette source, l'autoriser nouveau, restaurer les registres importants. Au dbut du programme principal, le registre INTCON est positionn tel qu'il puisse y avoir une interruption du timer ou de RB4, c'est dire de inter4.
Page 15/17
La programmation des PIC en C Les fonctions, les interruptions Nous allons maintenant programmer une serrure code. Le code se compose grce aux 3 boutons poussoirs 1, 2 et 3 afin de verrouiller la porte. Le code est 1322. Le bouton poussoir 4 permet d'ouvrir la porte lorsqu'elle n'est pas verrouille. La LED 4 s'allume alors pendant que le bouton poussoir est enclench. La LED1 clignote lorsque la porte n'est pas verrouille, reste rouge lorsque la porte est verrouille. Nous voyons clairement que pendant que l'on utilise les boutons poussoirs 1, 2 et 3, des oprations se produisent : gestion de la porte, gestion de la LED4. Nous allons grer ces actions par interruption. Cette gestion ressemble de plus trangement au programme prcdent. Nous allons utiliser aussi une fonction anti-rebond pour viter les rebonds des interrupteurs et une fonction attente qui vrifiera qu'aprs appui sur un bouton poussoir, celui-ci est bien relch, et qui attendra qu'un nouveau bouton poussoir soit enclench. // Attention de respecter les majuscules et minuscules #include "int16CXX.h" //---------------------------------E/S-----------------------------------------char sortie @ PORTB; bit inter1 @ RA0; bit inter2 @ RA1; bit inter3 @ RA4; bit inter4 @ RB5; bit led1 @ RB0; bit led4 @ RB3; //-----------------------------Variables globales-------------------------------bit ver; //etat de la porte 0=verrouill 1=non verrouill unsigned tempo :16; //tempo pour l'anti-rebond char temps; //variable de gestion du temps gale 15 au bout d'une seconde char a; //variable tampon si ncessaire //--------------------------------Interruption------------------------------------#pragma origin 4 interrupt timer_et_RB5(void) { int_save_registers if (T0IF) {++temps; if (temps == 15) { if (!ver)led1=!led1; else led1=1; temps = 0; } T0IF = 0;} if (RBIF) {if (!ver) led4=inter4; porte else led4 = 0; RBIF = 0;} int_restore_registers }
// interruption timer, 65ms coules // si 1 seconde coule // clignotement de led1 si non verrouillage //sinon led1 est allume
//-------------------------------Fonction anti-rebond------------------------------void antirebond(void) { for (tempo=0;tempo<5000;tempo++); } // anti-rebond de 50ms //-------------------------------Fonction attente-----------------------------------void attente(void)
Page 16/17
La programmation des PIC en C Les fonctions, les interruptions { // attente que les 3 inters soient relchs puis un enclenche antirebond(); a=0; do {a.0=inter1; a.1=inter2; a.2=inter3;} while (a!=0); //attente que tout soit relch antirebond(); do {a.0=inter1; a.1=inter2; a.2=inter3;} while (a==0); //attente qu'un inter soit enclench antirebond();}
//-------------------------------Fonction principale-----------------------------void main(void) { sortie = 0; // Initialisation du microcontrleur ver = 0; TRISB = 0b11110000; TMR0 = 0; INTCON = 0b10101000; // autorisation des interruptions par le timer et RB4 RB7 OPTION = 0b11000111; // prdiviseur 256 entre : clock/4 for(;;) { // Recherche du code avec des if imbriqus if (inter1){ attente(); if (inter3) { attente(); if (inter2) { attente(); if (inter2) {ver= !ver;}}}} }}
Nous en resterons l pour les interruptions. Le prochain didacticiel vous permettra de comprendre parfaitement la notion de variables globale, locale, de constante. Vous pourrez aussi mettre en fonction vos quations les plus farfelues.
Page 17/17