Vous êtes sur la page 1sur 31

PIC 16F84A

Remarques et astuces de programmation en


assembleur
Equivalence avec le langage C
1- Charger une valeur littrale dans un registre
2- Charger un registre avec le contenu d'un autre registre
3- Echanger le contenu de deux registres
4- IF ELSE : Tests de comparaison
o 4-1- Tests d'galit
4-1-1- Le contenu du registre est-il nul ?
4-1-2- Le contenu du registre est-il diffrent de zro ?
4-1-3- Le contenu du registre est-il gal une certaine valeur ?
4-1-4- Le contenu du registre est-il diffrent d'une certaine
valeur ?
4-1-5- Le contenu du registre est-il gal au contenu d'un autre
registre ?
4-1-6- Le contenu du registre est-il diffrent du contenu d'un
autre registre ?
o 4-2- Tests de supriorit
4-2-1 - Le contenu du registre est-il strictement suprieur une
certaine valeur ?
4-2-2 - Le contenu du registre est-il suprieur ou gal une
certaine valeur ?
4-2-3 - Le contenu du registre est-il strictement infrieur une
certaine valeur ?
4-2-4 - Le contenu du registre est-il infrieur ou gal une
certaine valeur ?
4-2-5 - Le contenu du registre est-il strictement suprieur au
contenu d'un autre registre ?
4-2-6 - Le contenu du registre est-il suprieur au contenu d'un
autre registre ?
5- Boucle DO WHILE
6- Boucle WHILE
7- Boucle FOR
8- Manipulation de bits. Les masques
o 8-1- Mettre 0 certains bits d'un registre
o 8-2- Mettre 1 certains bits d'un registre
o 8-3- Inverser certains bits d'un registre
9- Tableau de donnes
1- Charger une valeur littrale dans un registre

movlw B'10001100' ; W = B'10001100'

movwf REGISTRE ; (REGISTRE) = B'10001100' = 0x8C = D'140'

Equivalence en langage C :

REGISTRE = 0x8C ;

2- Charger un registre avec le contenu d'un autre registre

movf REGISTRE1 , W ; W = (REGISTRE1)

movwf REGISTRE2 ; (REGISTRE2) = (REGISTRE1)

Equivalence en langage C :

REGISTRE2 = REGISTRE1 ;

3- Echanger le contenu de deux registres : (REGISTRE1)


< - > (REGISTRE2)

Il faut utiliser une variable intermdiaire :

REGISTRE_TEMP (registre d'usage gnral)


movf REGISTRE1 , W ; W = (REGISTRE1)

movwf REGISTRE_TEMP ; (REGISTRE_TEMP) = (REGISTRE1)

movf REGISTRE2, W ; W = (REGISTRE2)

movwf REGISTRE1 ; (REGISTRE1) = (REGISTRE2)

movf REGISTRE_TEMP, W ; W = (REGISTRE_TEMP)

movwf REGISTRE2 ; (REGISTRE2) = (REGISTRE_TEMP)

Equivalence en langage C :

REGISTRE_TEMP = REGISTRE1 ;

REGISTRE1 = REGISTRE2 ;

REGISTRE2 = REGISTRE_TEMP ;

4- Tests de comparaison
4-1- Tests d'galit

4-1-1- Le contenu du registre est-il nul ?

(REGISTRE) = 0x00 ?
movf REGISTRE , f ; (REGISTRE) = (REGISTRE)

btfss STATUS , Z ; test du bit Z

goto non ; Z = 0 c'est--dire (REGISTRE) != 0x00

{ bloc d'instructions 1 }

goto suite

non

{ bloc d'instructions 2 }

suite

{ suite du programme }

Equivalence en langage C :

if (REGISTRE = = 0x00)

{
// bloc d'instructions 1

else

// bloc d'instructions 2

4-1-2- Le contenu du registre est-il diffrent de zro ?

(REGISTRE) != 0x00 ?

movf REGISTRE , f ; (REGISTRE) = (REGISTRE)

btfsc STATUS , Z ; test du bit Z

goto non ; Z = 1 c'est--dire (REGISTRE) = 0x00

{ bloc d'instructions 1 }
goto suite

non

{ bloc d'instructions 2 }

suite

{ suite du programme }

Equivalence en langage C :

if (REGISTRE != 0x00)

// bloc d'instructions 1

else

// bloc d'instructions 2

4-1-3- Le contenu du registre est-il gal une certaine valeur ?

(REGISTRE) = 0x3F ?
movlw 0x3F ; W = 0x3F

subwf REGISTRE, W ; W = (REGISTRE) - 0x3F

btfss STATUS, Z ; test du bit Z

goto non ; Z = 0 c'est--dire (REGISTRE) != 0x3F

{ bloc d'instructions 1 }

goto suite

non

{ bloc d'instructions 2 }

suite

{ suite du programme }

Equivalence en langage C :

if (REGISTRE = = 0x3F)
{

// bloc d'instructions 1

else

// bloc d'instructions 2

4-1-4- Le contenu du registre est-il diffrent d'une certaine valeur ?

(REGISTRE) != 0x3F ?

movlw 0x3F ; W = 0x3F


subwf REGISTRE, W ; W = (REGISTRE) - 0x3F

btfsc STATUS, Z ; test du bit Z

goto non ; Z = 1 c'est--dire (REGISTRE) = 0x3F

{ bloc d'instructions 1 }

goto suite

non

{ bloc d'instructions 2 }

suite

{ suite du programme }

Equivalence en langage C :

if (REGISTRE != 0x3F)

// bloc d'instructions 1

else

// bloc d'instructions 2

4-1-5- Le contenu du registre est-il gal au contenu d'un autre registre ?

(REGISTRE1) = (REGISTRE2) ?
movf REGISTRE2 , W ; W = (REGISTRE2)

subwf REGISTRE1, W ; W = (REGISTRE1) - (REGISTRE2)

btfss STATUS, Z ; test du bit Z

goto non ; Z = 0 c'est--dire (REGISTRE1) != (REGISTRE2)

{ bloc d'instructions 1 }

goto suite

non

{ bloc d'instructions 2 }

suite

{ suite du programme }

Equivalence en langage C :

if (REGISTRE1 = = REGISTRE2)
{

// bloc d'instructions 1

else

// bloc d'instructions 2

4-1-6- Le contenu du registre est-il diffrent du contenu d'un autre registre ?

(REGISTRE1) != (REGISTRE2) ?

movf REGISTRE2 , W ; W = (REGISTRE2)

subwf REGISTRE1, W ; W = (REGISTRE1) - (REGISTRE2)


btfsc STATUS, Z ; test du bit Z

goto non ; Z = 1 c'est--dire (REGISTRE1) = (REGISTRE2)

{ bloc d'instructions 1 }

goto suite

non

{ bloc d'instructions 2 }

suite

{ suite du programme }

Equivalence en langage C :

if (REGISTRE1 != REGISTRE2)

// bloc d'instructions 1

else

// bloc d'instructions 2

4-2- Tests de supriorit

4-2-1 - Le contenu du registre est-il strictement suprieur une certaine


valeur ?

(REGISTRE) > 0x3F ?


Les valeurs sont supposes en binaire naturel.

movf REGISTRE , W ; W = (REGISTRE)

sublw 0x3F ; W = 0x3F - (REGISTRE)

btfsc STATUS, C ; test du bit C (Carry)

goto non ; C = 1 c'est--dire 0x3F >= (REGISTRE)

{ bloc d'instructions 1 }

goto suite

non

{ bloc d'instructions 2 }

suite

{ suite du programme }
Equivalence en langage C :

if (REGISTRE > 0x3F)

// bloc d'instructions 1

else

// bloc d'instructions 2

4-2-2 - Le contenu du registre est-il suprieur ou gal une certaine valeur ?

(REGISTRE) >= 0x3F ?

Les valeurs sont supposes en binaire naturel.


movlw 0x3F ; W = 0x3F

subwf REGISTRE, W ; W = (REGISTRE) - 0x3F

btfss STATUS, C ; test du bit C (Carry)

goto non ; C = 0 c'est--dire (REGISTRE) < 0x3F

{ bloc d'instructions 1 }

goto suite

non

{ bloc d'instructions 2 }

suite

{ suite du programme }

Equivalence en langage C :

if (REGISTRE >= 0x3F)

// bloc d'instructions 1

else

// bloc d'instructions 2

4-2-3 - Le contenu du registre est-il strictement infrieur une certaine valeur


?

(REGISTRE) < 0x3F ?


Les valeurs sont supposes en binaire naturel.

movlw 0x3F ; W = 0x3F

subwf REGISTRE, W ; W = (REGISTRE) - 0x3F

btfsc STATUS, C ; test du bit C (Carry)

goto non ; C = 1 c'est--dire (REGISTRE) >= 0x3F

{ bloc d'instructions 1 }

goto suite

non

{ bloc d'instructions 2 }

suite

{ suite du programme }

Equivalence en langage C :

if (REGISTRE < 0x3F)


{

// bloc d'instructions 1

else

// bloc d'instructions 2

4-2-4 - Le contenu du registre est-il infrieur ou gal une certaine valeur ?

(REGISTRE) <= 0x3F ?

Les valeurs sont supposes en binaire naturel.

movf REGISTRE , W ; W = (REGISTRE)

sublw 0x3F ; W = 0x3F - (REGISTRE)


btfss STATUS, C ; test du bit C (Carry)

goto non ; C = 0 c'est--dire 0x3F < (REGISTRE)

{ bloc d'instructions 1 }

goto suite

non

{ bloc d'instructions 2 }

suite

{ suite du programme }

Equivalence en langage C :

if (REGISTRE <= 0x3F)

// bloc d'instructions 1

else

// bloc d'instructions 2

4-2-5 - Le contenu du registre est-il suprieur ou gal au contenu d'un autre


registre ?

(REGISTRE1) >= (REGISTRE2) ?

Les valeurs sont supposes en binaire naturel.


movf REGISTRE2 , W ; W = (REGISTRE2)

subwf REGISTRE1, W ; W = (REGISTRE1) - (REGISTRE2)

btfss STATUS, C ; test du bit C (Carry)

goto non ; C = 0 c'est--dire (REGISTRE1) < (REGISTRE2)

{ bloc d'instructions 1 }

goto suite

non

{ bloc d'instructions 2 }

suite

{ suite du programme }

Equivalence en langage C :

if (REGISTRE1 >= REGISTRE2)


{

// bloc d'instructions 1

else

// bloc d'instructions 2

4-2-6 - Le contenu du registre est-il strictement infrieur au contenu d'un


autre registre ?

(REGISTRE1) < (REGISTRE2) ?

Les valeurs sont supposes en binaire naturel.

movf REGISTRE2 , W ; W = (REGISTRE2)


subwf REGISTRE1, W ; W = (REGISTRE1) - (REGISTRE2)

btfsc STATUS, C ; test du bit C (Carry)

goto non ; C = 1 c'est--dire (REGISTRE1) >= (REGISTRE2)

{ bloc d'instructions 1 }

goto suite

non

{ bloc d'instructions 2 }

suite

{ suite du programme }

Equivalence en langage C :

if (REGISTRE1 < REGISTRE2)

// bloc d'instructions 1

else

// bloc d'instructions 2

5- Boucle Do While
Exemple :
debut

{ bloc d'instructions }

movf REGISTRE , f

btfsc STATUS , Z

goto debut

suite

{ suite du programme }

Equivalence en langage C :

do

// bloc d'instructions
}

while (REGISTRE = = 0x00) ;

6- Boucle While
Exemple :

debut

movlw 0xE8 ; W = 0xE8

subwf REGISTRE, W ; W = (REGISTRE) - 0xE8

btfss STATUS , Z

goto suite

{ bloc d'instructions }

goto debut

suite

{ suite du programme }
Equivalence en langage C :

while (REGISTRE = = 0xE8)

// bloc d'instructions

7- Boucle FOR
Une variable (1 octet) sert de compteur.

Exemple :

Pour excuter le bloc d'instructions 20 fois, la valeur initiale du compteur doit tre
21 :
movlw D'21' ; W = D'21'

movwf COMPTEUR ; (COMPTEUR) = D'21' pour 20 boucles

debut

decfsz COMPTEUR , f ; (COMPTEUR) = (COMPTEUR) - 1

goto boucle ; (COMPTEUR) != 0

goto suite ; (COMPTEUR) = 0

boucle

{ bloc d'instructions }
goto debut

suite

{ suite du programme }

N.B. Avec (COMPTEUR) = 0xFF en valeur initiale, on effectue 254 boucles.

Avec (COMPTEUR) = 0x00 en valeur initiale, on effectue 255 boucles.

Avec (COMPTEUR) = 0x01 en valeur initiale, on effectue 0 boucle.

Equivalence en langage C

for (COMPTEUR = 20 ; COMPTEUR > 0 ; COMPTEUR--)

// bloc d'instructions

8- Manipulation de bits. Les masques

8-1- Mettre 0 certains bits d'un registre

Exemple : on veut mettre 0 les bits 1, 2, 4 et 6, les autres bits tant inchangs :

B'u0u0u00u'

movlw B'10101001' ; W = B'10101001' (on appelle a un masque)

andwf REGISTRE , f ; fonction ET logique


Valeur initiale : (REGISTRE) = B'11010101'

Valeur finale : (REGISTRE) = B'10000001'

N.B. S'il n'y a qu'un seul bit mettre 0, il faut simplement utiliser
l'instruction bcf.

S'il faut mettre tous les bits 0, il faut simplement utiliser


l'instruction clrf REGISTRE.

8-2- Mettre 1 certains bits d'un registre

Exemple : on veut mettre 1 les bits 1, 2, 4 et 6, les autres bits tant inchangs :

B'u1u1u11u'

movlw B'01010110' ; W = B'01010110' (masque)

iorwf REGISTRE , f ; fonction OU logique

Valeur initiale : (REGISTRE) = B'11010101'

Valeur finale : (REGISTRE) = B'11010111'

N.B. s'il n'y a qu'un seul bit mettre 1, il faut simplement utiliser l'instruction bcf.

8-3- Inverser certains bits d'un registre

Exemple : on veut complmenter les bits 1, 2, 4 et 6, les autres bits tant inchangs.

movlw B'01010110' ; W = B'01010110' (masque)

xorwf REGISTRE , f ; fonction logique OU exclusif


Valeur initiale : (REGISTRE) = B'11010101'

Valeur finale : (REGISTRE) = B'10000011'

N.B. s'il faut inverser tous les bits, il faut simplement utiliser l'instruction comf
REGISTRE , f

9- Tables de donnes
On utilise la technique de l'adressage relatif.

Exemple :

On dsire effectuer l'opration arithmtique : y = 10x +1

Ainsi, pour x =D'16' : y = D'161'

Cela peut se faire simplement avec un tableau de donnes.

On commence par crer la routine table.

Pour des raisons de simplicit, l'adresse de dbut de cette routine peut tre (pour un
microcontrleur 16F84A) :

0x100
0x200
0x300

; xxxxxxxxxxx

; Routine table

; xxxxxxxxxxx

org 0x0300 ; adresse de dbut de la table


table

addwf PCL , f ; (PCL) = (PCL) + W

retlw D'1'

retlw D'11'

retlw D'21'

retlw D'31'

retlw D'41'

retlw D'51'

retlw D'61'

retlw D'71'

retlw D'81'

retlw D'91'

retlw D'101'

retlw D'111'

retlw D'121'

retlw D'131'

retlw D'141'

retlw D'151'

retlw D'161'

retlw D'171'

retlw D'181'

retlw D'191'

retlw D'201'

retlw D'211'
retlw D'221'

retlw D'231'

retlw D'241'

retlw D'251'

; Fin de la routine table

; xxxxxxxxxxxxxxxxxx

Avec un dbut de routine l'adresse 0x300, l'instruction retlw D'1' se trouve


l'adresse 0x301, retlw D'11' l'adresse 0x302 etc...

La table peut contenir jusqu' 255 lments (0x301 0x3FF).

Ici, notre table possde 26 lments donc pas de problme de taille.

Dans le programme principal, pour appeler la routine, il faut au pralable charger le


registre spcial PCLATH avec la valeur 0x03 (0x02 si l'adresse de dbut est 0x200
etc ...) :

movlw 0x03 ; W = 0x03

movwf PCLATH ; (PCLATH) = 0x03

movlw D'16' ; W = D'16' : 16me ligne de la table

call table

movwf resultat ; (resultat) = D'161'

Lien vers un projet qui utilise des tables de donnes

(C) Fabrice Sincre