Vous êtes sur la page 1sur 3

C O U R S

D E

P R O G R A M M A T I O N

CHAPITRE VII

La pr programmation ogrammation des PIC16F876


de la th thorie la pratique
Nous arrivons la fin de ce cours sur la programmation des microcontrleurs de la famille Microchip PIC16F87X. Nous vous prsentons, dans ce numro, un listing crit en C, qui ne devrait pas poser trop de problmes de comprhension et devrait montrer comment, avec quelques lignes de programmes, on obtient des rsultats difficilement imaginables en assembleur.

e programme pilote lafficheur 7 segments et gre les deux poussoirs de la carte de test. Lorsquon appuie sur le bouton-poussoir 1, le chiffre visualis sincrmente de 0 jusqu 9 et, bien entendu, le poussoir 2 ralise le contraire. Si lon appuie en mme temps sur les deux poussoirs, le chiffre visualis clignote 10 fois. Si lon appuie longuement sur un poussoir, le chif fre commence sincrmenter ou se dcrmenter trs rapidement. Le software est donc en mesure de rivaliser avec ce qui se passe avec la fonction de rptition automatique typique du clavier dun PC ou, si vous voulez, le compor tement des petites touches up et down presque toujours prsentes sur les horloges digitales. Il est certainement intressant de noter que raliser un circuit avec ce caractre fonctionnel, mais sans avoir recours un microcontrleur, serait une chose extrmement complexe (rseau RC, FLIP-FLOP, etc.). Il est galement impor-

tant de souligner que, si nous avions eu recours lassembleur pour la rdaction de ce programme, nous aurions eu beaucoup de difficults dans la phase dcriture et de debuggage et, en plus, nous aurions t contraints dcrire des dizaines et des dizaines de lignes de code. Notre programme quivaut un compteur qui, en utilisant lafficheur 7 segments et les 2 boutons-poussoirs prsents sur la carte de test, peut incrmenter de 0 9 et bien sr, dcrmenter de 9 0. En outre nous avons prvu que la pression simultane des 2 touches fera clignoter 10 fois le chiffre affich. La chose na aucune utilit mais sert dmontrer comment on peut raliser plusieurs fonctions avec seulement deux poussoirs (dans ce cas : up, down et clignotement). Le listing que nous allons maintenant dtailler contient certainement des mots clefs familiers ceux qui ont un minimum de connaissance en langage C. Il sagit des diffrentes instructions (if, else, switch) de la fonction main().

ELECTRONIQUE

76

magazine - n 24

Vous pourrez galement noter des instructions du type output_por t_c, disable_interrupt. Ces instructions sortent, si lon peut dire, du C standard mais sont videmment ncessaires pour la gestion du PIC. Pour la comprhension de ce listing, nous introduisons les instructions :

output_port_x(var1) var2=input_port_x() La premire ser t crire <var1> sur le por t x et cest lquivalent C de linstruction assembleur MOVWF PORTx (dans le cas o var1 aurait t prcdemment mmoris dans le registre W).

La deuxime, quant elle, lit la valeur du por t x et la mmorise dans la variable var2. Var1 et var2 sont de type char. Mais on peut utiliser galement des variables de type int (qui sont 16 bits et qui seront automatiquement coupes 8).

www.electronique-magazine.com TASTI.C Programme permettant la rptition automatique de la dernire touche appuye. #pragma CLOCK_FREQ 4000000 asm __CONFIG 03D31H #define premire_attente 90 #define seconde_attente10 main() { int retard; int valeur; int compteur; int appui_haut; int appui_bas; int attente_haut; int attente_bas; int i; int valeur_actuelle; appui_haut=0; appui_bas=0; attente_haut=premire_attente; attente_bas=premire_attente; disable_interrupt(GIE); retard=10; valeur=0; compteur=0; set_bit(STATUS,RP0); set_tris_c(0); set_tris_a(16+32); /* da RA0 a RA5: porte I/O */ asm movlw 07H asm movwf ADCON1 clear_bit(STATUS,RP0); for(;;) { switch(compteur) { case 0: output_port_c(32+16+8+2+4+128); break; case 1: output_port_c(16+8); break; case 2: output_port_c(32+16+64+4+2); break; case 3: output_port_c(32+16+64+8+2); break; case 4: output_port_c(128+16+64+8); break; case 5: output_port_c(32+128+64+8+2); break; case 6: output_port_c(128+4+2+8+64); break;

case 7: output_port_c(32+16+8); break; case 8: output_port_c(32+16+8+2+4+128+64); break; case 9: output_port_c(32+16+8+128+64); break; } delay_ms(retard); if((input_port_a()&48)==0) { valeur_actuelle=input_port_c(); for(i=0;i<10;i++) { output_port_c(0); delay_ms(500); output_port_c(valeur_actuelle); delay_ms(500); } } if((input_port_a()&32)==0) { if(appui_haut==0) { if(compteur<9) compteur++; } appui_haut++; if(appui_haut==attente_haut) { appui_haut=0; if(attente_haut==premire_attente) attente_haut=seconde_attente; } } else { if((input_port_a()&16)==0) { if(appui_bas==0) { if(compteur>0) compteur; } appui_bas++; if(appui_bas==attente_bas) { appui_bas=0; if(attente_bas==premire_attente) attente_bas=seconde_attente; } } else { appui_haut=0; appui_bas=0; attente_haut=premire_attente; attente_bas=premire_attente; } } } }

ELECTRONIQUE

77

magazine - n 24

La srie dinstructions suivantes, entrecoupes dattributions normales de variables, sont des commandes dinitialisation (plus proches de lassembleur que du C) caractristiques du microcontrleur PIC : pragma CLOCK_FREQ 4000000 asm_CONFIG 03D31H disable_interrupt(GIE) ; set_bit(STATUS,RP0) ; set_tris_c(0); set_tris_a(16+32) ; asm movlw 07H asm movwf ADCON1 clear_bit(STATUS,RP0) ; Grce ces informations, nous sommes en mesure danalyser le fonctionnement du programme : Linstruction for(;;) permet un cycle infini, que nous dfinissons comme tant le cycle principal. En effet ce programme ne se termine jamais. Voici ce qui se passe lintrieur du cycle : 1) Lafficheur est mis jour, en visualisant le contenu de la variable compteur qui peut, videmment, prendre les valeurs de 0 9. Grce linstruction switch(compteur) nous allumons de faon opportune les 7 segments de lafficheur, qui sont relis au port C du PIC. 2) Puis vient une temporisation de 10 ms (voir linstruction delay_ms(retard)). delay_ms est une autre des instructions caractristiques du PIC. retard est une variable de type char. Dans notre programme, il ny a aucune raison dutiliser une telle variable vu que retard est mis 10 au dbut du programme et nest plus modifi. Cependant, elle sert vous montrer comment, en une (vous avez bien lu une) ligne du programme, on peut introduire un retard variable, chose qui demandait plusieurs lignes de code en assembleur. 3) Vrifions que les deux poussoirs sont presss grce linstruction if((input_port_a()&48)==0). Nous vous rappelons que, dans notre car te de test, les poussoirs sont relis aux bits 4 et 5 du port A et que, lorsquils sont presss, lentre respective est mise masse. Le symbole &, en C, indique un AND logique. Donc, linstruction vrifie que les bits 4 (24 = 16) et 5 (25 = 32) sont tous les deux 0.

Maintenant, 16 + 32 = 48 et ceci explique le nombre qui apparat dans le programme. Au cas o la condition se vrifierait, le cycle for qui suit provoquerait le clignotement du chiffre. Linstruction delay_ms permet que notre chif fre reste allum pendant 500 ms puis teint pendant la mme dure (et ainsi de suite 10 fois). 4) Contrlons maintenant que seul le poussoir haut (up) est press grce if((input_por t_a()&32)==0). Nous vous rappelons que le poussoir haut est celui qui est reli au bit 5 du port A. Introduisons maintenant la variable appui_haut ==attente_haut et les constantes premire_attente et seconde_ attente. Nous avons choisi des noms assez significatifs : premire_attente et seconde_ attente reprsentent le temps (ou mieux, le nombre de cycles du programme entier) qui doit scouler depuis que le poussoir a t press jusquau moment o lon incrmente le chiffre. Nous avons dfini 2 constantes car il peut se produire 2 situations : le poussoir est press pour la premire fois ou bien le poussoir a dj t press. Dans le premier cas, nous attendrons un nombre de cycles gal premire_attente (qui, dans le programme, a t dfinie comme gale 90). Dans le second cas, le nombre sera gal seconde_attente (dfinie comme gale 10). La variable appui_haut est le compteur du temps dont nous avons parl. A chaque cycle, si le poussoir est press, cette variable est incrmente. Observez, en effet, linstruction appui_ haut++ qui sert incrmenter dune unit sa valeur. Cest alors quentre en jeu la variable attente_haut, dfinie, initialement, comme gale premire_attente. Le test if(appui_haut==attente_haut) vrifie que la dure dsire se soit coule et, dans ce cas, appui_haut est dfini gal 0. Cest linformation qui permet de savoir que le chif fre visualis doit sincrmenter. Ceci ne se produit pas dans le cycle en cours mais dans le suivant. En effet les instructions prvues dans ce but sont : if(appui_haut==0) { if(compteur<9) compteur++; }

En outre, grce elles, on vite que le compteur ne sarrte 9. Il serait du reste impossible de visualiser des chiffres suprieurs sur notre afficheur. Revenons maintenant lanalyse du test if(appui_haut= = attente_haut). Lorsque celui-ci donne un rsultat positif, la valeur de attente_haut est vrifie. Regardez attentivement les instructions suivantes : if(attente_haut==premire_attente) attente_haut=seconde_attente; Celles-ci indiquent que, si le temps fix par premire_attente sest dj coul, alors le poussoir a dj t press et, donc, nous pouvons passer seconde_attente, infrieure, comme nous lavons dit, la valeur de premire_attente. Concrtement, cela veut dire quen maintenant le poussoir appuy, il se passera moins de temps entre une incrmentation et la suivante du chiffre sur lafficheur. Nous avons donc ralis le caractre fonctionnel que nous nous tions fix en dbut darticle. 5) Tout le discours fait au point prcdent vaut galement pour le poussoir bas. Sa gestion commence avec la ligne if(input_por t_ a()&16)==0). Nous ne nous rpterons pas : lalgorithme est le mme. Nous avons videmment chang le nom des deux variables qui sont maintenant appui_bas et attente_bas. premire_ attente et seconde_attente sont videmment les mmes, vu que ces temps devront tre gaux pour les deux poussoirs. 6) Enfin (voir la dernire instruction else) au cas o aucun des deux poussoirs naurait t press, nous mettrions 0 les deux compteurs et dfinirions les attentes comme gales premire_attente. Cest tout ! Nous pensons vous avoir dmontr que raliser un tel programme en assembleur serait trs compliqu alors quen utilisant le C, quelques lignes de code, simples et faciles lire, suffisent. Si vous le voulez, vous pouvez, par curiosit, raliser le mme programme en assembleur ou en Basic et les comparer. Ce serait, de toute faon, un excellent exercice. N D. M.

ELECTRONIQUE

78

magazine - n 24

Vous aimerez peut-être aussi