Vous êtes sur la page 1sur 16

TD Microcontrôleur, famille PIC

Exercices de programmation en assembleur

!
" ## $ % & & ## '
" % ' % &% % # $ $ $ & & ##
" $ ( ) *% + #$ , - ./ % &
#+ % '
" ( ( $ $) $ # 0% # # '
"% # + , % ' % + % /'
" % !% + , #$ ' $ #1 ' 2/ - .

I – Table de retour de fonction

#include <p16F84.inc> ; processor specific variable definitions


__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC

org 0x0000
goto main

org 0x0010
HexaTo7Segments:
addwf PCL, f
retlw b'00111111' ;decode 0
retlw b'00000110' ;decode 1
retlw b'01011011' ;decode 2
retlw b'01001111' ;decode 3
retlw b'01100110' ;decode 4
retlw b'01101101' ;decode 5
retlw b'01111101' ;decode 6
retlw b'00000111' ;decode 7
retlw b'01111111' ;decode 8
retlw b'01101111' ;decode 9

main:
// init portB
bsf STATUS, RP0 ; bank1
movlw 0x00
movwf TRISB ; PORTB en sortie
bcf STATUS, RP0 ; bank0

movlw 5; Exemple ....


call HexaTo7Segments
movwf PORTB

END
34. 5 %

!! ! !
"# $"# % ! & '

#6# ( 7% $ % & &# '# $% 8 % 9


: % % 4+ ' % 8 % $% 8 % ;
% % # # ( 0 $ $% # 7% ' # !
< % # # $ & ## < # # $ & ## $ #
= % % ; >4 ,>=$ % > / $ & ## $ 7%
% # # % ' %
#+ % # ! ??

II – Adressage indexé
( ! ! ) * +
,- . / +
0 ,- !! / / !
1*22 3 4
#include <p16F84.inc> ; processor specific variable
definitions
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC

;***** VARIABLE DEFINITIONS


v1 equ 0x0010 ; premier vecteur
v2 equ 0x0018 ; le deuxième
s equ 0x0020 ; le resultat
n equ 0x000C ; la taille des vecteurs (max: 8)
i equ 0x000D ; indice de la boucle
p_v1 equ 0x002A ; pointeur sur la case en cours de v1
p_v2 equ 0x002B
p_s equ 0x002C
tmp_v equ 0x002D ; valeur tmp pour l'addition
;****************************************************************
ORG 0x0000 ; processor reset vector
goto main ; go to beginning of program
34. 5 %

ORG 0x0010

main:
bcf STATUS, RP0 ; bank0
;init des variables
clrf i ; 0-> i
movlw v1 ; on récupère l'adresse de v1 (0x10)
movwf p_v1

movlw v2 ; on récupère l'adresse de v2 (0x18)


movwf p_v2

movlw s ; idem avec s


movwf p_s

main_B1:
; valeur de v1[i] -> tmp_v
movf p_v1, W
movwf FSR
movf INDF, W
movwf tmp_v
; valeur de v2[i] -> W
movf p_v2, W
movwf FSR
movf INDF, W
; addition W + tmp_v -> tmp_v
addwf tmp_v, f
; tmp_v -> s[i]
movf p_s, W
movwf FSR
movf tmp_v, W
movwf INDF

; i = i+1 (et tous les pointeurs)


incf p_v1, f ;
incf p_v2, f
incf p_s , f
incf i , f ;
; on continue ?
movf i, W
subwf n, W ; n - i -> W!!!!
btfss STATUS, Z
goto main_B1 ; non fait si STATUS<Z> = 1

; fin
nop
END

+ 45 ! 6"#.*#.4#.'.$"# ?? , / 45
! 7 )((% - %8 (
. ∈ 9"#:$"#; 3 2 3 5

@
34. 5 %

A$ $% $% % %, # '# % &% % '


% $( & ' 2/' $ % & & % , % %
%# 7% % % % %# 7% &7% /' 2

- ! ) ! ∈ 9"#:<="#; 3
=
< $ +1# & % B C8 D) B C > D) $ #6#
% %% $ !" ! $ % !" ' #
#include <p16F84.inc> ; processor specific variable
definitions
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC

;***** VARIABLE DEFINITIONS


org 0x2100 ; 10 0001 0000 0000 (14 bits) : adresse EEPROM
; de permet de stocker des valeurs (ou variables) en EEPROM
t_sinus de .0, .9, .18, .27, .36, .45
de .54, .62, .71, .79, .88, .96
de .104, .112, .120, .128, .136, .143
de .150, .157, .164, .171, .178, .184
de .190, .196, .201, .207, .212, .217
de .221, .226, .230, .233, .237, .240
de .243, .246, .248, .250, .252, .253
de .254, .255, .255, .255

; variable en RAM
sinus_indice equ 0x0010
tmp_W equ 0x0011
;*******************************************************************
***
; processor reset vector
ORG 0x0000
goto main ; go to beginning of program

ORG 0x0010
Sinus_W: ; la valeur en degré est dans W
; sauvegarde de W
movwf sinus_indice

; ajouter ces lignes pour la question c


; W > 90 ?
sublw .90 ; 90 - W -> W
btfsc STATUS, C
goto Sinus_p90
; W>90 : calculer sin(180 - W)
movf sinus_indice, W;
sublw .180; k - W -> W
movwf sinus_indice;

Sinus_p90:
bcf STATUS, C ; si W = 90, mise à 0 du flag C (rrf !)
; fin ajout pour question c

4
34. 5 %

; division par 2
rrf sinus_indice, f

bcf STATUS, RP0 ; bank 0


movlw t_sinus ; debut de la table
addwf sinus_indice, W ; + offset (indice)

movwf EEADR ; positionner le pointeur EEPROM


bsf STATUS, RP0; bank 1
bsf EECON1, RD ; lecture
bcf STATUS, RP0; bank 0
movf EEDATA, W ; lire la valeur
; t_sinus[sinus_indice] -> W
return

main:
nop
; movlw .10 ; .10 : table: 0x2D = 45 -> /256 = 0.1764;
sin(10°)=0.1736
movlw .170 ; question c
call Sinus_W
nop
END

III – Arithmétique : addition 16 bits


"3 ! ) <5 +
) <5 / <5 ! *
> ! ! .! ! ! !
! .
( ! + 1

? ! ! 3 @ +(A
% BCD"E
#include <p16F84.inc> ; processor specific variable
definitions
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC

;***** VARIABLE DEFINITIONS


ah equ 0x0010 ; poids fort a
al equ 0x0011 ; poids faible a
bh equ 0x0012 ; poids fort b
bl equ 0x0013 ; poids faible b
sh equ 0x0014 ; poids fort s (resultat)
sl equ 0x0015 ; poids faible s

;****************************************************************
ORG 0x0000 ; processor reset vector
goto main ; go to beginning of program

ORG 0x0010
Add16:

?
34. 5 %

; init de s
; ah -> sh
movf ah, W
movwf sh

; al -> sl
movf al, W
movwf sl

; somme sl + bl
movf bl, W
addwf sl, f

;dépassement ?
btfsc STATUS, C
incf sh, f

; somme sh + bh -> sh
movf bh, W
addwf sh, f
return

main:
; init du portB
bsf STATUS, RP0 ; bank 1
bcf TRISB, 0 ; RB0 en sortie
bcf STATUS, RP0 ; bank 0
; init a
movlw H'FE'
movwf al
movlw H'30'
movwf ah

; init b
movlw H'FF'
movwf bl
movlw H'D0'
movwf bh

call Add16
; LED ?
bcf PORTB, 0 ; LED éteinte
btfsc STATUS, C
bsf PORTB, 0 ; LED allumée

; goto main …
nop

END
34. 5 %

IV – Arithmétique : Multiplication 8 bits


3 ) ) ! ! =
+ <5 * = !
!
(

;% % % ! $% #$ E F $$ ) $ %
$ % +%
: % $% $ , #$ 4 A 0$$ 2/ !
#include <p16F84.inc> ; processor specific variable definitions
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _RC_OSC

;***** VARIABLE DEFINITIONS


m_a equ 0x0010 ;
m_b equ 0x0011 ;
m_h equ 0x0012 ; poids fort b
m_l equ 0x0013 ; poids faible b

;*******MACRO DEFINITION
AddRoll MACRO ; addition et roll via la carry de m_h à m_l
btfsc STATUS,C
addwf m_h,F ; addition de W
rrf m_h,F ; on passe par la carry
rrf m_l,F ; la valeur de C passe sur m_l<7>
ENDM

ORG 0x0000 ; processor reset vector


goto main ; go to beginning of program

ORG 0x0010
Mul8x8: ;* 2 cycles for call - instruction
;m_a * m_b => m_h:m_l
movf m_a, W ; m_a -> m_l
movwf m_l
movf m_b, W ; m_b -> W
clrf m_h ; 1 cycle
rrf m_l,F ; 1 cycle
; utilisation de la macro “AddRoll”
AddRoll ; 4 cycles
AddRoll
AddRoll
AddRoll
AddRoll
AddRoll
AddRoll
AddRoll
retlw 0 ; 2 cycles

main:
movlw .50
movwf m_a

movlw .10
movwf m_b
34. 5 %

call Mul8x8
END

>
34. 5 %

Annexes :
Extraits de la documentation Microchip PIC16C84

( $! GG # ($ # G @ 44? $

& ' ( )* * +, %,-.

8
34. 5 %

& " '/ ( ) ( +, %,-.0


34. 5 %

& 1'/ ( ) ( $2
34. 5 %

& . '/ ( )3 (
34. 5 %

& 4'/ ( 5 6)377 8 !"

@
34. 5 %

& % '/ ( 5 6)377 8 "!"

4
34. 5 %

& '9 3 ( ( +, %,:::

?
34. 5 %

& - '/ ( ( )) ( ( 2 ;< ( 2 <&