Vous êtes sur la page 1sur 40

Programmation en mikroC.

Application pour les microcontrleurs de la famille PIC

CHAPITRE I

Mr Nizar TOUJENI

1/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

I. LANGAGE ET COMPILATEUR mikroC POUR PIC


Le langage mikroC pour PIC a trouv une large application pour le dveloppement de systmes embarqus sur la base de microcontrleur. Il assure une combinaison de l'environnement de programmation avance IDE (Integrated Development Environment), et dun vaste ensemble de bibliothques pour le matriel, de la documentation complte et dun grand nombre des exemples. Le compilateur mikroC pour PIC bnficie d'une prise en main trs intuitive et d'une ergonomie sans faille. Ses trs nombreux outils intgrs (mode simulateur, terminal de communication Ethernet, terminal de communication USB, gestionnaire pour afficheurs 7 segments, analyseur statistique, correcteur d'erreur, explorateur de code, mode Dbug ICD...) associ sa capacit pouvoir grer la plupart des priphriques rencontrs dans l'industrie (Bus I2C, 1Wire, SPI, RS485, Bus CAN, USB, gestion de cartes compact Flash et SD/MMC, gnration de signaux PWM, afficheurs LCD alphanumriques et graphiques, afficheurs LEDs 7 segments, etc.) en font un outil de dveloppement incontournable pour les systmes embarqus, sans aucun compromis entre la performance et la facilit de dbogage.

1.1 Compilateur mikroC PRO pour PIC


La nouvelle version appele mikroC PRO dispose de trs nombreuses amliorations du compilateur mikroC : nouvelles variables utilisables, nouvelle interface IDE, amlioration des performances du linker et de l'optimisateur, cycle de compilation plus rapide, code machine gnr plus compact (jusqu' 40 % suivant les cas), nouveaux PIC supports, environnement de dveloppement encore plus ergonomique, nouveaux exemples d'applications, etc. 1. Dans la suite nous utiliserons le compilateur mikroC PRO v.1.65 2. La simulation des applications de programmation nous ralisons PROTEUS v.7.10 SP laide du logiciel

Mr Nizar TOUJENI

2/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

CHAPITRE II

Mr Nizar TOUJENI

3/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

II. INTRODUCTION AU LANGAGE DE PROGRAMMATION MICROC


2.1 Structure d'un programme en mikroC
La structure la plus simple d'un programme en mikroC, cest le programme reprsent dans le code-source 2.1, qui nous permettra de faire clignoter une LED connecte au PORTB (par exemple bit 0 du PORTB) du microcontrleur PIC avec une priode de 2 secondes (1 seconde allume et une seconde teinte). 2.1.1 Rgles gnrale dcriture en mikroC Les instructions propres au langage mikroC doivent tre crites en minuscule (void main (void)). Les instructions particulires aux microcontrleurs doivent tre crites en majuscule (TRISB). Les retours la ligne et les espaces servent uniquement arer le code Toutes instructions ou actions se terminent par un point virgule ; .

Code-source 2.1
/*******************************************************************************

LED clignotante ============== Ce programme fait clignoter dune LED connecte au PORTB (broche RB0) avec un des intervalles d'une seconde. Microcontrleur : 16F84A Oscillateur : HS, 4.0000 Mhz Fichier : LED.c Date : Avril 2014

*******************************************************************************/ void main( ) { for( ; ; ) // Boucle sans fin { TRISB = 0; // Configuration du PORTB en sortie PORTB.0 = 0; // RB0 = 0 Delay_Ms(1000); // Pause dune seconde PORTB.F0 = 1; // RB0 = 1 Delay_Ms(1000); // Pause dune seconde } // Fin de la boucle }

Examinons le fichier LED.c du code-source

Mr Nizar TOUJENI

4/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC 2.1.2 Commentaires Les commentaires sont utiliss pour prciser le fonctionnement du programme et pour une annotation du programme. Les lignes de commentaires sont ignores et non compil par le compilateur. En mikroC les commentaires de programmes peuvent tre de deux types: de longs commentaires, stendant sur plusieurs lignes, et de courts commentaires, occupant une seule ligne. Un commentaire au dbut d'un programme peut dcrire brivement le fonctionnement du programme et de fournir le nom de l'auteur, le nom du fichier programme, la date laquelle le programme a t crit, et une liste des numros de version, ainsi que les modifications dans chaque version. Comme montre le Code-source 2.1 les longs commentaires commencent par le caractre /* et se termine par le caractre */ . De mme, de courts commentaires commencent par le caractre // et il na pas besoin d'un caractre de terminaison. 2.1.3 Dbut et fin d'un programme En langage mikroC, un programme commence avec les mots-cls: void main() Aprs cela, une accolade ouvrante est utilise pour indiquer le dbut du corps de programme. Le programme se termine par une accolade fermante. Ainsi, comme indiqu dans le Code-source 2.1, le programme a la structure suivante : void main() {

// Votre code ici


} 2.1.4 Fin dune instruction Le point virgule ; indique la fin dune instruction, sinon une erreur du compilateur sera gnre. 2.1.5 Espaces blancs Les espaces blancs sont des espaces, les tabulations et les caractres de nouvelle ligne. Le compilateur mikroC ne tient pas compte tous les espaces blancs.

Mr Nizar TOUJENI

5/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

2.2 Elments de programmation en mikroC


2.2.1 Les variables. Dfinition et dclaration de variables Une variable est une portion rserve dune mmoire laquelle on a donn un nom. On peut stocker ou lire les informations de ces variables. Toute variable utilise dans un programme doit auparavant tre dfinie. La dfinition dune variable consiste la nommer et lui donne un type et ventuellement lui donner une valeur initiale (initialiser). Cest cette dfinition qui rserve (alloue) la place mmoire ncessaire en fonction du type. Lorsque le programme que lon ralise est dcompos en plusieurs modules, une mme variable, utilise dans plusieurs modules, doit tre dclare dans chacun de ces modules. Par contre, on ne dfinira cette variable que dans un seul de ces modules. Cest au moment de ldition des liens que lon mettra en correspondance les variables apparaissant dans plusieurs modulez (variable partage, mot-cl extern). La position de la dclaration ou de la dfinition dune variable dtermine sa porte cest--dire sa dure de vie et sa visibilit. Les variables globales sont dclares en dehors de toute fonction. Les variables locales sont dclares lintrieur des fonctions et ne sont pas visible lextrieur de la fonction dans laquelle celle-ci est dfinie. Les noms des variables ne peuvent contenir que des lettres de a z et partir de A Z, le trait de soulignement "_" et les chiffres de 0 9. Les noms des variables dans mikroC n'est pas sensible la casse, de sorte que Som, som et soM reprsente le mme identifiant. Certains noms sont rservs pour le compilateur lui-mme et ne peut pas tre utiliss comme noms de variables dans un programme. Le tableau 2.1 donne une liste alphabtique de ces noms rservs. Tableau 2.1 Noms rservs en mikroC asm break char goto double else enum float switch int return short signed static const union volatile while auto case if long do extern for typedef default register sizeof struct continue unsigned void

Mr Nizar TOUJENI

6/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC 2.2.2 Constantes Les constantes reprsentent des valeurs fixes (numrique ou caractre) dans des programmes qui ne peuvent pas tre changes. En mikroC, les constantes peuvent tre entiers, flottants, caractres, chanes ou des types numrs. Integer Constants Les constantes entires (Integer Constants) peuvent tre en dcimal, hexadcimal, octal ou binaire. Le suffixe u ou U force la constante d'tre non sign (unsigned) et le suffixe l ou L force la constante d'tre longue (long). Utilisation de U (ou u) et L (ou l) oblige la constante d'tre unsigned long. Les constantes sont dclares en utilisant le mot-cl const et sont stockes dans le flash de mmoire du microcontrleur PIC. Par exemple, MAX est dclar comme la constante 100 : const MAX =100; Les constantes hexadcimales commencent par les caractres 0x ou 0X et peuvent contenir des donnes numriques de 0 9 et les caractres hexadcimaux de A F. Dans l'exemple suivant, TOTAL est la constante de la valeur hexadcimale FF: const TOTAL = 0xFF; Les constantes octales ont un zro au dbut du nombre et peuvent contenir des donnes numriques de 0 7. Dans l'exemple suivant, une constante CNT est affecte une valeur octale 17 : const CNT = 017; Les constantes binaires commencent par 0b ou 0B et ne peuvent contenir que 0 ou 1. Par exemple une constante nomme Min est dclare comme ayant la valeur binaire 11110000: const Min = 0b11110000 Floating Point Constants Les constantes virgule flottante (Floating Point Constants) se compose de: Entier dcimal Point dcimal Partie dcimale fractionnaire e ou E et l'ordre du signe

Dans l'exemple suivant, une constante nomme TEMP est dclare comme ayant la valeur fractionnelle 37.50 : const TEMP = 37.50 Mr Nizar TOUJENI 7/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC ou const TEMP = 3.750E1 Character Constants Une constante de caractre (Character Constants) est un caractre renferm dans des guillemets simples. Par exemple, une constante nomme First_Alpha est dclare comme ayant la valeur du caractre A: const First_Alpha = A; String Constants Les constantes de chane (String Constants) sont des squences fixes de caractres stockes dans la mmoire flash du microcontrleur. La chane doit commencer et se terminer par un guillemet " . Un exemple dune constante de type chane est la suivante : "Il s'agit d'un exemple de chaine constante" Une constante chane peut tre tendue travers une frontire en ligne en utilisant une barre oblique inverse "\" : "C'est la premiere partie de la chaine \ et c'est la poursuite de la chaine " Cette dclaration de la constante chane est la mme que : "C'est la premiere partie de la chaine et c'est la poursuite de la chaine " Enumerated Constants Les constantes numres (Enumerated Constants) sont de type entier et sont utilises pour faire un programme plus facile suivre. Dans l'exemple suivant, une constante nomme couleur stocke les noms de couleurs. Le premier lment de couleur a la valeur 0: enum couleur {noir, marron, rouge, orange, jaune, vert, bleu, gris, white}; 2.2.3 Squences d'chappement Les squences d'chappement (Escape Sequences) sont utilises pour reprsenter les caractres ASCII non imprimables. Par exemple, la combinaison de caractres \n reprsente le caractre de nouvelle ligne.

Mr Nizar TOUJENI

8/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC 2.2.4 Variables statiques
Les variables statiques (Static variables ) sont des variables locales utilises dans les fonctions lorsque la dernire valeur d'une variable entre les appels successifs de la fonction doit tre prserve. Comme le montre l'exemple suivant, les variables statiques sont dclares en utilisant le mot cl static : statique unsigned int count ;

2.2.5 Variables externes


Utilisation du mot (extern) devant un nom de variable dclare cette variable comme externe. Il indique au compilateur que la variable est dclare ailleurs dans un code-source distincte module. Dans l'exemple suivant, les variables sum1 et SUM2 sont dclars comme externes entiers non signs : extern int sum1, SUM2 ;

2.2.6 Variables volatiles


Les variables volatiles (Volatile Variables ) sont importantes dans d'interruption des programmes et de routines dentres-sorties. Utilisation de mot-cl volatile indique que la valeur de la variable peut changer au cours de la dure de vie du programme indpendant de l'coulement normal du programme. Dans l'exemple suivant, la variable Led est dclare comme un volatile non sign : volatile unsigned char Led;

2.2.7 Variables numres


Les variables numres sont utilises pour rendre un programme plus lisible. Dans une variable numre, une liste de rfrences est spcifie et la valeur du premier lment est fix 0, l'autre lment est mis 1, et ainsi de suite. Dans l'exemple suivant, la Semaine de type est dclar comme un liste numre et LUN = 0, MAR = 1, WEN = 2, et ainsi de suite : enum Semaine {LUN, MAR, MER, JEU, VEN, SAM, DIM}; Il est possible d'impliquer les valeurs des lments dans une liste numre. Dans le exemple suivant, noir = 2, bleu = 3, rouge = 4, et ainsi de suite. enum couleurs {noir = 2, bleu, rouge, blanc, gris}; De mme, dans l'exemple suivant, noir = 2, bleu = 3, rouge = 8, et gris = 9: enum couleurs {black = 2, bleu, rouge = 8, gris}; Les variables de type de recensement peuvent tre dclares par les spcifiant aprs la liste des articles. Par exemple, pour dclarer la variable My_Week de la Semaine de type numr, utilisez la dclaration suivante: enum Semaine {LUN, MAR, MER, JEU, VEN, SAM, DIM} My_Week; Maintenant, nous pouvons utiliser My_Week comme une variable dans un programme: My_Week = MER // assigne 2 a My_Week ou My_Week = 2 // le meme que ci-dessus Aprs avoir dfini Semaine comme un type numr, nous pouvons dclarer des variables This_Week et Next_Week de type Semaine : enum Semaine This_Week, Next_Week;

2.2.8 Tableaux
Les tableaux (Arrays) sont utiliss pour stocker des lments lis dans le mme bloc de mmoire et en vertu d'un nom spcifi. Un tableau est dclar en spcifiant son type, le nom, et le nombre dlments stocker. Par exemple: unsigned int Total [5] ;

Mr Nizar TOUJENI

9/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC


Ce tableau de type unsigned int est nomm Total et dispose de cinq lments. Le premier lment d'un tableau est index 0. Ainsi, dans cet exemple, Total[0] se rfre au premier lment du tableau et Total[4] se rfre au dernier lment. Le tableau Total est stock dans un mmoire ayant cinq emplacements conscutifs comme suit: Total[0] Total[1] Total[2] Total[3] Total[4] Les donnes peuvent tre stockes dans le tableau en spcifiant le nom du tableau et de l'indice. Par exemple, pour stocker 25 dans le deuxime lment du tableau, nous devons crire: Total[1] = 25; De mme, le contenu d'un tableau peut tre lu en spcifiant le nom du tableau et de son index. Par exemple, pour copier l'lment de tableau dindex 2 une variable appele Temp , nous devons crire: Temp = Total[2]; Le contenu d'un tableau peut tre initialis lors de la dclaration du tableau en attribuant d'une squence de valeurs spares par des virgules dans le tableau. Voici un exemple dun tableau ayant 12 lments des mois[0] = 31, mois[1] = 28, et ainsi de suite: unsigned char mois[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; www.newnespress. Le mme tableau peut galement tre dclar sans spcifier sa taille: unsigned char mois[ ] = {31,28,31,30,31,30,31,31,30,31,30,31}; Des tableaux de caractres peuvent tre dclars de manire similaire. Dans l'exemple suivant, un tableau de caractres nomms Hex_Letters est dclare avec 6 lments: unsigned char Hex_Letters[ ] ={A, B, C, D, E, F}; Les chanes sont des tableaux de caractres avec un terminateur null. Les chanes peuvent tre dclares soit par enfermant la chane entre guillemets, ou en spcifiant chaque caractre du tableau au sein de apostrophes et puis en terminant la chane avec un caractre nul. La chane de deux dclarations dans l'exemple suivant est identique :
unsigned char Mystring[ ] = COMP;

et unsigned char Mystring[ ] = {C, O, M, P, \0};

Dans le langage de programmation microC, nous pouvons aussi dclarer des tableaux aux dimensions multiples. Tableaux unidimensionnels sont gnralement appels vecteurs, et des tableaux bidimensionnels sont appels matrices. Un rseau bidimensionnel est dclar en spcifiant le type de donnes de la matrice, le nom de tableau, et la taille de chaque dimension. Dans l'exemple suivant, un tableau deux dimensions nomm P contiens trois lignes et quatre colonnes. Au total, le tableau a douze lments. Le premier lment de la matrice est P[0][0], et le dernier lment est P[2][3]. La structure de ce tableau est montre ci-dessous: P[0][0] P[0][1] P[0][2] P[0][3] P[1][0] P[1][1] P[1][2] P[1][3]

Mr Nizar TOUJENI

10/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC


P[2][0] P[2][1] P[2][2] P[2][3] lments d'un tableau multidimensionnel peut tre spcifi lors de la dclaration du tableau. Dans l'exemple suivant, rseau bidimensionnel Q a deux ranges et deux colonnes, ses lments diagonaux sont mis 1, et de ses lments non diagonaux sont remis 0:
unsigned char Q[2][2] = { {1,0}, {0,1} };

2.2.9 Pointeurs
Les pointeurs (Pointers) sont une partie importante du langage microC, car ils occupent les adresses mmoire des autres variables. Les pointeurs sont dclares de la mme manire que d'autres variables, mais avec le caractre * en face du nom de variable. Dans l'exemple suivant, un pointeur de caractre non sign du nom pnt est dclar: unsigned char *pnt; Quand un nouveau pointeur est cr, son contenu est d'abord indtermin et il ne tient pas l'adresse d'une variable. Nous pouvons attribuer l'adresse d'une variable un pointeur l'aide le & : pnt = &Count; Maintenant pnt affecte l'adresse de variable Count. La variable Count peut tre affecte une valeur en utilisant le caractre * en avant de son pointeur. Par exemple, le Count peut tre attribue 10 l'aide de son pointeur : * pnt = 10; // Count = 10 cest la mme chose que Count = 10; // Count = 10 ou, la valeur du Count peut tre copi la variable Cnt en utilisant son pointeur : Cnt = *pnt; // Cnt = Count Pointeurs de tableaux Dans le langage microC, le nom d'un tableau est aussi un pointeur de tableau. Ainsi, pour le tableau : unsigned int Total[10]; Le nom Total est galement un pointeur de ce tableau, et il contient l'adresse du premier ellment de la matrice. Ainsi, les deux noncs suivants sont gaux: Total[2] = 0; et *(Total + 2) = 0; En outre, l'nonc suivant est vrai: &Total[j] = Total + j ; En langage microC, nous pouvons effectuer des oprations arithmtiques pour pointeurs qui peuvent impliquer : Comparaison de deux pointeurs Addition ou la soustraction d'un pointeur et un entier La soustraction de deux pointeurs Assigner un pointeur vers un autre En comparant un pointeur avec zro Par exemple, supposons que le pointeur P est affect afin de contenir l'adresse du tableau dlment Z[2]:

Mr Nizar TOUJENI

11/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC


P = &Z[2];

Nous pouvons maintenant effacer les lments 2 et 3 du tableau Z, comme dans les deux exemples qui suivent. Les deux exemples sont identiques, sauf que dans le premier exemple pointeur P contient l'adresse de Z[3] la fin des tats, et il contient l'adresse de Z[2] la fin de deuxime srie de dclarations: *P = 0; // Z[2] = 0 P = P + 1; // maintenant P pointe lelement 3 de Z *P = 0; // Z[3] = 0 Ou *P = 0; // Z[2] = 0 *(P +1) = 0; // Z[3] = 0 Un pointeur peut tre affect un autre pointeur. Dans l'exemple suivant, les variables Cnt et Tot sont lensable de 10 lments crs l'aide de deux pointeurs diffrents: unsigned int *i, *j; // declare 2 pointeurs unsigned int Cnt, Tot; // declare deux variables i = &Cnt; // i pointe vers Cnt *i = 10; // Cnt = 10 j = i; // copy pointeur i vers pointeur j Tot = *j; // Tot = 10

2.2.10 Structures
Une structure peut tre utilise pour recueillir des lments connexes, qui sont ensuite traits comme un seul objet. Contrairement un tableau, une structure peut contenir un mlange de types de donnes. Par exemple, un structure permet de stocker les donnes personnelles (nom, prnom, ge, date de naissance, etc) d'un tudiant. Une structure est cre en utilisant le mot-cl struct, suivie d'une structure de nom et dune liste des dclarations de membre. ventuellement, des variables de mme type que la structure peuvent dclarer l'extrmit de la structure. L'exemple suivant dclare une structure nomme Personne :
struct Personne { unsigned char name[20]; unsigned char prenom[20]; unsigned char nationalite[20]; unsigned char age; }

Nous pouvons dclarer des variables du mme type que la structure en donnant le nom de la structure et le nom de la variable. Par exemple, deux variables Moi et Toi de type Personne vous pouvez crer par la dclaration: struct Personne Moi, Toi; Les variables de type Personne peuvent galement tre cres lors de la dclaration de la structure comme suit :

Mr Nizar TOUJENI

12/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

struct Personne { unsigned char name[20]; unsigned char prenom [20]; unsigned char nationalite [20]; unsigned char age; }Moi, Toi

Nous pouvons attribuer des valeurs aux lements d'une structure en spcifiant le nom de la structure, suivi d'un point . et le nom de l'lment. Dans l'exemple suivant, l'ge des variables de structure Moi est mis 25, et M variable est affect la valeur de l'ge dans variable de structure Vous: Moi.age = 25; M = Vous.age; Elments de la structure peut tre initialis lors de la dclaration de la structure. Dans l'exemple suivant, le rayon et la hauteur de la structure sont initialiss Cylindre 1.2 et 2.5 respectivement :
struct Cylindre { valeur de rayon; valeur dhauteur; } MienCylindre {1.2, 2.5};

Les valeurs peuvent galement tre attribues pour les lments d'une structure lade des pointeurs en dfinissant les variable el les types des pointeurs. Par exemple, si LeCylindre est dfini comme un pointeur vers la structure Cylindre, alors nous pouvons crire :
struct Cylindre { valeur de rayon; flotter dauteur; }*LeCylinder; LeCylinder -> rayon = 1.2; LeCylinder -> hauteur = 2.5;

La taille d'une structure est le nombre d'octets contenus dans la structure. Nous pouvons utiliser l'oprateur sizeof pour obtenir la taille d'une structure. Considront l'exemple ci-dessus : sizeof (MienCylindre) retours 8, tant donn que chaque variable de type float occupe 4 octets en mmoire. Les champs de bits peuvent tre dfinis en utilisant les structures. Avec les champs de bits, nous pouvons attribuer des identificateurs pour les bits dune variable. Par exemple, pour identifier les bits 0, 1, 2, 3 d'une variable pour LowNibble et d'identifier les 4 bits restants pour HighNibble nous pouvons crire :
struct {

Mr Nizar TOUJENI

13/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC


LowNibble: 4; HighNibble: 4; } MienVariable;

On peut alors accder aux quartets bits de la variable MienVariable : MienVariable.LowNibble = 12; MienVariable.HighNibble = 8; En microC, nous pouvons utiliser les dclarations typedef pour crer de nouveaux types dune variable. Par exemple, une nouvelle structure type de donnes nomm Reg peut tre cr comme suit :
typedef struct { unsigned char nom[20]; unsigned char prenom[20]; unsigned age; }Reg;

Les variables de type Reg peuvent ensuite tre crs de la mme manire que les autres types de variables. Dans l'exemple suivant, les variables MyReg, Reg1, et Reg2 sont crs partir de type de donnes Reg: Reg MyReg, REG1, REG2; Le contenu dune structure peut tre copi dans une autre structure, condition que des structures soient dtermines partir du mme modle. Dans l'exemple qui suit , P2 est copi sur P1:

struct Personne { unsigned char nom [20]; unsigned char prenom [20]; unsigned int age; unsigned int hauteur; unsigned poids; }

struct Personne P1, P2;


........................ ........................

P2 = P1;

2.2.11 Unions
Les unions sont utilises pour les variables de recouvrement. Une union est similaire une structure et il est mme dfini d'une manire similaire. Les deux sont bass sur des modles, et les membres de tous les deux sont accessible l'aide des oprateurs . ou -> . Une chausse diffre d'une structure en ce que tous variables dans une union occupent la mme

Mr Nizar TOUJENI

14/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC


zone mmoire, ils partagent le mme stockage. Un exemple de dclaration de l'union est la suivante :

union flags { unsigned char x; unsigned int y; }P;

Dans cet exemple, les variables x et y occupent la mme zone de mmoire, et la taille de ce l'union est de 2 octets de long, ce qui est de la taille de la plus grande partie de l'union. Quand la variable y est charg avec une valeur de 2 octets, la variable x aura la mme valeur que faible octet de y. Dans l'exemple suivant, y est charg avec 16-bit valeur hexadcimale 0xAEFA, et x est charg avec 0xFA: P.y = 0xAEFA ; La taille d'une union est la taille (nombre d'octets) de son lment est le plus important. Ainsi, la dclaration: sizeof (P) renvoie 2. Cette union peut aussi tre dclare comme suit :

union flags { unsigned char x; unsigned int y; } union flags P;

2.2.12 Oprateurs et expressions en mikroC


Les oprateurs sont appliqus aux variables et d'autres objets dans les expressions pour assurer certaines conditions ou des calculs. Une expression est un objet syntaxique obtenu en assemblant des constantes, des variables et des oprateurs. Exemple : x + 12 Dans le langage microC, il y a dautres oprateurs que les oprateurs arithmtiques quon a lhabitude de manipuler. Il y en a en fait plus de 40 oprateurs. Oprateurs et priorits Vous avez lhabitude de manipuler des expressions arithmtiques : 2+3*4*5-2, 2-3-4 On sait que ces expressions sons quivalentes (2+(3*(4*5)))-2, (2-3)-4.

Mr Nizar TOUJENI

15/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC


Introduire les parenthses permet de dfinir sans ambiguit lexpression que lon manipule. Pour viter lusage des parenthses qui alourdissent la lecture, il existe des rgles pour lever toute ambigit : Exemple : 2+3*4 La sous expression 3*4 est value en premier et le rsultat obtenu est ajout la valeur 2 (forme avec parenthse : 2+(3+4)). On dit que loprateur * possde une priorit suprieur la priorit de loprateur + . 2-3-4

Mr Nizar TOUJENI

16/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

CHAPITRE III

Mr Nizar TOUJENI

17/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

III. FONCTIONS ET BIBLIOTHEQUES DANS MIKROC


3.1 Fonctions dans mikroC
Les fonctions sont gnralement dfinies comme des sous-programmes qui renvoient une valeur fonde sur un certain nombre de paramtres d'entre. Chaque programme doit avoir une seule fonction externe marquant le point d'entre dans le programme principale. Les fonctions sont dclars comme des prototypes en standard ou fourni par l'utilisateur, ou par des fichiers du programme. Chaque programme crit en langage mikroC se compose de nombre plus ou moins de fonctions. L'ide principale est de diviser un programme en plusieurs parties qui utilisent ces fonctions afin de rsoudre le problme rel plus facile. En outre, les fonctions nous permettent d'utiliser les comptences et les connaissances d'autres programmeurs. Par exemple, sil est ncessaire d'envoyer une chane de caractres un cran LCD, il est beaucoup plus facile d'utiliser une partie dj crite du programme que de recommencer. Les fonctions consistent des commandes prcisant ce qui doit tre fait sur des variables. Elles peuvent tre compares des sous-routines. En rgle gnrale, il est beaucoup mieux d'avoir un programme compos d'un grand nombre de fonctions simples que de quelques fonctions importantes. 3.1.1 Dclaration dune fonction Chaque fonction doit tre dclare de manire tre correctement interprt au cours du processus de compilation. Dclaration contient les lments suivants: Nom de la fonction Liste des paramtres Dclaration des paramtres Corps de la fonction Type de rsultat de la fonction

La syntaxe gnrale d'une dfinition de fonction est montre ci-dessous : type_de_rsultat nom_fonction(parameter1, parameter2, .....) { ............. corps de la fonction ............. } Mr Nizar TOUJENI 18/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC Dans lexemple qui suit, la fonction, nomme Mult, reoit deux arguments entiers, a et b, et renvoie leur produit. Notez que l'utilisation des parenthses dans une instruction de retour est facultative : int Mult(int a, int b) { return (a*b); } Quand une fonction est appele, elle s'attend gnralement donner le nombre d'arguments exprims en liste d'arguments de la fonction. Par exemple, la fonction prcdente peut tre appele : z = Mult (x, y); o la variable z est le type de donnes int. Notez que les arguments dclars dans la dfinition de la fonction et les arguments passs lorsque la fonction est appele sont indpendants les uns des autres, mme si elles ont le mme nom. Dans l'exemple prcdent, lorsque la fonction est appele, variable x est copi a et variable y et est copie b sur entre en fonction Mult. Certaines fonctions ne renvoient pas de donnes. Le type de donnes de ces fonctions doit tre dclares comme nul. Par exemple : void LED(unsigned char D) { PORTB = D; } Fonctions void peut tre appele sans aucune instruction d'affectation, mais les parenthses sont ncessaires pour indiquer au compilateur que un appel de fonction est faite : LED ( ); En outre, certaines fonctions ne possdent pas d'arguments. Dans l'exemple suivant, la fonction, nomme Compl, complte PORTC du microcontrleur. Il ne renvoie pas de donnes et n'a pas d'arguments: void Compl( ) { PORTC = ~ PORTC; Mr Nizar TOUJENI 19/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC } Cette fonction peut tre appele en tant que : Compl ( ); Les fonctions sont normalement dfinies avant le dbut du programme principal. Certaines dfinitions de fonction et de leur utilisation dans les programmes principaux sont illustres dans les exemples suivants: Exercice 3.1 crire une fonction appele Cercle_Surface pour calculer la surface d'un cercle dont le rayon sera utilis comme un argument. Utilisez cette fonction dans un programme principal pour calculer la surface d'un cercle dont le rayon est de 2,5 cm. Sauvegarder la valeur de cette surface dans une variable appele Cercle. Solution 3.1 float Cercle_Surface(float rayon) { float s; s = PI*rayon*rayon; return s ; } Le code-source ci-dessous montre comment la fonction Cercle_Surface peut tre utilise dans un programme principal pour calculer la surface d'un cercle dont le rayon est de 2,5 cm. La fonction est dfinie avant le programme principal. La fonction est appele l'intrieur du programme principal pour calculer la surface et la stocker dans la variable Cercle.
/*******************************************************************************

SURFACE D'UN CERCLE ==================== Ce programme appelle la fonction Cercle_Surface pour calculer la surface d'un cercle. Microcontroleur : PIC 18F452 Oscillateur : HS, 08.0000 Mhz

Mr Nizar TOUJENI

20/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC


Fichier: SURFACE_CERCLE.c Date: Avril 2014
*******************************************************************************/

// Calcul de la surface d'un cercle en fonction de rayon


float Cercle_Surface (float rayon) { float s; s = PI*rayon*rayon; return s; }

/* Debut du programme principal. Calcul de la surface d'un cercle ou le rayon = 2,5 */


void main () { float r, Cercle; r = 2.5; Cercle = Cercle_Surface(r); }

Exercice 3.2 crire une fonction appele Surface et une fonction appele Volume pour calculer la surface et le volume d'un cylindre, respectivement. Puis crire un programme principal pour calculer la surface et le volume du cylindre dont le rayon est 2,0 cm et la hauteur est 5,0 cm. Stocker la valeur de cette surface dans la variable Cylindre_Surface et la valeur de volume dans la variable Cylindre_Volume. Solution 3.2
/*******************************************************************************

SURFACE ET VOLME DUN CYLINDRE

Mr Nizar TOUJENI

21/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC


============================== Ce programme calcule la surface et le volume d'un cylindre dont le rayon est 2,0cm et la hauteur est 5,0cm. Microcontroleur : PIC 18F452 Oscillateur : HS, 08.0000 Mhz Fichier: VOLUM_CYLINDRE.c Date: Avril 2014
***************************************************************************/

//Fonction pour calculer la surface d'un cylindre


float Surface(float rayon, float hauteur) { float s; s = 2.0*PI*rayon*hauteur; return s; }

// Fonction pour calculer le volume d'un cylindre


float Volume(float rayon, float hauteur) { float s ; s = PI*rayon*rayon*hauteur; return s; }

// Debut du programme principale


void main ()

Mr Nizar TOUJENI

22/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC


{ float r = 2.0, h = 5.0; float Cylindre_Surface, Cylindre_Volume; Cylindre_Surface = Surface(r,h); Cylindre_Volume = Volume(r,h); }

Exercice 3.3 crire une fonction appele Minuscule_Majuscule pour convertir un caractre de minuscule en majuscule. Utilisez cette fonction dans un programme principal pour convertir la lettre r en majuscules. Solution 3.3 La valeur ASCII du caractre en majuscule du premier caractre ('A') est gale 0x41. De mme, la valeur l'ASCII du premier caractre en minuscule ('a') est gale 0x61. Un caractre minuscule peut tre converti en son quivalent majuscule en soustrayant 0x20 du caractre en minuscule.
/******************************************************************************* MINUSCULEMAJUSCULE =================== Ce programme convertit le caractre en minuscule de la variable Lc dans le caractre en majuscule et le sauvegarde dans la variable Uc. Microcontroleur : PIC 16F84A Oscillateur : HS, 8.0000 Mhz Fichier: MINUSC_MAJUSC.c Date: Avril 2014
*******************************************************************************/

/* Fonction pour convertir un caractre en minuscule dans un caractre en majuscule*/


unsigned char Minuscule_Majuscule (unsigned char c)

Mr Nizar TOUJENI

23/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC


{ if(c > ='a' && c <= 'z') return(c - 0x20); else return c; }

// Debut du programme principal


void main () { unsigned char Lc, Uc; Lc = r; Uc = Minuscule_Majuscule (Lc); }

3.1.2 Prototypes de fonctions Si une fonction n'est pas dfinie avant qu'il ne soit appel, le compilateur gnre une erreur. Une faon de contourner ce problme est de crer un prototype de fonction. Une fonction prototype est construite facilement en faisant une copie de la tte de la fonction. Les paramtres ne sont pas obligatoires, mais le type de donnes et des paramtres doivent tre dfinis. Dans un exemple, qui suit, le prototype de fonction appele Area est dclare et la fonction s'attend davoir un paramtre de type en virgule flottante : float Area(float rayon); Ce prototype de fonction pourrait galement tre dclar comme suit : float Area (float); Prototype de fonction doit tre dclar au dbut d'un programme. Les dfinitions et les appels de fonction peuvent alors tre faits n'importe quel point dans le programme.

Mr Nizar TOUJENI

24/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

Mr Nizar TOUJENI

25/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

CHAPITRE IV

Mr Nizar TOUJENI

26/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

IV. EXEMPLES DE PROGRAMMATION EN mikroC POUR LES MICROCONTROLEURS DE LA FAMILLE PIC


Exemple 1. Chenille LEDs Dans ce projet les huit LEDs sont connectes PORTC d'un microcontrleur. Lorsqu'une tension est applique au microcontrleur (ou est rinitialis), les LEDs s'allument en alternance. Il y a le dlai dune seconde de sorte quune LED peut tre vu tourner sur ON et OFF. Le schma de principe du projet est illustr la figure 4.1.

Fig.4.1. Schma de simulation pour lexemple 1 Le fichier dsign comme LED1.c et donn dans le code-source 4.1. Code-source 4.1
/*******************************************************************************

Chenille a LEDs =============== Les huit LEDs sont connectees PORTC du microcontrleur 18f452. Lorsqu'une tension est applique au microcontrleur (ou est rinitialise), les LEDs s'allument en alternance. Microcontroleur: 18F452 Oscillateur : HS, 4.0000 Mhz Fichier: LED1.c

Mr Nizar TOUJENI

27/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

Date: Avril 2012


***************************************************************************/ void main() { unsigned char J = 1; TRISC = 0; for( ; ; ) { PORTC = J; Delay_ms(100); J = J << 1; if(J == 0) J = 1; } } // Envoyer J au PORTC // Pause 100 ms // Dcalage gauche J // Si la derniere LED, allumer la 1ere LED // PORTC est configure en sortie // Boucle sans fin

Exemple 2. Clignotement des LEDs deux faons diffrentes On propose de faire clignoter LEDs branches au port B dun microcontrleur (fig. 4.2) de deux faons diffrentes : 1. Ds que le microcontrleur est activ, tous les LEDs clignotent avec une priode dune seconde (voire la figure ci-dessous). Et a doit rpter 10 fois.

2. Aprs cela, les LEDs doivent clignoter chaque 500 ms infiniment comme indiqu dans la figure ci-dessous.

Mr Nizar TOUJENI

28/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

Le fichier nomm LED2.C qui ralise ce projet est reprsent dans le code-source 4.2

Fig.4.2. Schma de simulation pour lexemple 2 Code-source 4.2


/*******************************************************************************

LEDs clignotantes diffremment ===============================


Les huit LEDs sont connectes PORTB du microcontrleur 16f887. Lorsqu'une tension est applique au microcontrleur (ou est rinitialis), les LEDs s'allument en alternance en deux faons diffrentes.

Microcontroleur: 16F887

Mr Nizar TOUJENI

29/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

Oscillateur : HS, 10.0000 Mhz Fichier: LED2.c Date: Avril 2014


*******************************************************************************/ void main() { ANSEL = 0; ANSELH = 0; PORTB = 0xFF; TRISB = 0; Delay_ms(500); PORTB = 0; for (k=1 ; k < 20 ; k++) { switch (PORTB) { case 0x00: PORTB = 0xFF; Delay_ms(500); break; case 0xFF: PORTB = 0x00; Delay_ms(500); } } PORTB=0b01010101; while(1) {

Mr Nizar TOUJENI

30/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

PORTB = ~PORTB; Delay_ms(500); } }

Exemple 3. RELAI Dans ce projet la minuterie, sur la base de registre TMR0, est utilise comme un compteur. L'entre de comptage est relie un bouton-poussoir Input (fig. 4.3) de sorte que toute pression sur Input provoque TMR0 compter une impulsion. Lorsque le nombre d'impulsions correspond au nombre stock dans le registre nomm TEST, la valeur logique 1 (5V) apparat sur le pin3 de PORTD. Cette tension active un relais lectromcanique, et ce bit est appel RELAI dans le programme (voire le fichier RELAI.C de code-source 4.3). Dans le registre de TEST est stock un nombre de 5 pour cet exemple. Bien sr, il peut tre n'importe quel nombre dfini comme une constante. Par ailleurs, le microcontrleur peut activer un autre appareil au lieu de relais, tandis que le capteur peut tre utilis la place du boutonpoussoir. Cet exemple illustre l'une des applications les plus courantes du microcontrleur dans l'industrie; quand quelque chose est effectu autant de fois que ncessaire, puis quelque chose d'autre doit tre activ ou dsactiv ...

Fig.4.3. Schma de simulation pour lexemple 3 Mr Nizar TOUJENI 31/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC Code-source 4.3
/*******************************************************************************

RELAI =======
Dans ce projet la minuterie, sur la base de registre TMR0, est utilise comme un compteur. L'entre de comptage est relie un bouton-poussoir Input de sorte que toute pression sur Input provoque TMR0 compter une impulsion. Lorsque le nombre d'impulsions correspond au nombre stock dans le registre nomm TEST, la valeur logique 1 (5V) apparait sur le pin3 de PORTD. Cette tension active un relais lectromcanique RELAI.

Microcontroleur: 16F887 Oscillateur : HS, 10.0000 Mhz Fichier: RELAI.c Date: Avril 2014
*******************************************************************************/ void main() { char TEST = 5; // Constante TEST = 5

enum sortie {RELAI = 3}; // Constante RELAI = 3 ANSEL = 0; ANSELH = 0; PORTA = 0; TRISA = 0xFF; PORTD = 0; TRISD = 0b11110111; OPTION_REG.F5 = 1; // Initialisation du porte A // Porte A est configure en entre // Initialisation du PORTD // Broche 3 du PORTD3 est configure en sortie // Compteur TMR0 reoit des impulsions par la broche RA4 // Les E/S sont configures en numriques

Mr Nizar TOUJENI

32/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

OPTION_REG.F3 = 1; TMR0 = 0; do {

// Taux de prdiviseur est de 1:1 // Initialisation du compteur TMR0

if (TMR0 == TEST) PORTD.RELAI = 1; // Est-ce que le nombre dimpulsion TMRO est gal constante TEST? // Nombre est gal TEST. La broche RD3 est en 1 (RELAIS est active) } while (1); } // Restez dans la boucle sans fin

Une seule constante numre RELAI est utilise dans cet exemple. Il est attribu une valeur lorsquelle est dclare : enum sortie {RELAI = 3}; Si plusieurs broches du PORTD sont relies des RELAIS, lexpression ci-dessus pourrait tre crite comme suit : enum sortie {RELAI=3, CHAFFAGE, ECLAIRAGE =6, POMPE} ; Toutes les constantes, aprs celle avec les valeurs affectes (RELAI = 3 et ECLARAGE = 6), sont des valeurs automatiquement incrment de 1 par rapport la valeur prcdente. Dans ce cas, la constante CHAUFFAGE et celle POMPE seront affects les valeurs 4 et 7 respectivement (CHAUFFAGE = 4 et POMPE = 7). Exemple 4. Registres TMR0 et TMR1 comme minuteries Dans l'exemple prcdent, le microcontrleur ne fait rien entre des impulsions de comptage en utilisant des boucles sans fin. Ces dchets du temps est un luxe inadmissible et par consquent une autre mthode doit tre applique. Considrons le schma microcontrleur 16F887 de la figure 4.1 qui sera toujours le mme pour raliser les nouvelles fonctions. Le fichier INTERRUP_TMR0.C du code-source 4.4 montre lutilisation du registre TMRO avec prdiviseur pour gnrer une interruption. Une fois que le registre TMR0 est trop-plein le routin dinterruption incrmente automatiquement la variable cnt par 1. Lorsque sa valeur atteint

Mr Nizar TOUJENI

33/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC 400, le PORTB est incrment de 1. L'ensemble de la procdure est masqu , qui permet au microcontrleur de faire autre chose. Code-source 4.4
/******************************************************************************* TMR0 ======= Une fois que le registre TMR0 est trop-plein la routine dinterruption incrmente automatiquement la variable cnt par 1. Lorsque sa valeur atteint 400, le PORTB est incrment de 1. L'ensemble de la procdure est masque, qui permet au microcontrleur de faire autre chose.

Microcontroleur: 16F887 Oscillateur : HS, 10.0000 Mhz Fichier: INTERRUP_TMR0.c Date: Avril 2014
*******************************************************************************/ unsigned cnt; void interrupt( ) { cnt++; TMR0 = 100; INTCON = 0x20; } void main() { OPTION_REG = 0x84; // Prdiviseur pour TMR0 // Interruption cause lincrmentation par 1 de la variable cnt // Valeur initiale du TMR0 // Bit T0IE est positionne a 1, bit T0IF est en 0

// Dfinir la variable cnt

Mr Nizar TOUJENI

34/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

ANSEL = 0; ANSELH = 0; TRISB = 0; PORTB = 0x0; TMR0 = 100; INTCON = 0xA0; cnt = 0; do {

// Toutes les broches E/S sont configur en digitale

// PORTB est configur en sortie // Initialisation du PORTB // TMR0 compte de 100 255 // Interruption par TMR0 est autoriss // Variable cnt est initialise 0

// Boucle sans fin if (cnt == 400) {

// Incrmenter port B aprs 400 interruptions


PORTB = PORTB++; // Incrmenter PORTB par 1 cnt = 0; // Initialiser la variable cnt

} } while(1); }

On voie que lInterruption se produit sur chaque dbordement du registre TMR0. Le nombre dinterruption 400, dans cet exemple, provoque lincrmentation du PORTB comme indique la figure ci-dessous.

Mr Nizar TOUJENI

35/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC Dans le code-source 4.5 (fichier INTERRUP_TMR1) on utilise linterruption produit par le dbordement de registre TMR1(TMR1H, TMR1L). Aprs 76 dinterruption se produit lvolution sur le PORTB comme indique la figure ci-dessous. Code-source 4.5
/******************************************************************************* TMR1 =======

Une fois que le registre TMR1 est trop-plein, la routine dinterruption incrmente automatiquement par 1 la variable cnt. Lorsque sa valeur atteint 76, les bits du PORTB sont inverss. Microcontroleur: 16F887 Oscillateur : HS, 10.0000 Mhz Fichier: INTERRUP_TMR1.c Date: Avril 2014
*******************************************************************************/ unsigned short cnt; void interrupt() { cnt++ ; PIR1.TMR1IF = 0; TMR1H = 0x80; TMR1L = 0x00; } void main() { // Valeurs initiales du TMR1H and TMR1L // Interruption cause lincrmentation par 1 de la variable cnt // Remise 0 bit TMR1IF // Dfinir la variable cnt

Mr Nizar TOUJENI

36/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

ANSEL = 0; ANSELH = 0; PORTB = 0xF0; TRISB = 0; T1CON = 1; PIR1.TMR1IF = 0; TMR1H = 0x80; TMR1L = 0x00; PIE1.TMR1IE = 1; cnt = 0; INTCON = 0xC0; do { if (cnt == 76) {

// Broches E/S sont configure en numriques

// Initialisation de PORTB // PORTB est configur en sortie // Remise 1 du TMR1 // Remise 0 du TMR1IF // Initialisation du TMR1

//Activer linterruption en cas de dbordement du TMR1 // Remis 0 la variable cnt // Activer interruption (bits GIE et PEIE)

// Boucle sans fin

PORTB = ~PORTB; //Bits du PORTB sont inverss aprs 76 dinterruptions cnt = 0; } } while (1); } // Initialisation de la variable cnt

Mr Nizar TOUJENI

37/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

Mr Nizar TOUJENI

38/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

Mr Nizar TOUJENI

39/85

Programmation en mikroC. Application pour les microcontrleurs de la famille PIC

Mr Nizar TOUJENI

40/85