9.11 Linstruction " 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.
Syntaxe
|
andlw |
k |
; avec k = octet : (w) & k -> (w) |
Bit du registre STATUS affecté
Z
Exemple
|
movlw |
B11001101 |
; charger w |
|
andlw |
B11110000 |
; effectuer un and (&) |
|
b7 |
b6 |
b5 |
b4 |
b3 |
b2 |
b1 |
b0 |
|
1 |
1 |
0 |
0 |
1 |
1 |
0 |
1 |
And |
1 |
1 |
1 |
1 |
0 |
0 |
0 |
0 |
= |
1 |
1 |
0 |
0 |
0 |
0 |
0 |
0 |
Rappelez-vous quon effectue un AND entre chaque bit de même rang. Seuls restent
donc positionnés à 1 les bits dont les 2 opérandes valent 1. Donc, le fait
deffectuer un AND avec la valeur B11110000 MASQUE les bits 0 à 3, et ne
laisse subsister que les bits 4 à 7.
Tant que vous ne jonglerez pas avec lhexadécimal, je vous conseille de toujours
traduire les nombres en binaires pour toutes les instructions concernant les bits.
9.12 Linstruction " ANDWF " (AND W with F) |
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.
Syntaxe
|
andwf |
f , d |
; (f) AND (w) -> (d) |
Bit du registre STATUS affecté
Z
Exemple
|
movlw |
0xC8 |
; charger 0XC8 dans w |
|
movwf |
mavariable |
; sauver dans mavariable |
|
movlw |
0xF0 |
; charger le masque |
|
andwf |
mavariable,f |
; (mavariable) = 0xC0 (on a éliminé le quartet faible). |
9.13 Linstruction " IORLW " (Inclusive OR Literal with
W) |
Et oui, les mêmes instructions, mais pour le OU inclusif. Inclusif signifie simplement
le contraire dexclusif, cest à dire que le bit de résultat vaudra 1 si un
des bits, OU LES DEUX BITS, opérandes =1.
Syntaxe
|
iorlw |
k |
; (w) OR k -> (w) |
Bit du registre STATUS affecté
Z
Exemple
|
movlw |
0xC3 |
; charger 0xC3 dans W |
|
iorlw |
0x0F |
; FORCER les bits 0 à 3 |
|
|
|
; résultat ; (w) = 0xCF |
|
b7 |
b6 |
b5 |
b4 |
b3 |
b2 |
b1 |
b0 |
|
1 |
1 |
0 |
0 |
0 |
0 |
1 |
1 |
OR |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
= |
1 |
1 |
0 |
0 |
1 |
1 |
1 |
1 |
Donc, avec un ou inclusif (OR), on peut FORCER nimporte quel bit à 1 (pour
rappel, avec AND, on peut forcer nimporte quel bit à 0).
9.14 Linstruction " IORWF " (Inclusive OR W with File) |
Effectue un OR entre (w) et lemplacement spécifié. Cest donc une
instruction en ADRESSAGE DIRECT. Je ne donnerais pas dexemple, vous devriez avoir
compris.
Syntaxe
|
iorwf |
f , d |
; (w) OR (f) -> (d) |
Bit du registre STATUS affecté
Z
9.15 Linstruction " 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.
Cette instruction va donc servir à INVERSER nimporte quel bit dun octet.
En effet, si vous effectuez " 1 xor 0 ", vous obtenez 1, si vous
effectuez " 0 xor 0 ", vous obtenez 0. Donc, si vous appliquez xor 0,
la valeur de départ est inchangée.
Si par contre vous appliquez " 0 xor 1 " , vous obtenez 1, et avec
" 1 xor 1 ", vous obtenez 0. En appliquant xor 1, vous inversez le
bit, quelque soit son état initial.
Maintenant, vous pouvez donc FORCER un bit à 1 avec OR, MASQUER un bit (le mettre à
0) avec AND, et lINVERSER avec XOR.
Syntaxe
|
xorlw |
k |
; (w) xor k -> (w) |
Bit du registre STATUS affecté
Z
Exemple
|
movlw |
B11000101 |
; charger W |
|
xorlw |
B00001111 |
; xor avec la valeur |
|
|
|
; résultat : B 11001010 |
|
|
|
; les 4 bits de poids faible ont été inversés |
|
b7 |
b6 |
b5 |
b4 |
b3 |
b2 |
b1 |
b0 |
|
1 |
1 |
0 |
0 |
0 |
1 |
0 |
1 |
xor |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
1 |
= |
1 |
1 |
0 |
0 |
1 |
0 |
1 |
0 |
Remarquez que tous les bits de loctet initial ont été inversés par chaque bit
de la seconde opérande qui étaient à 1.
9.16 Linstruction " XORWF " (eXclusive OR W with F) |
Cest exactement la même opération que XORLW, mais en ADRESSAGE DIRECT.
Syntaxe
|
xorwf |
f , d |
; (w) xor (f) -> (d) |
Bit du registre STATUS affecté
Z
9.17 Linstruction " BSF " (Bit Set F) |
Cest une instruction qui permet tout simplement de forcer directement un bit
dun emplacement mémoire à 1
Syntaxe
|
bsf |
f , b |
; le bit n° b est positionné dans la case mémoire (f) |
|
|
|
; b est évidemment compris entre 0 et 7 |
Bit du registre STATUS affecté
Aucun
Exemples
|
bsf |
STATUS , C |
; positionne le bit C à 1 dans le registre STATUS |
|
bsf |
mavariable , 2 |
; positionne bit 2 de (mavariable) à 1 |
9.18 Linstruction " BCF " (Bit Clear F) |
Cest une instruction qui permet tout simplement de forcer directement un bit
dun emplacement mémoire à 0
Syntaxe
|
bcf |
f , b |
; le bit n° b est mis à 0 dans la case mémoire (f) |
|
|
|
; b est évidemment compris entre 0 et 7 |
Bit du registre STATUS affecté
Aucun
Exemples
|
bcf |
STATUS , C |
; positionne le bit C à 0 dans le registre STATUS |
|
bcf |
mavariable , 2 |
; positionne bit2 de (mavariable) à 0 |
9.19 Linstruction " RLF " ( Rotate Left through Carry) |
Rotation vers la gauche en utilisant le carry.
Les opérations de décalage sont des opérations très souvent utilisées. Les PICs
ont la particularité de ne posséder que des opérations de ROTATION. Vous allez voir
quavec ces opérations, on peut très facilement réaliser des décalages.
Lopération de rotation effectue lopération suivante : Le bit de
carry C est mémorisé. Ensuite chaque bit de loctet est déplacé vers la gauche.
Lancien bit 7 sort de loctet par la gauche, et devient le nouveau carry. Le
nouveau bit 0 devient lancien carry. Il sagit donc dune rotation sur 9
bits.
Syntaxe
|
rlf |
f, d |
; (f) rotation gauche avec carry-> (d) |
Bit du registre STATUS affecté
C
Exemple1
Un petit exemple vaut mieux quun long discours.
|
bsf |
STATUS,C |
; positionne le carry à 1 |
|
movlw |
B00010111 |
; charge la valeur dans w |
|
movwf |
mavariable |
; initialise mavariable |
|
rlf |
mavariable,f |
; rotation vers la gauche |
|
C |
b7 |
b6 |
b5 |
b4 |
b3 |
b2 |
b1 |
b0 |
f |
1 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
rlf |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
Vous voyez que tous les bits ont été décalés vers la gauche.
" C " a été réintroduit dans b0. Le résultat reste sur 9 bits.
Exemple 2
|
bcf |
STATUS,C |
; positionne le carry à 0 |
|
movlw |
B00010111 |
; charge la valeur dans w |
|
movwf |
mavariable |
; initialise mavariable |
|
rlf |
mavariable,f |
; rotation vers la gauche |
Si vous avez compris, le résultat sera B00101110, avec le carry à 0. Si
le carry est à 0 au départ, on effectue un simple décalage vers la gauche. Que se
passe-t-il si, en décimal, on effectue ce type dopération ?
Prenons le nombre 125 et décalons-le vers la gauche en décimal, nous obtenons 1250.
Nous avons multiplié le nombre par sa base. Et bien cest la même chose en binaire
(une fois de plus).
Prenons B00010111 , soit 23 en décimal. Décalons-le, nous obtenons
B00101110, soit 46. Nous avons donc effectué une multiplication par 2.
Retenez ceci, cela vous sera très utile par la suite.
9.20 Linstruction " RRF " ( Rotate Right through
Carry) |
Rotation vers la droite en utilisant le carry
Lopération de rotation vers la droite effectue lopération suivante :
Le bit de carry " C " est mémorisé. Ensuite chaque bit de
loctet est déplacé vers la droite. Lancien bit 0 sort de loctet par la
droite, et devient le nouveau carry. Lancien Carry devient le nouveau bit7. Il
sagit donc également dune rotation sur 9 bits.
Syntaxe
|
rrf |
f, d |
; (f) rotation droite avec carry-> (d) |
Bit du registre STATUS affecté
C
Exemple1
|
bsf |
STATUS,C |
; positionne le carry à 1 |
|
movlw |
B00010111 |
; charge la valeur dans w |
|
movwf |
mavariable |
; initialise mavariable |
|
rrf |
mavariable,f |
; rotation vers la droite |
|
b7 |
b6 |
b5 |
B4 |
b3 |
b2 |
b1 |
b0 |
C |
f |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
1 |
rrf |
1 |
0 |
0 |
0 |
1 |
0 |
1 |
1 |
1 |
Vous voyez que tous les bits ont été décalés vers la droite. C a été réintroduit
dans b7. Le résultat reste sur 9 bits.
Exemple 2
|
bcf |
STATUS,C |
; positionne le carry à 0 |
|
movlw |
B00010111 |
; charge la valeur dans w |
|
movwf |
mavariable |
; initialise mavariable |
|
rrf |
mavariable,f |
; rotation vers la droite |
Si vous avez compris, le résultat sera B00001011, avec le carry à 1.
Si le carry est à 0 au départ, on effectue un simple décalage vers la droite.
Que sest-il passé ? Et bien notre nombre de départ, soit 23 en décimal
est devenu 11. Le carry représente le bit " -1 ", donc, la moitié du
bit 0, donc ½. En effet, en décimal, le chiffre derrière les unités a comme valeur
1/base, donc 1/10. En binaire ce sera donc ½.
Si nous regardons alors les 9 bits, nous obtenons 11 ½ . Nous avons donc effectué une
DIVISION PAR 2. Retenez ceci, cela vous sera également très utile par la suite.
9.21 Linstruction " BTFSC " (Bit Test F, Skip if
Clear) |
Traduit littéralement, cela donne : Teste le bit de lemplacement mémoire
et saute sil vaut 0. Il sagit ici de votre premier SAUT CONDITIONNEL, ou
RUPTURE DE SEQUENCE SYNCHRONE CONDITIONNELLE .
En effet, il ny aura saut que si la condition est remplie. Notez que dans ce cas
linstruction prendra 2 cycles, sinon, elle nutilisera quun cycle. De
plus, il faut retenir que pour tous ces types de saut, ON NE SAUTE QUE lINSTRUCTION
SUIVANTE. En effet, la syntaxe ne contient pas dadresse de saut, comme nous allons
le voir
Syntaxe
|
btfsc |
f, b |
; on teste le bit b de la mémoire (f). |
|
|
|
; si ce bit vaut 0, on saute linstruction suivante, sinon |
|
|
|
; on exécute linstruction suivante. |
|
Instruction exécutée si faux |
; si le bit vaut 0, ne sera pas exécutée (skip) |
|
Poursuite du programme |
; le programme continue ici |
Bit du registre STATUS affecté
Aucun
Exemple1
Voici un exemple dans lequel on doit exécuter une seule instruction supplémentaire si
le bit vaut 1.
|
btfsc |
STATUS,C |
; tester si le bit C du registre STATUS vaut 0 |
|
bsf |
mavariable,2 |
; non (C=1), alors bit 2 de mavariable mis à 1 |
|
xxxx |
|
; la suite du programme est ici dans les 2 cas |
Exemple 2
Que faire si les traitements différent de plus dune instruction ? Et bien,
on combine les sauts conditionnels avec les saut inconditionnels (par exemple goto).
|
movlw |
0x12 |
; charger 12 dans le registre de travail |
|
subwf |
mavariable,f |
; on soustrait 0x12 de mavariable |
|
btfsc |
STATUS,C |
; on teste si le résultat est négatif (C=0) |
|
goto |
positif |
; non, alors au saute au traitement des positifs |
|
xxxx |
|
; on poursuit ici si le résultat est négatif |
Ces procédures sont les mêmes pour tous les sauts inconditionnels, je ne les
détaillerai donc pas avec autant dexplications.
9.22 Linstruction " BTFSS " (Bit Test F, Skip if Set) |
Traduit littéralement, cela donne : Teste le bit de lemplacement mémoire
et saute sil vaut 1. Toutes les remarques de linstruction
" BTFSC " restent valables.
Syntaxe
|
btfss |
f, b |
; on teste le bit b de la mémoire (f). |
|
|
|
; si ce bit vaut 1, on saute linstruction suivante, sinon |
|
|
|
; on exécute linstruction suivante. |
|
Instruction exécutée si faux |
; si le bit vaut 0, ne sera pas exécutée (skip) |
|
Poursuite du programme |
; le programme continue ici |
Bit du registre STATUS affecté
Aucun
Exemple
|
btfss |
STATUS,C |
; tester si le bit C du registre STATUS vaut 1 |
|
bsf |
mavariable,2 |
; non (C=0), alors bit 2 de mavariable mis à 1 |
|
xxxx |
|
; la suite du programme est ici dans les 2 cas |
9.23 Linstruction " DECFSZ " (DECrement F, Skip if Z) |
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
linstruction suivante si le résultat de la décrémentation donne une valeur nulle.
Syntaxe
|
decfsz |
f, d |
; (f) 1 -> (d). Saut si (d) = 0 |
Bit du registre STATUS affecté
Aucun
Exemple1
|
movlw |
3 |
; charger 3 dans w |
|
movwf |
compteur |
; initialiser compteur |
|
movlw |
0x5 |
; charger 5 dans w |
boucle |
|
|
; étiquette |
|
addwf |
mavariable , f |
; ajouter 5 à ma variable |
|
decfsz |
compteur , f |
; décrémenter compteur et tester sa valeur |
|
goto |
boucle |
; si compteur pas 0, on boucle |
|
movf |
mavariable , w |
; on charge la valeur obtenue dans w |
Comment écrit-on ce type de programme ? Et bien tout simplement de la manière
suivante :
- on initialise les compteur de boucles.
- on place une étiquette de début de boucle
- on écrit les instructions qui doivent sexécuter plusieurs fois
- linstruction decfsz permet de déterminer la fin des boucles
- linstruction goto permet de localiser le début de la boucle.
ATTENTION
- Si vous aviez mis :
|
decfsz |
compteur , w |
; décrémenter compteur et tester sa valeur |
la boucle naurait jamais de fin, car la variable compteur ne serait jamais
modifiée.
- Si vous placez 0 dans le compteur de boucles, la boucle sera exécutée 256 fois. Si
vous ne désirez pas que la boucle soit exécutée dans ce cas, vous devez ajouter un test
AVANT lexécution de la première boucle, comme dans lexemple suivant :
Exemple 2
|
movf |
compteur,f |
; permet de positionner Z |
|
btfsc |
STATUS , Z |
; sauter si Z = 0, donc si compteur >0 |
|
goto |
suite |
; compteur = 0, ne pas traiter la boucle |
boucle |
|
|
; étiquette de début de boucle |
|
addwf |
mavariable , f |
; ajouter 5 à ma variable |
|
decfsz |
compteur , f |
; décrémenter compteur et tester sa valeur |
|
goto |
boucle |
; si compteur pas 0, on boucle |
suite |
|
|
; on saute directement ici si compteur = 0 |
|
movf |
mavariable , w |
; on charge la valeur obtenue dans w |
9.24 Linstruction " INCFSZ " (INCrement F, Skip if
Zero) |
Je ne vais pas détailler cette instruction, car elle est strictement identique à la
précédente, hormis le fait quon incrémente la variable au lieu de la
décrémenter.
Syntaxe :
|
incfsz |
f , d |
; (f) + 1 -> (d) : saut si (d) = 0 |
Bit du registre STATUS affecté
Aucun
|