Académique Documents
Professionnel Documents
Culture Documents
particuliers de la RAM. W
L’architecture RISC
implique que toutes les Xtal Horl
General 20h
General A0h
General 120h
EFh
7Fh 1FFh
Les instructions à adressage immédiat comportent la valeur immédiate k sur 8 bits dans le
code de l’instruction. Le résultat d’une opération arithmétique est toujours mis dans W.
ADDLW k Add Literal to W
Les instructions de saut ont une destination décrite ANDLW k And Literal with W
sur 11 bits. Il y a les instructions de saut (goto), CALL k Call subroutine
d’appel de procédure (call) et 3 retours de CLRWDT Clear Watchdog Timer
procédure (Retxxx). GOTO k GoTo address f
IORLW k Inclusive OR literal with W
Il n’y a pas vraiment d’instruction de saut MOVLW k Move Literal to W
conditionnel utilisant les drapeaux du registre RETFIE Return from Interrupt
RETLW k Return with Literal in W
d’état STATUS. Une manière de réaliser un RETURN Return from subroutine
‘débranchement’ conditionnel est d’utiliser l’une SLEEP Go into stanby mode
des instructions d’incrémentation et de SUBLW k Sunstract W from Literal
décrémentation d’un registre. Ainsi l’instruction XORLW k Exclusive OR Literal with W
DECFSZ f,d décrémente le registre f et met le résultat dans W ou f (suivant la valeur de d),
incrémente le compteur de programme PC de 1 (passe à l’instruction suivante) si le résultat
est différent de 0 et incrémente PC de 2 dans le cas contraire (saute l’instruction suivante)
test DECFSZ compteur, f ;inst i
(+1) GOTO suite ;inst i+1
(+2) CALL proc1 ;inst i+2 : le résultat valait 0
Suite …
La variable compteur est décrémentée (résultat dans compteur car d=f) et un appel de
procédure est réalisé quand le compteur passe à 0. L’autre manière de procéder passe par
l’utilisation de l’une des deux instructions BTFSx (Bit Test and Skip if x). La structure de saut
est semblable à celle de l’instruction DECFZ : saut de l’instruction suivante si la condition
est vraie.
Exemple de code
Ce code initialise à 0 une table de 8 éléments et utilise pour ce faire l’adressage indirect. La
boucle d’itération est faite sur la base d’une instruction de test de bit.
movlw Table ; @Table mise dans W (reg en RAM)
movwf FSR ; @Table mise dans le registre FSR
movlw huit ; initialise un compteur cpt à 8
movwf cpt ;
iter clrf INDF ; ‘clear’ indirect, adresse dans FSR
incf FSR ; FSR pointe sur l’octet suivant
decfsz cpt,f ; fini les 8 octets ? aller à suite
goto iter ; l’initialisation continue.
suite …
Les deux premières instructions mettent l’adresse de Table dans le registre d’adresse FSR.
L’instruction CLRF INDF est particulière au sens du registre destination INDF. L’opération
‘clear’ porte sur un registre RAM INDF qui n’existe pas (adresse 0) mais qui indique que
l’adressage à utiliser est indirect (INDirect File) avec l’adresse réelle dans FSR. C’est bien
le registre d’adresse FSR qui est ensuite incrémenté pour pointer l’élément suivant. Le
compteur cpt est décrémenté et la sortie de boucle réalisée quand il passe à 0.
Les interruptions.
Le µc PIC16f628 autorise 10 sources d’interruptions parmi lesquelles l’interruption externe,
d’usage général, via la broche RB0/INT, les changements de valeur sur les broches RB4-7
du portB, les signaux Tx et Rx de l’USART, et les dépassements (passage de ffh à 00h du
compteur) de temporisateurs (timer).
Si les principes généraux de la gestion des interruptions sont semblables à ceux d’un
processeur classique, il y a quand même pas mal de singularités du point de vue de
l’implémentation technique et donc de la mise en oeuvre au niveau de l’assembleur.
Lors de la prise en compte d’une interruption, le compteur de programme PC est
normalement sauvegardé dans la pile et restitué en sortie de routine d’interruption avec
l’instruction RETFIE. Les interruptions peuvent être masquées soit globalement soit
localement (plus ou moins individuellement) : des bits de configuration sont prévus à cet
effet dans le registre-RAM INTCON (INTerrupt CONfiguration).
Par contre, l’architecture interne implique les particularités suivantes.
Il n’y pas de vecteur d’interruption, donc une seule routine à une adresse fixe (004) et
l’identification de la source d’interruption doit se faire par scrutation. Le temps de latence se
voit ainsi augmenté.
Il n’y a pas de prise en compte d’une interruption pendant le traitement d’une autre : l’entrée
dans la routine d’interruption masque automatiquement les interruptions, le démasquage est
fait par RETFIE. Il n’y a pas d’interruptions logicielles.
Il n’y a pas de hiérarchisation des interruptions par niveau, le traitement des interruptions est
séquentiel (en fifo), éventuellement dans la même routine d’interruption.
Au niveau des sauvegardes du contexte, seul PC est rangé dans la pile. Il est du ressort du
programmeur de faire la sauvegarde du registre de travail W et du registre STATUS (registre
RAM). Mais, la pile n’étant pas accessible à la programmation, ces sauvegardes doivent
nécessairement se faire dans les registres RAM. Or cette sauvegarde est pour le moins
singulière en ce qui concerne STATUS. Il n’existe pas d’instruction de transfert d’un
registre-RAM vers un autre (à part W) sans passer par W. Cela signifie en premier lieu qu’il
faut d’abord obligatoirement sauvegarder le registre W. La sauvegarde de STATUS
implique sa recopie dans W (movf STATUS, w), puis le transfert dans un registre (movwf
svg_ST) que l’on aura affecté à cette destination. Or l’instruction movf de copie de STATUS
dans W, considérée comme une instruction arithmétique (‘mettre’ un résultat dans W)
modifie le drapeau Z de … STATUS et ne peut donc être utilisée. L’ « astuce » consiste
alors à trouver une instruction permettant le transfert d’un registre dans W sans affecter
STATUS. L’instruction swapf fait ce transfert, mais permute (swap) les 2 quartets du
registre. Le registre est ainsi recopié avec cette permutation : à la restauration il faudra bien
penser à faire la permutation inverse.
L’ossature générale d’une routine de traitement d’une interruption avec sa séquence de
sauvegarde-restauration pourra avoir la forme suivante :
CBLOC 0x020 ; début de la zone mémoire pour les données
Svg_W : 1 ; 1 octet pour sauvegarder W
Svg_ST : 1 ; 1 octet pour sauvegarder STATUS
ENDC
ORG 0x004 ; adresse de début de la routine d’interruption
; sauvegarde de W et STATUS
movwf Svg_W ; W est sauvegardé, STATUS intact
swapf STATUS, w ; STATUS ‘permuté’ dans W, STATUS intact
movwf Svg_ST ; STATUS ‘permuté’ sauvegardé dans Svg_ST
; sauvegarde d’éventuels autres registres (FSR par exemple)
bcf STATUS, RP0 ; travailler en page 0 (par exemple)
bcf STATUS, RP1 ; (bits RP0 et RP1 de STATUS mis à 0)
Les bits RP0 et RP1 de STATUS indiquent la page courante de travail : ce numéro de page
est donc ‘hérité’ du programme interrompu et n’est pas forcément la page souhaitée, d’où le
positionnement de ces 2 bits après la séquence de sauvegarde. La page d’origine sera
automatiquement remise en activité par la restauration de STATUS.
Pour rendre la programmation plus lisible, il est évidemment possible de définir deux
macros pour l’ensemble de ces instructions qui reviennent systématiquement dans la routine
d’interruption. On retiendra aussi que les choix architecturaux dans la conception d’un
processeur ont une incidence certaine sur la programmation de celui-ci.
Le µC PIC16f628 prend en compte d’autres formes d’ « interruptions », maintenant
indispensables sur les systèmes embarqués, comme la mise en sommeil et le redémarrage
par chien de garde. Le mode Sleep est une mise en sommeil pour économiser l’énergie dans
le système embarqué. Le processeur est arrêté par suppression de son horloge, il est comme
figé dans le temps et il n’y a pas de sauvegarde particulière à faire. C’est une forme
particulière d’interruption logicielle par l’appel à l’instruction sleep.
Le chien de garde (WatchDog) est un dispositif de veille automatique analogue à celui de
« l'homme mort » qui permet de s'assurer en permanence que le conducteur d’une
locomotive est présent à son poste et conscient. Le conducteur doit effectuer une tâche
périodique (appui d’une manette ou pédale) faute de quoi l’arrêt d’urgence du train se met
en route automatiquement.
Lorsque le Watchdog est activé le programme en cours d’exécution sur le microcontrôleur
doit venir régulièrement remettre à 0 le compteur de temps du chien de garde. S’il arrive à
expiration, le Watchdog provoque la réinitialisation du programme. Cela permet de s’assurer
que le programme ne reste pas bloqué sur une attente infinie ou boucle dans une zone non
prévue. La conception de l’application doit, dès les premiers stades, prendre en compte ce
type de système de sécurité.