Chapitre 3 : Commençons à programmer !
Bonjour à tous ! Bienvenue dans le chapitre 3.
Vous voulez programmer ? Alors vous allez adorer cette partie, car on ne va faire que ça. Nous allons d'abord créer notre premier programme, celui de faire clignoter une LED ! Puis petit à petit, nous allons arriver au programme final, celui de easybot.
Note : Pour pouvoir programmer, il faut au moins avoir lu la partie 1 et le chapitre 4 de la partie 2 du
tutoriel du site du zéro. Il le fera mieux que moi !
Allez fini le blabla. où en étions-nous... Ah oui ! Vous venez d'installer MikroC et picflash normalement sans encombres, si c'est le cas, contactez-moi.
Ouvrez MikroC, vous voyez maintenant la belle interface du logiciel. Nous allons la découvrir au fur et à mesure.
Commencez par cliquer sur "project" en haut à gauche (oui vous avez remarqué c'est en anglais :( ), puis sur "close project". Pour fermer tout projet il faudra impérativement cliquer sur cela.
Créer un nouveau projet
-Voilà maintenant nous allons en créer un nouveau, pour cela, cliquez sur "project"-"new project". Dans le premier champ, entrez le nom de votre projet voulu, attention sans espaces ni accents ! Nous allons l'appeler "LED_clignote". Dans le deuxième champ, indiquez le répertoire dans lequel vous voulez l'enregistrer. Perso moi je me suis fait un dossier nommé "pics" et je met un projet pour chaque sous dossiers.
-Le champ "description" est facultatif.
-Viens la liste déroulante : "Device". Là, vous devez sélectionner le pic que vous avez inséré dans le support, si le 16F877 vous a été fourni, mettez le 16F877 (en effet les pics 16F877 et 16F877A sont peut-être pareil mais ils sont ""différents pour MikroC"").
-Maintenant le champ "clock", ceci correspond à l'oscillation du quartz. Ouille c'est compliqué ça

.
Ca sert en gros d'horloge externe au micro-contrôleur, c'est ce petit truc brillant à coté du 16F877 :

Si on veut, le quartz sert comme base de temps au pic... Lisez la valeur écrite sur le dessus de celui_ci (c'est une fréquence donc en hertz). Pour le 16F877, la fréquence est normalement de 8.000000 mhz (8 méga hertz).
-Cliquez sur le bouton "default" en dessous, et enfin sur ok ! Votre projet est enfin créé
-Maintenant faîtes une pause et soufflez un peu

.
Programmer
Ne faîtes pas une attaque quand vous verrez l'immonde écran noir qui s'offre à vos yeux

. On va tout de suite le mettre en blanc : cliquez sur "tools"-"options...", ensuite sur le petit + à coté de "Editor" à gauche, puis sur color. Ensuite sur la liste déroulante : Background, sélectionnez la couleur désirée
Maintenant on peut commencer ! Bien, vous savez tous que dans tout programme, il y a une fonction principale : main. Et nous avec MikroC, il n'y aura pas de paramètres à renvoyer dans presque la totalité des programmes. Donc pas de problèmes, on va commencer par : "void main" tout simplement. Le programme sera donc :
void main ()
{
//Fonction main
}
Compilez ce premier programme à l'aide du bouton "built project" :

ou alors avec les boutons "ctrl + F9".
"Success (Release Build)" s'affiche en bas, vous venez de réaliser votre premier programme !

.
L'électronique numérique et analogique
L'électronique analogique
Nous allons maintenant aborder un sujet fondamental : L'électronique
numérique et analogique. Il faut connaître cette notion pour programmer
avec les micro-contrôleurs. Je vais essayer de vous l'expliquer, sachant
qu'on peut écrire un livre entier sur le sujet.
Commençons par un schéma :

Le point A veut dire "salut" au point B, pour cela il va lui envoyer
un signal pour lui dire son mot :

C'est la même chose de façon électrique, le point A va
envoyer au point B une tension, et le point B saura que
ça veux dire "salut", puisqu'il n'y a qu'une possibilité,
ou seulement un signal possible. Autrement dit le point A ne pourra que
dire au point B "salut", autant de fois qu'il voudra.
Mais nous avons
un gros soucis, le point A veut dire au point B :
"Salut manu, ramène ta playstation". Que faut-il faire pour que B
reçoive toutes les informations de A ? La réponse est simple,
il va envoyer plusieurs signaux, et chaque signal correspondra à un
mot :

Le point B recevra bien après la phrase "Salut manu, ramène ta
playstation".
D'un point de vue électrique, les différents
signaux
seront des tensions différentes. EX : Salut vaudra 5V, manu 4V, ramène
3V, ta 2V et playstation 1V. Le point B sait à quoi
correspondent les tension, autrement dit il peut si le point A envoie les informations
dans le désordre, reconstituer la
phrase dans le désordre EX :

B recevra donc : "manu ramène Salut ta playstation".
Jusque là ça va ? Bien, ce qu'on vient de voir est déjà
un aspect de l'électronique
analogique, c'est à dire que A, pour communiquer avec B, utilise plusieurs
signaux différents. Je vais prendre un exemple
d'utilisation : Je possède une chaîne hifi. Pour augmenter ou diminuer
le volume, je dois tourner le bidule (qu'on appelle
potentiomètre) vers la droite (le volume augmente) ou vers la gauche
(le volume diminue). Eh bien ce système est purement
analogique, on peut donc le représenter de la façon suivante :

Ici le point B recevra le signal de A (c'est à dire le volume voulu
du son qui est ici de 10), et agira en conséquence :
Il ordonnera aux Haut-parleurs de se mettre sur le volume "10". Bien
sûr tout ceci est imagé 

Ici le point B recevra pour le volume : 20.
Nous avons donc 2 valeurs "10 et 20", qui correspondent à des
signaux différents. Donc électriquement à des tensions
différentes.
L'électronique numérique
Passons maintenant à l'électronique numérique qui est un
peu plus compliquée à comprendre.
Dans l'exemple sur l'envoi de la phrase "Salut manu ramene ta playstation",
il y'a un gros problème : L'envoi de ces informations
est très long. En effet le point A sera obligé d'envoyer les signaux
différents l'un après l'autre. Pour cette phrase ça va
encore, mais si A veut envoyer un texte de Victor Hugo, ce sera beaucoup trop
long. Aussi si on veut envoyer pleins de nombres
différents à B, les tensions seront très élevées
si on veut envoyer 100234587 par exemple.
Pour cela on a trouvé une solution très astucieuse : Si on utilisait
plusieurs canaux différents ? Pour chaque canaux, il
y aura seulement deux valeurs, 1 ou 0. Illustrons tout cela par un schéma
:

Le point B ne recevra que des zéros et des uns.
Vous êtes perdus ? C'est normal c'est très dur à comprendre
au début mais
à force on finit par comprendre.
Bien, maintenant on veut envoyer la phrase "Salut manu ramene ta playstation"
rien qu'avec des 0 et des 1 :

Ici, "1;1;0" correspond à "Salut", "1;0;1"
correspond à "manu", "0;0;1" à "ramène",
"1;1;1" à "ta" et "0;0;0" à "playstaion".
B recevra donc à la fin la phrase entière.
Mais vous allez me
dire que c'est la même chose qu'avant car on envoi l'un après
l'autre les signaux. Oui c'est vrai on se complique inutilement la vie, mais
pour des grands nombres d'informations c'est très très
pratique !
On peut constater que sur ce schéma, il y'a trois canaux, en fait on
appelle cela des "bits", ça vous dis quelque chose ? 
Avec 3 bits, on peut avoir 8 possibilités (ou dans cet exemple 8 mots
différents) qu'on peut envoyer. Ici elles sont :
"1;1;0" "1;0;1" "0;0;1" "1;1;1" "0;0;0"
""1;0;0" "0;1;0" "0;1;1" Ce qui fait en tout
8.
On peut bien sûr calculer les possibilités de façon très
simple : On prend le nombre de bits (de canaux) et on le met en exposant
sur le chiffre 2. Pour ce cas la ce sera : 2 au cube, ce qui fait 8.
Si on a 8 bits, on fera 2puissance8, ce qui fait 256 possibilités.
Si on a 256 bits, on fera 2puissance256, ce qui fait... beaucoup beaucoup
Donc si on a beaucoup de canaux, on pourra transporter beaucoup plus d'informations.
Petits exercices
Pourriez vous me dire si les composants suivant sont analogique ou numérique
?
Une résistance :
Analogique car il fait varier une tension (cf la loi d'ohm), on a pas que des 0 et des 1
Un interrupteur :
Numérique car il
laisse passer ou pas le courant, 1 ça passe, 0 ça passe pas.
Un condensateur :
Analogique car il lisse
un courant, rien à voir avec des 0 et des 1.
Un mirco-contrôleur :
Numérique
eh oui on va le voir il travail avec au moins 16 bits, dans les ordinateurs
les micro-processeurs possèdent un grand nombre de bits, c'est pour cette
raison qu'ils sont très rapides et peuvent travailler
avec de grands nombres.
Le pic 16F877 et la gestion des entrées sorties
Nous allons aborder un sujet beaucoup plus facile que le précédent.
C'est un peu dur à comprendre au début, mais on s'y fait
très vite !
Vous vous rappelez encore du 16F877 ?
J'espère
Bien voici
le schéma du pic :

Ce schéma explique à quoi correspondent les broches du pic 16F877.
Ex : La broche 36 correspond à RB3/PGM. Il y'a en tout 40
broches. Nous avons expliqué avant qu'est-ce qu'étaient les bits
(canaux), Et bien pour info sur le 16F877 il y a exactement
33 bits, ce qui fait fait en passant 2puissance33 = 8589934592 possibilités.
Ces bits sont "rangés" la plupart du temps par groupe de 8.
On appelle ces groupes de 8, des ports. Chaque port a une lettre (ici il y a
le port A, B, C, D et E).
Pour reconnaitre à quelle port correspond une broche, on fait, en prenant l'exemple de la broche 17 :
On ne s'occupe pas de CCP1, on prend "RC2".
On enlève le "R" et on garde seulement "C2". Le "C"
nous dit à quelle port elle appartient (en l'occurrence ici au port C)
et le 2 le numéro de la broche dans le port (ici la broche numéro
"2").
Attention !! : la broche RC0 est aussi une broche comme les autres ! Il faut
faire très attention ! Ici la la broche RC0 correspond à la broche
numéro zéro du port C.
Petits excercices : Comptez combien il y a de bits sur le PORTE :
Il
y en a seulement 3
Comptez combien il y'a de possibilités d'envoi d'informations sur le
PORTD :
Sur le portD, il y a 8 bits :
RD0, RD1, RD2, RD3, RD4, RD5, RD5, RD6 et RD7. Donc on met 8 en exposant sur
2 : 2puissance 8 = 256. Ce qui fait 256 possibilités
rien qu'avec le PORTD !
NB: A chaque fois que vous cherchez des bits sur le schéma du 16F877,
enlevez toujours les indications après ou avant le slash "/".
EX : La broche 7 correspond à RA5, on enlève le "AN4/SS".
On verra plus tard à quoi servent ces indications.
Les sorties et les entrées
Nous arrivons maintenant aux entrées-sorties.
Vous vous rappelez du schéma d'avant ? :

On peut dire que les bits du point A envoient des informations et les bits
du point B réceptionnent des informations : Ils attendent un signal.
Et bien dans ce cas il faut dire que les bits du point A sont configurés
en sortie (ils "sortent" un signal) et les bits du point B en entrée
(ils attendent un signal qui "entre"). Le point A représente
le 16F877 et le point B peut-être aussi un 16F877 au autre chose.
Sur un pic on peut donc configurer si un bit est en entrée ou en sortie.
Exemple :

Donc si je veux allumer une LED, je configure RB3 en sortie. Si je veux savoir
si un bouton-poussoir est enclenché ou non,
je configure RD2 en entrée. C'est pas si sorcier non ? O_o
Maintenant la programmation !
On va traduire tout ça en langage C maintenant !
Ouvrez Mikroc et reprenez le programme de la dernière fois :
void main ()
{
//Fonction main
}
Pour dire quels bits on veut configurer en entrée/sorties, il faut ajouter
la ligne suivante :
TRIS + nom du port = 0b + bit7,bit6,bit5,bit4,bit3,bit2,bit1,bit0
On va expliquer tout ça :
-Le "TRIS" signifie que l'on va configurer un PORT, ne vous occupez
pas de savoir ce que ça veut dire. A chaque fois qu'il
faudra configurer un port, il faudra mettre ça devant.
-Ensuite il faut mettre le nom du port ou autrement dit la lettre. Par exemple,
si on veut configurer le PORTC, ça sera :
TRISC.
-puis on a le "=0b" (attention c'est un zéro). Ceci indique
que l'on va donner la valeur des 8 bits (qui vont suivre).
-Et ensuite il suffit de mettre la valeur de chaque bits.
Edit : Chaque bit correspond à son numéro. Par exemple si on configure
le PORTC, le bit 7 sera RC7, le bit 3 RC3 etc...
Vous devez retenir ceci, quand on configure un PORT :
1 = entrée
0 = sortie
Et oui on est en numérique, donc on bosse qu'avec des 0 et des 1 !
Si je veux configurer la broche RC3 en entrée et tout les autres broches
du PORTC en sortie la ligne sera :
TRISC=0b00001000
J'aimerais allumer un LED sur la broche RB5 et détecter l'appui d'un BP (bouton poussoir) sur la broche RB0.
Voici le programme qui va permettre de configurer le PORTB :
void main ()
{
//configuration du PORTB
TRISB=0b00000001
}
C'est bon ça rentre ?
TP : Notre premier programme : Faire clignoter une LED !
Ah ! Enfin ! On y arrive, votre premier programme va déjà vous impressionner malgré sa simplicité

.
Commençons :
Ouvrez MikroC, et créez un nouveau programme qui se nommera : "led_clignote". Si vous ne vous souvenez plus comment créer
un projet, rendez-vous tout en haut de la page du tutoriel.
Tapez déjà les lignes de base de votre programme (void main etc...). Nous allons faire clignoter la LED RB2, donc nous allons
configurer le PORTB. La broche RB2 sera donc configurée en sortie (donc -> 0). Le programme sera :
void main ()
{
//configuration du PORTB
TRISB=0b00000000
// -----x-- Broche RB2 en sortie
}
Compilez le programme, qui sera sans erreurs bien-sûr ^^ .
Une question vous tracasse surement : Comment on fait pour allumer une LED ?
C'est bien simple, on le fait avec la commande suivante :
PORT + nom du port.F + numéro de la broche qu'on veux allumer = 1
-Le début ne pose pas de problèmes, si je veux être sur le port C, ce sera : "PORTC".
-Puis on a ce fameux ".F", pas de questions à se poser, il suffit juste de le rajouter : "PORTC.F"
-Ensuite viens le numéro de la broche qu'on veut allumer (ou le numéro du bit), si on veut allumer la broche RC7, ce
sera : "PORTC.F7"
-Et enfin le "=1", je vous rappelle que nous sommes en numérique mes amis ^^ Donc que des zéros et des 1.
1 = LED allumée (ça passe)
0 = LED éteinte (ça passe pas)
Attention ! : Ces 0 et ces 1 n'ont rien à voir avec ceux du "TRIS", ne vous trompez pas, ils servent
juste à dialoguer (comme on l'a vu au dessus avec le point A et le point B).
Exemple concret :
Micro-contrôleur, je t'ordonne d'allumer la LED RD7, la commande sera :
PORTD.F7=1
Bien sûr il faut auparavant configuré la broche RD7 en sortie, c'était juste un exemple.
Maintenant, à votre avis, quel sera le programme pour allumer notre broche RB2 ? :
void main ()
{
//configuration du PORTB
TRISB=0b00000000
// -----x-- Broche RB2 en sortie
PORTC.F2=1;
}
Compilez le programme, sa fonction sera d'allumer une LED !
Flasher le programme dans le pic
Vous pouvez vous en douter, nous allons "mettre" (le terme exacte est flasher) le programme dans le pic 16F877.
Pour cela il vous faut le logiciel PIC flash (que vous avez au préalable téléchargé). Et vous devez bien sûr avoir allumé
la carte easypic. Vérifiez bien que la LED "jaune" est allumée (signifiant que la carte est bien connectée à l'ordinateur).
Appuyez sur l'icône suivante eu milieu tout à droite :
Attendez que le logiciel picflash fasse son travail en regardant plusieurs barres de défilement, puis regardez votre carte :
La LED RC2 est allumée !!!!!! C'est la magie des pics, ceci n'est rien comparé aux multiples fonction qu'on peut faire avec
mais c'est déjà un bon début que d'être arrivé ici ! Bravo !
Mais ? La LED ne clignote pas O_o ! Oui normal nous allons le faire grâce à la fonction Delay_ms().
Cette fonction qui est intégrée dans MikroC, à pour but d'attendre le nombre de millisecondes que vous lui donner entre les
parenthèses. C'est très très facile, pratique et rapide ! Vous allez l'utiliser très souvent.
Je vous rappelle que 1000 millisecondes font une seconde.
Donc si je vous demande d'attendre 1.5 sec., vous m'écrirez :
Delay_ms(1500);
Voici donc le programme final qui fera clignoter une LED pendant une seconde allumée et une seconde éteinte :
void main()
{
//configuration du PORTB
TRISB=0b00000000
// -----x-- Broche RB2 en sortie
while (1) //Boucle while infinie
{
PORTB.F2=1; //On allume la LED RB2
Delay_ms(1000); //On l'a laisse allumée pendant 1sec.
PORTB.F2=0; //Puis on l'éteint
Delay_ms(1000); //Pendant 1sec.
//et ça recommence
}
}
C'est bête comme chou non ? On allume la LED, puis on attends 1000 microsecondes (1 secondes), puis on éteint la LED et
on ré-attend 1000 secondes pour éviter qu'elle ne se rallume tout de suite.
Sinon la LED resterait tout le temps allumé, car
un programme s'exécute très vite.
Voilà notre premier résultat qui est très concluant non ? On a bien entamé la construction d'easybot, Bravo !