Les périphériques internes
Comme évoqué plus haut, un microcontrôleur dispose de périphériques internes.
Voici la liste de ce que j’ai pu traduire :
16 Entrées / Sorties configurables
Un Timer0 de 8 bits avec un pré-diviseur
Un Timer1 de 16 bits
Un Timer2 de 8 bits avec pré-diviseur et post-diviseur
Un module USART (Universal Synchronous/Asynchronous Receiver / Transmitter)
Un module Capture / Compare / PWM
012.jpg
Les ports A et B
Les ports A et B représentent les organes de commandes ainsi que les organes de puissances.
Il ne faut pas se dire que le A est la commande et le B la puissance, ça n'a rien à voir. Si il y a deux ports, c'est surement pour une raison électronique très compliquée.
Le port A dispose de 8 I/O, de RA0 à RA7.
Le port B dispose de 8 I/O, de RB0 à RB7.
C'est troublant car on voit que les pattes de ces I/O ont plusieurs noms, comme par exemple RA6 et RA7 qui portent aussi le nom de OSC1 et OSC2...
En fait, il faut se souvenir que ces pattes sont configurables via un registre et que leur fonction change suivant les périphériques internes que l'on utilise.
Sur ce montage, je vous fait utiliser un Quart 4Mhz qui se branche sur OSC1 et OSC2. Le Quartz introduit dans le montage une notion de temps et vous permet de cadencer un cycle (via le timer). Le fait d'utiliser la fonction Timer me retire donc la possibilité d'utiliser RA6 et RA7.
Pour résumer ça, il faut se dire qu'avec le montage le plus simple, nous disposons de 16 I/O (port A et B), plus nous utilisons de périphériques internes, moins nous disposons d'I/O pour le reste du montage.
Comment placer une I/O en mode O (Output / Sortie) ?
Prenons par exemple le port A qui contient 8 I/O (8 I/O, comme un octet?, oui c'est ça ^^)
Pour le configurer, nous devons utiliser le registre TRISA qui permet de choisir le mode I ou O d'une patte RA.
Le registre TRISA contient donc 8 bits comme le nombre d'I/O du port A, chaque bit représente l'état I ou O d'une patte RA. Si je met un bit à 1, la patte concernée va passer en mode I (Entrée pour la commande), si le bit concerné est à 0, la patte sera une sortie(Sortie pour la puissance)
Rappelez vous que le registre W est omniprésent.
La bonne marche à suivre pour assigner la fonction du port A doit ressembler à ça :
- Je met un octet dans W (par exemple 0 0 0 0 0 0 0 0)
- Je place le contenu de W dans TRISA
Ici, tous les bits sont à 0 donc, toutes les pattes du port A seront des sorties.
- Je met un octet dans W (par exemple 1 0 0 1 0 0 1 0)
- Je place le contenu de W dans TRISA
Ici, RA0 sera une sortie, RA1 sera une entrée, RA2, RA3 seront des sorties, RA4 sera une entrée, RA5 et RA6 seront des sorties et RA7 sera une entrée.
On commence à capter l'utilité d'un registre non ? Il faut car tout marche comme ça dans le monde des microcontrôleurs.
Voilà pour les ports A et B, ça sera plus concret quand vous allez allumer et éteindre vos 3 voyants en modifiant le registre TRISB (car sur mon schéma, les voyants sont sur RB1, RB2 et RB3)
- Je met un octet dans W (par exemple 1 1 1 1 0 0 0 1)
- Je place le contenu de W dans TRISB
Ici, RB1, RB2 et RB3 sont placés en mode Output.
- Je met un octet dans W (par exemple 0 0 0 0 0 0 0 0)
- Je place le contenu de W dans PORTB
Les 3 voyants sont éteints
- Je met un octet dans W (par exemple 0 0 0 0 1 0 1 0)
- Je place le contenu de W dans PORTB
Ici, RB1, RB2 et RB3 sont TOUJOURS en mode Output (puisque c'est TRISB qui gère ça)
Par contre, le voyant RB1 sera allumé, le voyant RB2 sera éteint, le voyant RB3 sera allumé.
En résumé, on utilise toujours le registre W pour manipuler quelque chose. Le registre TRISA et TRISB servent à définir le mode I ou O des pattes RA et RB. Le registre PORTA et PORTB servent à définir l'état (présence de tension ou absence de tension) des pattes RA et RB.
N’oubliez pas qu’il va falloir changer de banque car si on reprend le schéma de l’organisation de la mémoire, on voit que TRISA et TRISB sont en banque 1 et que PORTA et PORTB sont en banque 0.
Les Timers
Le Timer 0 est un compteur sur 8 bits. Il peut être utilisé en mode Compteur ou en mode Timer.
En premier lieu, vous pouvez compter les impulsions reçues sur la pin RA4/TOKI. Nous dirons dans ce cas que nous sommes en mode compteur.
Vous pouvez aussi décider de compter les cycles d’horloge du PIC® lui-même. Dans ce cas, comme l’horloge est fixe, nous compterons donc en réalité du temps. Donc, nous serons en mode « timer ».
La sélection d’un ou l’autre de ces deux modes de fonctionnement s’effectue par le bit 5 du registre OPTION : T0CS pour Tmr0 Clock Source select bit.
T0CS = 1 : Fonctionnement en mode compteur.
T0CS = 0 : Fonctionnement en mode timer.
Le Timer 1 est un compteur sur 16 bits, le Timer 2 est un compteur sur 8 bits. Chaque Timer possède des caractéristiques particulières mais on ne va pas les utiliser tout de suite.
Le module USART
USART signifie « Universal Synchronous Asynchronous Receiver Transmitter ». C’est donc un module qui permet d’envoyer et de recevoir des données en mode série, soit de façon synchrone, soit asynchrone. Dans certaines littératures, vous retrouverez également le terme générique de SCI pour « Serial Communications Interface ».
Il permet donc de communiquer avec d’autres composants de notre montage, pour notre application, on va utiliser un MAX232 ou un HIN232 pour relier notre montage à un ordinateur.
Voici un aperçu des quatre modes disponible :
- Mode asynchrone full duplex : émission sur TX et réception sur RX
- Mode asynchrone half-duplex sur 2 lignes (TX et RX) ou sur une ligne (TX/RX reliées)
- Mode synchrone maître : émission horloge sur CK et émission/réception données sur DT
- Mode synchrone esclave : réception horloge sur CK et émission/réception données sur DT
Le module Capture / Compare / PWM
Ici c’est encore un peu complexe pour moi, on va tenter d’utiliser le mode PWM pour moduler un signal et ainsi utiliser des composants externes qui acceptent ce signal comme par exemple certains petits extracteurs ou encore un driver LED.
Le jeu d'instructions
goto (
Aller à) :
Cette instruction effectue ce qu’on appelle un saut inconditionnel, encore appelé rupture de séquence synchrone inconditionnelle.
incf (
INCrement File) :
Cette instruction provoque l’incrémentation de l’emplacement spécifié (encore appelé File).
decf (
DECrement File) :
Decrémente l’emplacement spécifié. Le fonctionnement est strictement identique à l’instruction précédente.
movlw (
MOVe Literal to W) :
Cette instruction charge la valeur spécifiée (valeur littérale, ou encore valeur immédiate), dans le registre de travail W.
movf (
MOVe File) :
Charge le contenu de l’emplacement spécifié dans la destination.
movwf (
MOVe W to File) :
Permet de sauvegarder le contenu du registre de travail W dans un emplacement mémoire.
addlw (
ADD Literal and W) :
Cette opération permet d’ajouter une valeur littérale (adressage immédiat) au contenu du registre de travail W.
addwf (
ADD W and File) :
Ne pas confondre avec l’instruction précédente. Une nouvelle fois, il s’agit ici d’un ADRESSAGE DIRECT. Le CONTENU du registre W est ajouté au CONTENU du registre F.
sublw (
SUBtract W from Literal) :
Attention, ici il y a un piège. L’instruction aurait du s’appeler SUBWL. En effet, on soustrait W de la valeur littérale, et pas l’inverse.
subwf (
SUBtract W from File) :
Nous restons dans les soustractions, mais, cette fois, au lieu d’un adressage immédiat, nous avons un ADRESSAGE DIRECT.
andlw (
AND Literal with W) :
Cette instruction effectue une opération « AND » BIT A BIT entre le contenu de W et la valeur littérale qui suit.
andwf (
AND W with File) :
Maintenant, vous devriez avoir bien compris. De nouveau la même opération, mais en ADRESSAGE DIRECT. Je vais donc accélérer les explications.
iorlw (
Inclusive OR Literal with W) :
Et oui, les mêmes instructions, mais pour le OU inclusif. Inclusif signifie simplement le contraire d’exclusif, c’est à dire que le bit de résultat vaudra 1 si un des bits, OU LES DEUX BITS, opérandes =1.
iorwf (
Inclusive OR W with File) :
Effectue un OR entre (w) et l’emplacement spécifié. C’est donc une instruction en ADRESSAGE DIRECT.
xorlw (
eXclusive OR Literal with W) :
Par opposition au ou inclusif, voici maintenant le OU EXCLUSIF. Sa table de vérité est la même que le ou inclusif, excepté que lorsque les 2 bits sont à 1, le résultat est 0.
xorwf (
eXclusive OR W with File) :
C’est exactement la même opération que XORLW, mais en ADRESSAGE DIRECT.
bsf (
Bit Set File) :
C’est une instruction qui permet tout simplement de forcer directement un bit d’un emplacement mémoire à 1.
bcf (
Bit Clear File) :
C’est une instruction qui permet tout simplement de forcer directement un bit d’un emplacement mémoire à 0.
rlf (
Rotate Left through carry to File) :
Rotation vers la gauche en utilisant le carry.Les opérations de décalage sont des opérations très souvent utilisées. Les PIC® ont la particularité de ne disposer que d’instructions de ROTATION. Vous allez voir qu’avec ces instructions, on peut très facilement réaliser des décalages.
L’opération de rotation effectue l’opération suivante : Le bit de carry C est mémorisé. Ensuite chaque bit de l’octet est déplacé vers la gauche. L’ancien bit 7 sort de l’octet par la gauche, et devient le nouveau carry. Le nouveau bit 0 devient l’ancien carry. Il s’agit donc d’une rotation sur 9 bits.
rrf (
Rotate Right through carry to File) :
Rotation vers la droite en utilisant le carry. L’opération de rotation vers la droite effectue l’opération suivante : Le bit de carry « C » est mémorisé. Ensuite chaque bit de l’octet est déplacé vers la droite. L’ancien bit 0 sort de l’octet par la droite, et devient le nouveau carry. L’ancien carry devient le nouveau bit7. Il s’agit donc également d’une rotation sur 9 bits.
btfsc (
Bit Test File, Skip if Clean) :
Traduit littéralement, cela donne : Teste le bit de l’emplacement mémoire et saute s’il vaut 0. Il s’agit ici de votre premier SAUT CONDITIONNEL, ou RUPTURE DE SEQUENCE SYNCHRONE CONDITIONNELLE .
btfss (
Bit Test File, Skip if Set) :
Traduit littéralement, cela donne : Teste le bit de l’emplacement mémoire et saute s’il vaut 1. Toutes les remarques de l’instruction « BTFSC » restent valables.
decfsz (
DECrement File, Skip if Zero) :
Nous poursuivons les sauts conditionnels avec une instruction très utilisée pour créer des boucles. Cette instruction décrémente un emplacement mémoire et saute l’instruction suivante si le résultat de la décrémentation donne une valeur nulle.
incfz (
INCrement File, Skip if Zero) :
Je ne vais pas détailler cette instruction, car elle est strictement identique à la précédente, hormis le fait qu’on incrémente la variable au lieu de la décrémenter.
swapf (
SWAP nibbles in File) :
Nous pouvons traduire cette instruction par «inverser les quartets dans F ». Cette opération inverse simplement le quartet (demi-octet) de poids faible avec celui de poids fort.
call (
CALL subroutine) :
Cette opération effectue un saut inconditionnel vers un sous-programme.
Voyons ce qu’est un sous-programme. Et bien, il s’agit tout simplement d’une partie de programme qui peut être appelé depuis plusieurs endroits du programme dit « principal ».
Le point de départ est mémorisé automatiquement, de sorte qu’après l’exécution du sous-programme, le programme continue depuis l’endroit où il était arrivé. Cela paraît un peu ardu, mais c’est extrêmement simple.
return (
RETURN from subroutine) :
Retour de sous-routine. Va toujours de pair avec une instruction call. Cette instruction indique la fin de la portion de programme considérée comme sous-routine (SR). Rappelez-vous que pour chaque instruction « call » rencontrée, votre programme devra rencontrer une instruction « return ».
retlw (
RETurn with Literal to W) :
Retour de sous-routine avec valeur littérale dans W.
C’est une instruction très simple : elle équivaut à l’instruction return, mais permet de sortir d’une sous-routine avec une valeur spécifiée dans W.
retfie (
RETurn From IntErrupt) :
Cette instruction indique un retour d’interruption (nous verrons ultérieurement ce que sont les interruptions). Cette instruction agit d’une manière identique à RETURN, excepté que les interruptions sont remises automatiquement en service au moment du retour au programme principal.
clrf (
CLeaR File) :
Cette instruction efface l’emplacement mémoire spécifié.
clrw (
CLeaR W) :
Cette instruction efface W.
clrwdt (
CLeaR WatchDog Timer) :
Remet à 0 le chien de garde (watchdog) de votre programme. Nous aborderons la mise en oeuvre du watchdog ultérieurement. Sachez cependant que c’est un mécanisme très pratique qui permet de provoquer un reset automatique de votre PIC® en cas de plantage du programme (parasite par exemple).
comf (
COMplemente File) :
Effectue le complément à 1 de l’emplacement mémoire spécifié. Donc, inverse tous les bits de l’octet désigné.
nop (
No OPeration) :
Comme vous devez être fatigué, et moi aussi, je vous présente l’instruction qui ne fait rien, qui ne positionne rien, et qui ne modifie rien. On pourrait croire qu’elle ne sert à rien. En fait elle est surtout utilisée pour perdre du temps, par exemple pour attendre une ou deux instructions, le temps qu’une acquisition ai pu se faire, par exemple. Nous l’utiliserons donc à l’occasion.
sleep (
Mise en sommeil) :
Place le PIC® en mode de sommeil. Il ne se réveillera que sous certaines conditions que nous verrons plus tard.