On désigne généralement sous la dénomination " logiciel
embarqué " un programme destiné à tourner localement sur une carte disposant
dun microcontroleur. Nous allons donc commencer la partie la plus amusante. Nous
allons créer de petits programmes sur une carte à PIC.
11.1 Le matériel nécessaire |
Utilisez une platine dessais constituée de petits trous reliés ensemble par
rangées. Les liaisons seffectuent alors en fils volants. Vous trouverez ces
platines chez tous les marchands délectronique. Pour mettre ces leçons en
pratique, il vous faudra le matériel suivant (récupérable et peu onéreux) :
- 1 PIC 16F84 ou 16F84A en boîtier PDIP et de fréquence quelconque
- 2 supports " tulipe " 18 pins / écartement entre les
rangées : 0.3
- 1 Quartz de 4MHz
- 2 condensateurs de 27pF
- 1 Led rouge
- 1 Résistance de 330 ohms.
- 1 bouton-poussoir " normalement ouvert " (N.O.)
- 1 peu de fil rigide pour les connexions sur la platine dessais
- 1 alimentation stabilisée
Si vous ne disposez pas dune alimentation de 5V, vous pouvez, soit utiliser une
pile plate de 4.5V, soit réaliser une petite alimentation dont le schéma est donné page
suivante.
Il vous faudra dans ce dernier cas :
- 1 Bloc dalimentation secteur de 9 à 15V, pas critique.
- 1 Condensateur de 100µF/35V.
- 1 Condensateur de 0.1 µF
- 1 diode 1N4007, ou autre diode permettant un courant de 1A (pas critique)
- 1 Régulateur de type 7805.
Cet ensemble ne vous ruinera pas. De plus, les composants pourront être récupérés
pour vos prochaines applications. Vous verrez que les PICs peuvent être utilisées dans
des tonnes dapplications au quotidien
11.2 Montage de la platine dessais |
- Insérez la pic dans un des supports tulipe.
- Insérez le support restant dans la platine dessais, et procédez aux connexions
suivant le schéma ci-joint.
- Vérifiez tout avant de connecter lalimentation.
- Si vous navez pas dalimentation stabilisée, utilisez une pile, ou connectez
les composants suivant le schéma suivant.
Une fois tout ceci fait, vérifiez une dernière fois, sans placer la PIC avec son
support dans le support de la platine, puis mettez sous tension. Vérifiez que les
tensions sont correctes au niveau des broches dalimentation de la PIC.
Vous êtes maintenant prêt à commencer les expérimentations.
Effectuez une copie de votre fichier m16F84.asm, et renommez cette copie Led_cli.asm.
Lancez MPLAB et répondez " non " lorsquon vous demande si vous
voulez charger Essai1.
Schéma de connexion de la PIC :
Schéma de la petite alimentation stabilisée :
Dans MPLAB, vous savez maintenant créer un projet. Créez donc le projet Led_cli dans
votre répertoire de travail (project->new project). Si vous avez une fenêtre
" untitled " à lécran, fermez-la préalablement.
Editez le nud, noubliez pas de cocher " Default radix :
Dec ". Ajoutez ensuite le nud " Led_cli.asm ". Vous
êtes prêts à commencer.
Noubliez pas bien sûr douvrir votre fichier
" Led_cli.asm " (" file->open ").De nouveau, ce
fichier est disponible en annexe. [ NDLR : Fichiers
exemples ici ]
11.4 Edition du fichier source |
Complétez le cadre den-tête suivant votre désir. Je vous indique ci-dessous un
exemple. Prenez lhabitude de toujours documenter vos programmes. Ce nest pas
un luxe, cest impératif pour une maintenance efficace dans le temps.
;*************************************************************************** |
; PROGRAMME DE CLIGNOTEMENT D'UNE LED CONNECTEE SUR LE PORTA.2 |
; D'UNE PIC16F84. PROGRAMME D'ENTRAINEMENT AU FONCTIONNEMENT |
; DES PICS. |
;*************************************************************************** |
; |
; NOM: LED-CLI |
; Date: 09/02/2001 |
; Version: 1.0 |
; Circuit: Platine d'essais |
; Auteur: Bigonoff |
; |
;*************************************************************************** |
; |
; Fichier requis: P16F84.inc |
; |
;*************************************************************************** |
; |
; Notes: Ce petit programme permet de faire clignoter une LED |
; sur le port A.2 à une fréquence de 1Hz |
; Ce programme fait partie de la leçon 6 des cours |
; |
;*************************************************************************** |
11.5 Choix de la configuration |
Plus bas dans le fichier, vous trouverez ceci :
|
__CONFIG |
_CP_OFF & _WDT_ON & _PWRTE_ON & _HS_OSC |
|
; '__CONFIG' précise les paramètres encodés dans le processeur
au moment de |
; la programmation du processeur. Les définitions sont dans le
fichier include. |
; Voici les valeurs et leurs définitions : |
|
; _CP_ON |
Code protection ON : impossible de relire |
; _CP_OFF |
Code protection OFF |
; _PWRTE_ON |
Timer reset sur power on en service |
; _PWRTE_OFF |
Timer reset hors-service |
; _WDT_ON |
Watch-dog en service |
; _WDT_OFF |
Watch-dog hors service |
; _LP_OSC |
Oscillateur quartz basse consommation |
; _XT_OSC |
Oscillateur quartz moyenne vitesse ou externe |
; _HS_OSC |
Oscillateur quartz grande vitesse |
; _RC_OSC |
Oscillateur à réseau RC |
Jai inclus les commentaires dans le fichier de façon à ce quil soit plus
rapidement modifiables sans devoir recourir au datasheet. Je vais donner un brin
dexplication.
Remarquez quon effectue un AND (&) entre les différentes valeurs, les
niveaux actifs sont donc des niveaux 0
Le premier paramètre précise si votre PIC sera protégée ou non contre la lecture à
la fin de la programmation. Laissez ici ce paramètre sur " CP_OFF " =
non protégée.
Le second paramètre précise si le " chien de garde " (watchdog)
est mis ou non en service. Dans un premier temps, remplacez WDT_ON par WDT_OFF pour le
mettre hors-service.
Ensuite, laissez PWRTE sur ON pour préciser que vous utilisez un reset
" sécurisé ", donc avec un allongement du temps avant démarrage.
Ceci vous met à labri des alimentations un peu lentes à démarrer.
Jexpliquerai ceci plus tard.
Enfin, vient le fonctionnement de loscillateur que vous allez utiliser. Le
tableau 8-1 page 40 donne les valeurs recommandées en fonction des fréquences utilisées
pour une PIC de 10MHz. Retenez que la valeur _HS_OSC convient pour les fréquences
élevées, ce qui est notre cas, puisque nous utilisons la vitesse maximale de notre PIC.
Il est important de ne pas utiliser _RC_OSC si on utilise un quartz. Ce paramètre est
réservé à un fonctionnement par réseau R/C tel que dessiné figure 8-7 page 41.
LE FAIT DUTILISER LE PARAMETRE " RC " AVEC UNE HORLOGE
EXTERNE PEUT ENTRAINER LA DESTRUCTION DE LA PIC.
Même, si en pratique, les PICs sont des composants très solides, évitez de vous
tromper à ce niveau. Et voilà, vous connaissez parfaitement _Config. Vous avez
maintenant la ligne suivante :
|
__CONFIG |
_CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC |
Si vous regardez le tableau 4-2, vous constaterez que ce registre se trouve à
ladresse 0x81, donc dans la banque1. Dans les fichiers include de MPLAB, ce registre
est déclaré avec le nom OPTION_REG. Cest donc ce nom que vous devrez utiliser.
Nous allons le détailler ici. Ce registre est un registre de bits, cest à dire que
chaque bit a un rôle particulier.
Le tableau de la page 16 représente le contenu de ce registre :
b7 : RBPU
Quand ce bit est mis à 0 (actif niveau bas en italique), une résistance de rappel au
+5 volt est placée sur chaque pin du PORTB. Nous verrons dans cette leçon le
fonctionnement du PORTB. Si vous regardez notre schéma, vous constaterez que le
bouton-poussoir connecté sur RB2 place cette pin à la masse si on le presse.
Il nexiste aucune possibilité pour envoyer du +5V dans notre schéma. En
validant cette option, la résistance interne force la pin RB2 à 1 lorsque le bouton
nest pas pressé. Notez que cette option valide les résistance sur toutes les pins
du PORTB. Il nest donc pas possible de choisir certaines résistances en
particulier. De même cette fonction nexiste que pour le PORTB.
Vous constatez donc déjà que tous les ports ne sont pas identiques : il faut y
penser au moment de la conception dun circuit. Dans notre cas, nous mettrons donc
les résistances en service avec b7 = 0
b6 : INTEDG
Donne, dans le cas où on utilise les interruptions sur RB0, le sens de déclenchement
de linterruption. Si b6 = 1, on a interruption si le niveau sur RB0 passe de 0 vers
1. Si b6 = 0, linterruption seffectuera lors de la transition de 1 vers 0.
Comme nous nutilisons pas les interruptions dans cette leçon, nous pouvons
laisser b6 = 0.
b5 : TOCS
Ce bit détermine le fonctionnement du timer0, que nous verrons bientôt. Retenez que
le timer0 est incrémenté soit en fonction de lhorloge interne (synchronisé au
programme) , dans ce cas b5 = 0, soit il compte les impulsions reçues sur la pin RA4,
dans ce cas b5=1.
Comme ce dernier mode nécessite un circuit de génération de pulses externe, nous
utiliserons pour le timer0 lhorloge interne, donc b5 = 0
b4 : TOSE
Donne, pour le cas ou le bit 5 serait 1, le sens de la transition qui détermine le
comptage de tmr0. Si b4 = 1, on a comptage si le signal passe de 5V à 0V sur RA4, si on a
b4 = 0, ce sera le contraire.
Comme nous avons placé b5=0, b4 est alors inutilisé. Nous laisserons donc b4 = 0.
b3 : PSA
Nous avons dans la PIC un prédiviseur. Quest-ce que cest ? Et bien
tout simplement, ceci indique le nombre de pulses qui devra être reçu pour provoquer une
incrémentation de la destination. Nous y reviendrons en détail avec le fonctionnement du
tmr0.
A ce niveau, sachez simplement que ce prédiviseur peut servir à une des deux
fonctions suivantes (et pas les deux) : soit il effectue une prédivision au niveau
du timer du watchdog (b3 = 1), soit il effectue une prédivision au niveau du tmr0
(timer0) (b3=0). Dans notre cas, mettez b3 = 1 (nous verrons ci-dessous pourquoi).
b2, b1,b0 : PS2,PS1,PS0
Ces trois bits déterminent la valeur de prédivision pour le registre déterminé
ci-dessus. Il y a donc 8 valeurs possibles, montrées dans le petit tableau de la page 16.
Remarquez que les valeurs sont différentes pour le watchdog et pour tmr0. En effet, il
ny a pas de division par 1 pour ce dernier registre.
Si vous désirez ne pas utiliser de prédiviseur du tout, la seule méthode est de
mettre b3=1 (prédiviseur sur watchdog) et PS2 à PS0 à 0. Dans ce cas : pas de
prédiviseur sur tmr0, et prédiviseur à 1 sur watchdog, ce qui correspond à pas de
prédiviseur non plus. Nous mettrons donc b2=b1=b0= 0.
11.7 Edition du programme |
Voilà encore un registre vu. Nous utiliserons donc la valeur B00001000
pour notre programme, soit 0x08. Jai lhabitude de ne pas traîner des valeurs
fixes à travers mes programmes, afin den faciliter la maintenance. Je place ces
valeurs en début de programme en utilisant des assignations.
Lassignation est déjà créée plus bas dans le programme. Jai créé une
CONSTANTE que jai appelé OPTIONVAL et qui contiendra la valeur à placer plus tard
dans le registre OPTION_REG. Je rappelle que les CONSTANTES noccupent pas de place
dans la PIC, elles sont simplement remplacées par lassembleur au moment de la
compilation. Elles servent à faciliter la lecture du programme.
Cherchez donc plus bas dans le programme après les assignations, et remplacez la
valeur affectée à OPTIONVAL par celle que nous avons trouvée et ajoutez vos
commentaires. Supprimez lassignation concernant INTERMASK, car nous ne nous
servirons pas des interruptions dans ce premier programme. Dans la zone des assignations,
il vous reste donc ceci :
;********************************************************************* |
; ASSIGNATIONS |
;********************************************************************* |
|
|
|
|
OPTIONVAL |
EQU |
H'0008 |
; Valeur registre option |
|
|
|
; Résistance pull-up ON |
|
|
|
; Pas de préscaler |
Descendons encore jusqu'à la zone des définitions. Nous allons donner un nom à
notre bouton-poussoir et à notre LED. Les instructions bcf et bsf que nous allons
utiliser pour mettre ou lire des 1 ou des 0 dans les registres ont la syntaxe
suivante bsf f , n et comme le registre daccès sappelant PORTA
(pour le port A) et PORTB (pour le port B), nous utiliserons des DEFINE permettant
dintégrer f et n en même temps.
Nous voyons sur le schéma que la LED est connectée sur le bit 2 du port A. Le
bouton-poussoir est connecté sur le bit 2 du port B. Nous effaçons donc les définition
dexemple, et nous les remplaçons par les nôtres. Nous obtenons alors ceci :
;********************************************************************* |
; DEFINE |
;********************************************************************* |
|
|
|
|
#DEFINE |
LED |
PORTA, 2 |
; Led rouge |
#DEFINE |
BOUTON |
PORTB, 2 |
; bouton-poussoir |
Notez que LED et BOUTON sont des noms que nous avons librement choisis, à
condition quil ne sagisse pas dun mot-clé. Pas question par exemple
dutiliser STATUS ou encore MOVLW, bien que ces exemples soient tirés par les
cheveux, cela pourrait vous arriver un jour dutiliser un mot réservé par
inadvertance.
A quoi servent les définitions ? Et bien supposons que vous décidez de connecter
la LED sur le PORTB bit 1 (RB1), par exemple. Et bien, nul besoin de rechercher partout
dans le programme, il suffira de changer dans la zone DEFINE.
On descend encore un peu, et on arrive dans la zone des macros. Nous nen avons
pas vraiment besoin ici, mais nous allons quand même les utiliser à titre
dexemple.
Effacez la macro donnée à titre dexemple et entrons celles-ci :
;********************************************************************* |
; MACRO |
;********************************************************************* |
|
|
|
|
LEDON |
macro |
|
|
|
bsf |
LED |
|
|
endm |
|
|
|
|
|
|
LEDOFF |
macro |
|
|
|
bcf |
LED |
|
|
endm |
|
|
La première colonne donne le nom de la macro (ici, 2 macros, une LEDON et une
LEDOFF). La directive macro signifie début de la macro la directive endm
signifie fin de la macro. Notez que les macros peuvent évidemment comporter
plusieurs lignes de code.
Prenons notre exemple : quand nous utiliserons la ligne suivante dans notre
programme (attention, ne pas mettre la macro en première colonne) :
Au moment de la compilation, notre assembleur remplacera LEDON par :
Il remplacera également LED par PORTA,2. Ce qui fait quen réalité nous
obtiendrons :
Nous avons donc obtenu une facilité décriture et de maintenance. Gardez
à lesprit que les macros sont des simples substitution de traitement de texte. Si
votre macro se compose de 50 lignes de code, les 50 lignes seront copiées dans la PIC à
chaque appel de la macro.
Nous arrivons dans la zone des variables. Nous ajouterons celles-ci au fur et à mesure
de leur nécessité. Effacez donc les 2 variables présentes, car elles sont utilisées
dans les routines dinterruption que nous nutiliserons pas ici.
;********************************************************************* |
; DECLARATIONS DE VARIABLES |
;********************************************************************* |
|
|
|
|
|
CBLOCK |
0x00C |
; début de la zone variables |
|
|
|
|
|
ENDC |
|
; Fin de la zone |
A lORG 0x00, laissons lappel vers la routine dinitialisation.
Tout programme comporte en effet une étape dinitialisation des variables et des
registres. Prenez lhabitude de séparer cette initialisation du reste du programme.
Comme nous nutiliserons pas les interruptions, supprimez tout ce qui suit
jusquà la routine dinitialisation, vous obtenez :
;********************************************************************* |
; DEMARRAGE SUR RESET |
;********************************************************************* |
|
|
|
|
|
org |
0x000 |
; Adresse de départ après reset |
|
goto |
init |
; Adresse 0: initialiser |
|
|
|
|
;********************************************************************* |
; INITIALISATIONS |
;********************************************************************* |
suite du programme
A ce stade, avant de poursuivre, nous allons étudier les registres dont nous allons
nous servir, et tout dabord :
Ce registre est un peu particulier, puisquil donne directement accès au monde
extérieur. Cest en effet ce registre qui représente limage des pins RA0 à
RA4, soit 5 pins. Si vous suivez toujours, cest ce registre qui va servir à allumer
la LED.
Ce registre se situe à ladresse 05H, dans la banque0. Chaque bit de ce registre
représente une pin. Donc, seuls 5 bits sont utilisés. Pour écrire sur une pin en
sortie, on place le bit correspondant à 1 ou à 0, selon le niveau souhaité.
Par exemple :
|
bsf |
PORTA, 1 |
; envoyer niveau 1 sur RA1 |
place un niveau +5V sur la pin RA1. Notez quil faut pour cela que cette pin
soit configurée en sortie (voir TRISA). Pour tester une entrée, on pourra par exemple
utiliser :
|
bsfss |
PORTA, 3 |
; tester RA3 et sauter si vaut 5V |
Pour les électroniciens, vous avez le schéma interne des bits RA0 à RA3 figure
5-1 page 21. Vous voyez que la sortie peut être placée au niveau haut ou bas grâce aux
deux transistors de sortie (montage push-pull). Quand ces pins sont programmées en
entrées, elles sont sensibles à des niveaux TTL.
Pour la pin RA4, figure 5-2, en sortie elle est de type drain ouvert, et en entrée
elle comporte un trigger de Schmitt.
Les PORTS disposent dune diode de protection vers le 0V et vers le 5V. De sorte
quavec une simple résistance série, vous pouvez envoyer des signaux vers ces pins
qui sortent de la gamme de tension TTL. La pin RA4 fait exception à cette règle, car
elle dispose que dune diode vers la masse.
Pour tous, retenez que les pins RA0 à RA3 peuvent être utilisées en entrée avec des
niveaux 0/5V ou en sortie en envoyant du 0V ou du 5V. Quand à la pin RA4, en sortie, elle
ne peut pas envoyer du 5V.
Elle ne peut que mettre la sortie " en lair " sur niveau 1 et
la forcer à la masse sur niveau 0. En entrée, elle comporte un dispositif permettant
dempêcher les hésitations lorsque le niveau présenté nest pas franc. Par
exemple lorsque le niveau varie lentement de 0V à 5V.
Tenez compte de ces spécificités lorsque vous construirez votre montage. Par exemple,
si nous avions placé la LED telle quelle sur RA4, elle ne se serait jamais allumée.
A partir de la page 75, chapitre 11, vous avez les caractéristiques max de
fonctionnement de la pic. Vous pouvez retenir simplement de vous limitez à utiliser 20mA
maximum par pin de sortie, avec un maximum total de 80mA pour le PORTA, et 150mA pour le
PORTB.
Si vous utilisez des caractéristiques proches de cette limite, analysez les tableaux
avec plus de précision pour obtenir les limites en puissance et t°. Nous naurons
pas ce genre de problème dans nos exercices. La consommation de notre LED sur RA2 répond
à la formule suivante :
Intensité : (5V Tension Led) / 330 ohms, soit (5V 1,75V) / 330 ohms
= 9,85mA.
11.8.1 Fonctionnement particulier des PORTS
Les PORTS fonctionnent toujours sur le principe lecture->modification->écriture.
Par exemple, si vous écrivez bsf PORTA,1, la PIC procède de la manière
suivante :
- La totalité du PORTA est lu (même les bits en sortie)
- Le bit 1 est mis à 1
- La totalité du PORTA est réécrit.
Conséquences
supposons par exemple que le RA4 soit en sortie et mis à 1. Comme il est à drain
ouvert, supposons quune électronique externe le force actuellement à 0.
Si vous effectuez lopération suivante :
|
bsf |
PORTA, 1 |
; mettre RA1 à 1 |
Lorsque le PORTA va être lu, RA4 sera lu comme 0, bien quil soit à 1. RA1
sera forcé à 1, et le tout sera replacé dans PORTA. RA4 est donc maintenant à 0, sans
que vous layez modifié.
Cest vrai que ce type de cas nest pas courant, mais il est bon de le
savoir, si un jour une de vos interfaces vous pose problème, et si vous avez
limpression que vos pins en sortie changent de niveau sans que vous le désiriez.
Pour les non-électroniciens, ne paniquez pas, car, de toute façon, vous ne
réaliserez sans doute jamais une interface qui pose ce type de problème. Je tenais
cependant à être exhaustif.
Ce registre est situé à la même adresse que PORTA, mais dans la banque 1. Son
adresse complète sur 8 bits est donc 0x85.
Ce registre est dun fonctionnement très simple et est lié au fonctionnement du
PORTA.
Chaque bit positionné à 1 configure la pin correspondante en entrée. Chaque bit à 0
configure la pin en sortie.
Au reset de la PIC, toutes les pins sont mises en entrée, afin de ne pas envoyer des
signaux non désirés sur les pins. Les bits de TRISA seront donc mis à 1 lors de chaque
reset.
Notez également que, comme il ny a que 5 pins utilisées sur le PORTA, seuls 5
bits (b0/b4) seront utilisés sur TRISA.
Exemple dutilisation
Prenons en exemple le schéma de notre petit circuit : que devons-nous faire pour
allumer la LED ?
PS : ne mettez pas pour linstant ces instructions dans votre projet.
Premièrement, nous devons configurer TRISA et mettre le bit2 (RA2) en sortie.
Comme le registre TRISA se trouve en banque1, et que ladressage DIRECT
nutilise que 7 bits, nous devrons donc commuter le bit RP0 du registre STATUS (voir
chapitres précédents).
Ensuite, nous pourrons envoyer un niveau 1 sur PORTA, correspondant à 5V
sur la pin RA2. La séquence correcte sera donc :
|
bsf |
STATUS , RP0 |
; on passe en banque 1 |
|
bcf |
TRISA , 2 |
; bit 2 de TRISA à 0 = sortie pour RA2 |
|
bcf |
STATUS , RP0 |
; on repasse en banque 0 |
|
bsf |
PORTA , 2 |
; on envoie 5V sur RA2 : la LED sallume |
|
xxx |
|
|
|
xxx |
|
|
|
xxx |
|
|
|
bcf |
PORTA , 2 |
; 0V sur RA2, la LED séteint |
Notez que comme RA2 restera en sortie durant tout le programme (dépend du
schéma), nous placerons la valeur de TRISA dans la routine dinitialisation. Quand
nous voudrons allumer ou éteindre la LED dans le programme principal, nous nauront
donc plus quune seule instruction à utiliser. On commence à entrer dans le
concret .
11.10 Les registres PORTB et TRISB |
Ces registres fonctionnent exactement de la même manière que PORTA et TRISA, mais
concernent bien entendu les 8 pins RB. Tous les bits sont donc utilisés dans ce cas.
Voyons maintenant les particularités du PORTB. Nous en avons déjà vu une, puisque
les entrées du PORTB peuvent être connectées à une résistance de rappel au +5V de
manière interne.
La sélection seffectuant par le bit 7 du registre OPTION. Le schéma interne
visible figures 5-3 et 5-4 page 23 vous montre que les bits b0 et b4/b7 peuvent être
utilisés comme source dinterruption, le bit 0 peut de plus être utilisé de
manière autonome pour générer un autre type dinterruption.
Nous verrons le fonctionnement des interruptions dans un autre chapitre. Sachez
cependant déjà que les schémas que vous concevrez vous-même dans le futur devront
tenir compte des particularités des PORTs.
Note :
Après un reset, vous vous demandez peut-être quel est létat de tel ou tel
registre.
Vous trouverez ces explications dans le tableau de la page 14. Vous voyez
quaprès un reset, le registre OPTION_REG a tous ses bits à 1. Vous devez donc
spécifier leffacement du bit7 pour valider les résistances de rappel au +5V.
|