Utiliser les PIC 16F et 18F/Les sous-programmes en assembleur

Leçons de niveau 15
Une page de Wikiversité, la communauté pédagogique libre.
Début de la boite de navigation du chapitre
Les sous-programmes en assembleur
Icône de la faculté
Chapitre no 5
Leçon : Utiliser les PIC 16F et 18F
Chap. préc. :Les structures de contrôle et l'Arithmétique en assembleur
Chap. suiv. :Introduction au langage C

Exercices :

Les sous-programmes en assembleur
fin de la boite de navigation du chapitre
En raison de limitations techniques, la typographie souhaitable du titre, « Utiliser les PIC 16F et 18F : Les sous-programmes en assembleur
Utiliser les PIC 16F et 18F/Les sous-programmes en assembleur
 », n'a pu être restituée correctement ci-dessus.

Les sous-programmes[modifier | modifier le wikicode]

Le sous-programme est la brique de base pour la construction de programmes lisibles. Ils servent :

  • à regrouper un ensemble d'instructions pour leur donner un nom explicite
  • à regrouper des instructions qui font un calcul très souvent utilisé

Les instructions de sous-programmes[modifier | modifier le wikicode]

Les instructions CALL et RETLW et RETURN sont pour l'appel de sous-programme.

Opérations littérales (adressage direct) et de contrôles
Mnémonique

Opérande

Description Cycles 14 bits Opcode status affected notes
CALL k appel du sous programme k 2 10 0kkk kkkk kkkk
GOTO k aller à l'adresse 2 10 1kkk kkkk kkkk
RETLW k retour avec le littéral dans W 2 11 01xx kkkk kkkk
RETURN retour de sous-programme 2 00 0000 0000 1000

Le rôle de la pile pour les appels imbriqués[modifier | modifier le wikicode]

Si l’on veut qu'un sous-programme puisse lui-même appeler un autre sous-programme il faut que les appels successifs utilisent une pile. Chaque appel (de sous-programme) empile l'adresse de retour (ou adresse de l'instruction suivante) tandis que chaque fin de sous-programme dépile cette adresse.

Avec le PIC 16F on ne peut pas abuser des sous-programmes car il n'y a que 8 niveaux d'imbrications. C'est relativement peu pour l’utilisation de compilateurs car les librairies elles-mêmes peuvent déjà en comporter quelques uns.


Les choix multiples[modifier | modifier le wikicode]

La programmation de suivant le cas faire... peut se faire de différentes manières. Nous commençons par en présenter une :

	CBLOCK 0x00 ; début de la zone variables en ACCESS RAM
		w_temp :1 ; Zone de 1 byte 
		status_temp : 1 ; zone de 1 byte 
		Choix : 1 ; je déclare ma variable 
	ENDC ; Fin de la zone 
	...
;si Choix=0 faire le sous programme spgm0 si Choix=1 faire spgm1
	; Choix contient ici une valeur <=N
	movlw 0x0
	subwf Choix,w		;Choix - W -> W
	btfsc STATUS,Z		;Z=1 si = 0 et on saute
	goto spgm0
	movlw 0x1
	subwf Choix,w		;Choix - W -> W
	btfsc STATUS,Z		;Z=1 si = 0 et on saute
	goto spgm1
	...
	movlw 0xN
	subwf Choix,w		;Choix - W -> W
	btfsc STATUS,Z		;Z=1 si = 0 et on saute
	goto spgmN
	; erreur ici !!!
suite
	....

spgm0		;code ici
	goto suite
	....


Les tableaux en mémoire programme (lookup table en anglais)[modifier | modifier le wikicode]

Comme aucune instruction ne permet de lire un octet en mémoire programme, l’astuce est d’utiliser l’instruction retlw qui permet de retourner une valeur passée en argument. Écrivons donc notre tableau sous forme de retlw (voir plus haut, cela donne :

	retlw 0 ; premier élément = 0 
	retlw 1 ; deuxième élément = 1 
	...
	retlw 225 ; nième élément = 225

Nous pouvons ensuite utiliser PCL (poids faible du compteur programme) pour accéder à ce tableau. Si l'index d'accès au tableau est dans une variable "index" :

	movf index, w		; index -> W
	call tableau
   	...
tableau 
	addwf PCL , f 	; ajouter w à PCL 
	retlw 0 ; premier élément = 0 
	retlw 1 ; deuxième élément = 1 
	...
	retlw 225 ; nième élément = 225

Donc, si on charge 1 dans W et qu’on effectue un appel « call tableau ». Le programme se branche sur la bonne ligne, le PCL est incrémenté de 1 et le programme exécute donc alors la ligne « retlw 1 ». Si l'origine du tableau est au-delà des 8 bits, par exemple :

Début de l'exemple
Fin de l'exemple


L'adressage indirect du 16FXXX[modifier | modifier le wikicode]

Cet adressage fait appel à 2 registres, dont un est particulier, car il n’existe pas vraiment. Examinons-les donc :

Les registres FSR et INDF

INDF signifie INDirect File. C’est le fameux registre de l’adresse 0x00. Ce registre n’existe pas vraiment, ce n’est qu’un procédé d’accès particulier à FSR utilisé par le PIC® pour des raisons de facilité de construction électronique interne.

Le registre FSR est à l’adresse 0x04 dans les 2 banques. Il n’est donc pas nécessaire de changer de banque pour y accéder, quelle que soit la banque en cours d’utilisation.

Le contenu du registre FSR pointe sur une adresse en 8 bits. Or, sur certains PIC®, la zone RAM contient 4 banques (16F876). L’adresse complète est donc une adresse sur 9 bits. Le registre FSR est alors complété alors par le bit IRP du registre Status.

Début de l'exemple
Fin de l'exemple

Les puristes peuvent se demander pourquoi ne pas écrire directement

	movf FSR,w

au lieu de

	movf INDF,w

C'est tout simplement parce que movf FSR,w existe mais a une autre signification, mettre le registre FSR dans w ! On a bien besoin d'un pseudo registre pour l'adressage indirect.

Tableau en RAM[modifier | modifier le wikicode]

On complète l'adressage indexé de la section précédente.

	movf INDF,w ; W<-(FSR)

avec

	movwf INDF ;(FSR)<-W

Nous pouvons ainsi utiliser l'adressage indexé dans les deux directions.

Architecture complète du 16F84[modifier | modifier le wikicode]

Puisque cette section termine notre description du PIC 16F84 du point de vue de ses instructions, nous allons résumer ce que nous avons appris avec le schéma complet de ce microcontrôleur tel qu'on peut le trouver dans la documentation officielle.

Documentation complète du PIC 16F84

Un certain nombre de fonctions de ce schéma seront détaillées un peu plus loin : les ports d'entrées et sorties ainsi que le timer 0.

L'adressage indirect du 18FXXX[modifier | modifier le wikicode]

Le concept précédent a été étendu dans les PIC 18F pour pouvoir accéder à de plus grandes quantités de mémoires. Il y a maintenant 3 registres FSR. Puisqu’ils doivent permettre d'adresser toute la mémoire ils doivent avoir 12 bits chacun, d'où la présence de FSR2H:FSR2L, FSR1H:FSR1L et FSR0H:FSR0L. Pour compliquer un peu les choses, il y a cinq équivalent à INDF : INDFn, POSTINCn, POSTDECn, PREINCn et PLUSWn. Évidemment cette complexité est faite pour simplifier la construction des compilateurs sur cette architecture.

Début de l'exemple
Fin de l'exemple

Microchip a donc ajouté une instruction pour faciliter ce mode d'adressage.


Image logo représentative de la faculté Faculté de Sciences de l'ingénieur Faites ces exercices : Les sous-programmes en assembleur.