<< The Fribotte Homepage >>
Un club de passionnés en robotique participant à la coupe de France E=M6.
[Accueil] [Qui sommes-nous ?] [Robots] [Coupe e=m6] [BD Technique] [Forum] [Reportages] [Liens] [WiKiFri]

Fribotte

 

La Programmation des pics
par Bigonoff
Premiere partie - pic 16f84 - Révision 4

Téléchargement des fichiers originels ici
Publié le 26/10/2001

9. Le jeu d’instructions

Index coursIndex du cours
Chapitre précédent8. La simulation d’un programme (Suite)
Chapitre suivant9. Le jeu d’instructions (Suite 1)

 

9. Le jeu d’instructions

Les instructions sont détaillées à partir de la page 57 du datasheet. Il peut donc sembler inutile de les reprendre dans ce cours. Mais j’ai finalement opté pour une explication pratique de ces instructions. J’ai choisi en effet de les expliquer avec des petits exemples concrets, plutôt que de simplement traduire le datasheet.

Bien entendu, vous pouvez expérimenter ces instructions avec MPLAB et son simulateur, en insérant ces instructions après l’étiquette " start " de votre programme.

Je vais donc expliquer ces instructions dans un ordre qui me facilite les explications, en commençant par celles déjà vues, dans le but final d’obtenir toutes les références aux instructions dans le même document.

9.1 L’instruction " GOTO " (aller à)

Cette instruction effectue ce qu’on appelle un saut inconditionnel, encore appelé rupture de séquence synchrone inconditionnel.

Rappelez-vous que l’instruction goto contient les 11 bits de l’emplacement de destination. Les 2 bits restants sont chargés depuis le registre PCLATH. Rappelez-vous en effet la manière dont est construit le PC dans le cas des sauts. On ne peut sauter qu’à l’intérieur d’une même PAGE de 211, soit 2048 Kmots.

Ceci n’a aucune espèce d’importance pour la 16F84, qui ne dispose que de 1Kmots de mémoire programme, mais devra être considéré pour les pics de plus grande capacité (16F876). Nous en reparlerons à ce moment.

Voici donc en résumé le fonctionnement du goto :

  • L’adresse de saut sur 11 bits est chargée dans le PC.
  • Les 2 bits manquants sont chargés depuis PCLATH (b3 et b4), pas pour la 16F84.
  • Le résultat donne l’adresse sur 13 bits (10 bits pour la 16F84)
  • La suite du programme s’effectue à la nouvelle adresse du PC.

Souvenez-vous, que pour la 16F84 : Adresse de saut = adresse réelle. Vous ne devez donc vous préoccuper de rien. Pour les autres, en cas de débordement, MPLAB vous le signalera.

Syntaxe

  goto etiquette  

Exemple :

Start      
  goto plusloin ; le programme saute à l’instruction qui suit l’étiquette
  xxxx xxxx ; plusloin
  xxxx xxxx  
plusloin      
  xxxx xxxx ; instruction exécutée après le saut : le programme se poursuit ici

Remarquez que vous pouvez sauter en avant ou en arrière.

goto nécessite 2 cycles d’horloge, comme pour tous les sauts

9.2 L’instruction " INCF " (INCrement File)

Cette instruction provoque l’incrémentation de l’emplacement spécifié (encore appelé File).

Syntaxe

  incf f,d  

Comme pour toutes les instructions, f représente File, c’est à dire l’emplacement mémoire concerné pour cette opération. d représente la Destination. Sauf spécification contraire, d vaut toujours, au choix :

  • F (la lettre f) : dans ce cas le résultat est stocké dans l’emplacement mémoire.
  • W (la lettre w) : dans ce cas, le résultat est laissé dans le registre de travail, et le contenu de l’emplacement mémoire n’est pas modifié.

La formule est donc (f) + 1 -> (d) : Les parenthèses signifient " le contenu de "

Bit du registre STATUS affecté

Le seul bit affecté par cette opération est le bit Z.

Etant donné que la seule manière, en incrémentant un octet, d’obtenir 0, est de passer de 0xFF à 0x00. Le report n’est pas nécessaire, puisqu’il va de soi. Si, après une incrémentation, vous obtenez Z=1 , c’est que vous avez débordé. Z vaudra donc 1 si (f) avant l’exécution valait 0xFF.

Exemples

  incf mavariable , f ; le contenu de ma variable est augmenté de 1
      ; le résultat est stocké dans mavariable.
  incf mavariable , w ; Le contenu de mavariable est chargé dans w et
      ; augmenté de 1. W contient donc le contenu de
      ; mavariable + 1. mavariable n’est pas modifié

 

9.3 L’instruction " DECF " (DECRement File)

Decrémente l’emplacement spécifié. Le fonctionnement est strictement identique à l’instruction précédente.

Syntaxe

  decf f,d ; (f) – 1 -> (d)

Bit du registre STATUS affecté

Le seul bit affecté par cette opération est le bit Z.

Si avant l’instruction, (f) vaut 1, Z vaudra 1 après l’exécution (1-1 = 0)

Exemples

  decf mavariable , f ; décrémente mavariable, résultat dans mavariable
  decf mavariable , w ; prends (mavariable) – 1 et place le résultat dans w

 

9.4 L’instruction " 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.

Syntaxe

  movlw k ; k représente une valeur de 0x00 à 0xFF.

Bit du registre STATUS affecté

Aucun ( donc même si vous chargez la valeur ‘0’.)

Exemple

  movlw 0x25 ; charge 0x25 dans le registre w

 

9.5 L’instruction " MOVF " (MOVe File)

Charge le contenu de l’emplacement spécifié dans la destination

Syntaxe

  movf f , d ; (f) -> (d)

Bit du registre STATUS affecté

Une fois de plus, seul le bit Z est affecté (si f vaut 0, Z vaut 1).

Exemple 1

Pour cette instruction, je vais me montrer beaucoup plus explicite. Vous allez comprendre pourquoi

  movf mavariable,w ; charge le contenu de mavariable dans w.

ATTENTION

Il est impératif ici de bien faire la distinction entre movlw k et movf f,w. Dans le premier cas, c’est la VALEUR qui est chargée dans w, dans le second c’est le CONTENU de l’emplacement spécifié. Si nous nous rappelons, dans la leçon précédente que mavariable représentait l’adresse 0x0E de notre zone de RAM. Supposons maintenant que mavariable contienne 0x50.

Si nous exécutons l’instruction suivante :

  movlw mavariable  

L’assembleur va traduire en remplaçant mavariable par sa VALEUR. Attention, la valeur, ce n’est pas le contenu. L’assembleur va donc réaliser la substitution suivante :

  movlw 0x0E  

Après l’instruction, nous aurons 0x0E dans le registre W. Nous parlerons dans ce cas d’un ADRESSAGE IMMEDIAT. Le déroulement est du type f -> (d) (f n’est pas entre parenthèses).

Si nous exécutons par contre l’instruction suivante :

  movf mavariable , w  

L’assembleur va traduire également en remplaçant mavariable par sa valeur. Nous obtenons donc :

  movf 0x0E , w  

Ce qui signifie : charger le CONTENU de l’emplacement 0x0E dans w. Nous parlerons ici d’un ADRESSAGE DIRECT. Je rappelle qu’il est primordial de ne pas confondre, sinon, vous ne comprendrez plus rien lors de la réalisation des programmes. Après cette instruction, W contient donc 0x50. Le déroulement est du type (f) -> (d).

Exemple 2

  movf mavariable , f  

Que fait cette instruction ? Si vous avez tout suivi, elle place le CONTENU de mavariable dans mavariable. Dire que cela ne sert à rien est tentant mais prématuré.

En effet, si le contenu de mavariable reste bien inchangé, par contre le bit Z est positionné. Cette instruction permet donc de vérifier si (mavariable) = 0.

9.6 L’instruction " Movwf " (MOVe W to File)

Permet de sauvegarder le contenu du registre de travail W dans un emplacement mémoire.

Syntaxe

  movwf f ; (W) -> (f)

Bit du registre STATUS affecté

Aucun

Exemple

  movlw 0x50 ; charge 0x50 dans W
  movwf mavariable ; ma variable contient maintenant 0x50.

 

9.7 L’instruction " 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.

Syntaxe

  addlw k ; (W) + k -> (W)


Bits du registre STATUS affectés

  • Z Si le résultat de l’opération vaut 0, Z vaudra 1
  • C Si le résultat de l’opération est supérieur à 0xFF (255) , C vaudra 1
  • DC Si le résultat de l’opération entraîne en report du bit 3 vers le bit 4, DC vaudra 1
    Ne vous inquiétez pas trop pour DC, il n’est utilisé que pour les opérations sur les quartets, par exemple, les nombres Binary Coded Decimal

Exemple

  movlw 253 ; charger 253 en décimal dans W
  addlw 4 ; Ajouter 4. W contient 1, Z vaut 0, C vaut 1(déborde)
  addlw 255 ; ajouter 255 W vaut 0, C vaut 1, Z vaut 1

 

9.8 L’instruction " ADDWF " (ADD W and F)

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

Syntaxe

  addwf f , d ; (w) + (f) -> (d)

Bits du registre STATUS affectés

C, DC, et Z

Exemple

  movlw 12 ; charger 12 dans W
  movwf mavariable ; mavariable vaut maintenant 12
  movlw 25 ; charger 25 dans W
  addwf mavariable,f ; résultat : (W) + (mavariable), donc 25+12
      ; résultat = 37 sauvé dans mavariable (,f)

 

9.9 L’instruction " 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.

Syntaxe

  sublw k ; k – (W) -> (W)

Bits du registre STATUS affectés

C, DC, Z

Notez ici que le bit C fonctionne de manière inverse que pour l’addition. Ceci est commun à la plupart des microprocesseurs du marché.

Si le résultat est positif, donc, pas de débordement : C =1. S’ il y a débordement, C devient 0.

Ceci est logique, et s’explique en faisant une soustraction manuelle. Le bit C représente le 9ème bit ajouté d’office à la valeur initiale. Si on effectue une soustraction manuelle donnant une valeur <0, on obtient donc une valeur finale sur 8 bits, le report obtenu venant soustraire le bit C. Si le résultat est >0, il n’y a pas de report, le résultat final reste donc sur 9 bits. La formule de la soustraction est donc : k précédé d’un neuvième bit à 1 – contenu de W = résultat sur 8 bits dans W avec 9ème bit dans C.

Exemple 1

  movlw 0x01 ; charger 0x01 dans W
  sublw 0x02 ; soustraire W de 2
      ; résultat : 2 – (W) = 2-1 = 1
      ; Z = 0, C = 1, donc résultat positif

Effectuons cette opération manuellement :

 

C

b7

b6

b5

b4

b3

b2

b1

b0

Dec

 

1

0

0

0

0

0

0

1

010

2

-

0

0

0

0

0

0

0

01

1

1

=

1

0

0

0

0

0

0

0

1

1

 

Comment procéder ? Et bien, comme pour une soustraction décimale. On commence par les bits de droite : 0-1, ça ne passe pas, donc on emprunte 10 (noté en exposant vert), et on soustraira évidemment une unité supplémentaire au bit b1. On a donc :B ‘10’ – B’1’, car souvenez-vous qu’on a emprunter 10 en BINAIRE. Résultat 1. On soustrait ensuite les b1 : on aura 1 – 0 – l’emprunt, donc 1-0-1 = 0. On continue de droite à gauche jusqu’au 9ème bit qui est le carry. Résultat final : B’00000001’ et carry à 1, cqfd.

Exemple 2

  movlw 0x02 ; charger 0x02 dans W
  sublw 0x02 ; soustraire 2 – (w) = 2 –2 = 0
      ; Z = 1 , C = 1 : résultat nul

 

 

C

b7

b6

b5

b4

b3

b2

b1

b0

Dec

 

1

0

0

0

0

0

0

1

0

2

-

0

0

0

0

0

0

0

1

0

2

=

1

0

0

0

0

0

0

0

0

0

 

On procède toujours de la même manière.

Exemple 3

  movlw 0x03 ; charger 0x03 dans W
  sublw 0x02 ; soustraire 2 – (W) = 2 – 3 = -1
      ; Z = 0, C = 0, résultat négatif

 

 

C

b7

b6

b5

b4

b3

b2

b1

b0

Dec

 

1

010

010

010

010

010

010

110

010

2

-

01

01

01

01

01

01

01

11

1

3

=

0

1

1

1

1

1

1

1

1

-1

 

Procédons de la même manière, et nous obtenons B’11111111’, avec le bit C à 0. Et là, me dites-vous, B’11111111’, c’est FF, pas –1. Et bien, rappelez-vous ceci : Vous DEVEZ lire le bit C pour interpréter le résultat de votre soustraction.

Comme ce dernier vaut 0, vous êtes AVERTIS que le résultat de l’opération est négatif. Or, comment savoir la valeur absolue d’un nombre négatif ? En prenant son complément à 2. Rappelez-vous :

Complément à 1 de B’11111111’ = B’00000000’ (on inverse tous les bits)
Complément à 2 = complément à 1 + 1, donc B’00000001’.
Donc, le complément à 2 de 0xFF vaut –0x01. cqfd.

La preuve, si vous ajoutez 1 à –1, vous obtenez B’11111111’ + B’00000001’ = B’00000000’ = 0.

Vous maîtrisez maintenant les soustractions. Certains auront sans doute pensé que j’expliquais trop en détail, mais mon expérience m’a appris que les soustractions représentaient souvent un écueil dans la réalisation de trop de programmes.

Encore un dernier détail : Pour effectuer une soustraction de 1, vous pouvez bien entendu effectuer une addition de –1. Le résultat sera strictement le même, à votre charge d’interpréter les bits Z et C. Je vous laisse le faire vous-même pour vous convaincre.

9.10 L’instruction " SUBWF " (SUBtract W from F)

Nous restons dans les soustractions, mais, cette fois, au lieu d’un adressage immédiat, nous avons un ADRESSAGE DIRECT.

Syntaxe

  subwf f , d ; (f) – (W) -> (d)

 

Bits du registre STATUS affectés

C , DC , Z

Exemple

  movlw 0x20 ; charger 0x20 dans w
  movwf mavariable ; mettre w dans (mavariable) (0x20)
  movlw 0x1F ; charger 0x1F dans w
  subwf mavariable,w ; (mavariable) - (w) -> (w)
      ; 0x20 – 0x1F = 0x01
      ; résultat dans w, C=1, Z=0
  movwf autrevariable ; sauver 0x01 dans une autre variable

 

 

Index cours
Index du cours
Chapitre précédent
8. La simulation d’un programme (Suite)
Chapitre suivant
9. Le jeu d’instructions (Suite 1)

 


Complétez cette page, posez vos questions et remarques ici : WiKiFri

Page http://fribotte.free.fr/bdtech/cours/pic16f84/PART1_cours09a.html modifiée le 14/10/2002.
Copyright fribotte@free.fr, libre de droit pour toute utilisation non commerciale.
Reproduction autorisée par simple mail