TD Microcontrôleur, famille PIC
Exercices de programmation en assembleur ! " ## $ % &&##' " %' % &%%# $ $ $ &&## " $ ( ) *% + #$ , -./ % & #+%' " (( $ $ ) $# 0% ##' " % # + ,%' % +%/' " % ! % + ,#$' $#1' 2/ -.
I – Table de retour de fonction
#include
; processor specific variable definitions __CONFIG __CONF IG _CP_OFF & _WDT _WDT_OFF _OFF & _PWRTE _PWRTE_ON _ON & _RC_OS _RC_OSC C org 0x0000 goto main org 0x0010 HexaTo7Segments: addwf PCL, f retlw b'00111111' retlw b'00000110' retlw b'01011011' retlw b'01001111' retlw b'01100110' retlw b'01101101' retlw b'01111101' retlw b'00000111' retlw b'01111111' retlw b'01101111'
;decode ;decode ;decode ;decode ;decode ;decode ;decode ;decode ;decode ;decode
0 1 2 3 4 5 6 7 8 9
main: // init portB bsf STATUS, RP0 ; bank1 movlw 0x00 movwf TRISB ; PORTB en sortie bcf STATUS, RP0 ; bank0 movlw call movwf
5; Exemple .... HexaTo7Segments PORTB
END
3 4 .5%
!! ! ! ! "# $"# %! & ' #6# ( 7% $% & ' # $% 8 % 9 :
% % 4 +' % 8 % $% 8 % ; % % ## ( 0 $ $% #7%' # ! <
% ## $&## < ## $&## $# = % % ; >4 ,>= $% >/ $&## $ 7% % ## %' % #+
% # ! ??
II – Adressage indexé ( ! ! ) * + ,- . / + 0 ,- !! / / ! 1 *22 3 4 #include ; processor specific variable definitions __CONFIG __CONF IG _CP_OFF & _WDT_OFF _WDT_OFF & _PWRTE_ON _PWRTE_ON & _RC_OS _RC_OSC C ;***** 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 ; go to beginning of program goto main
3 4 .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 movwf
; on récupère l'adresse de v2 (0x18) v2 p_v2
movlw movwf
s ; idem avec s 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 = 1 ; fin nop END
+ 45 ! 6"#. 6"#. *#. 4#. '. $"# ?? , / 45 !7 )((%- %8 ( . ∈ 9"#:$"#; 3 2 3 5 @
3 4 .5%
A$ $% $% % % ,#' #% &%%' % $(&' 2/' $% & &% , % % %#7% % % % %#7% &7%/' 2
- ! ) ! ∈ 9"#:<="#; 3 = <
$+1# & % B C 8D ) B C >D ) $ #6# % % % $ !" !" ! ! $% !" $% !"'' # #include ; processor specific variable definitions __CONFIG __CONFI G _CP_OFF _CP_OF F & _W _WDT_OFF DT_OFF & _PWRTE_ON _PWRTE_ON & _RC_OS _RC_OSC C
;***** VARIABLE DEFINITIONS org 0x2100 ; 10 0001 0000 0000 (14 bits) : adresse EEPROM ; de permet de stocker des valeurs (ou variables) en EEPROM de t_sinus .0, .9, .18, .27, .36, .45 de .54, .62, .71, .79, .88, .96 de .104, .112, .120, .12 8, .128, .136, .143 de .150, .157, .164, .17 1, .171, .178, .184 de .190, .196, .201, .20 7, .207, .212, .217 de .221, .226, .230, .23 3, .233, .237, .240 de .243, .246, .248, .25 0, .250, .252, .253 de .254, .255, .255, .255 ; variable en RAM sinus_indice equ 0x0010 tmp_W equ 0x0011 ;******************************************************************* *** ; processor reset vector 0x0000 ORG 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
3 4 .5%
; division par 2 rrf sinus_indice, f
STATUS, RP0 ; bank 0 t_sinus ; debut de la table ; + offset (indice) ; sinus_indice, W
bcf movlw addwf
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 ; processor specific variable definitions __CONFIG __CONF IG _CP_OFF & _WDT_OFF _WDT_OFF & _PWRTE_ON _PWRTE_ON & _RC_OS _RC_OSC C ;***** VARIABLE DEFINITIONS ah equ 0x0010 ; poids fort a al equ 0x0011 ; poids faible bh equ 0x0012 ; poids fort b bl equ 0x0013 ; poids faible sh equ 0x0014 ; poids fort s sl equ 0x0015 ; poids faible
a b (resultat) s
;**************************************************************** ; processor reset vector ORG 0x0000 goto main ; go to beginning of program ORG
0x0010
Add16:
?
3 4 .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 movwf movlw movwf call ; LED ? bcf btfsc bsf
H'FF' bl H'D0' bh Add16 PORTB, 0 ; LED éteinte STATUS, C PORTB, 0 ; LED allumée
; goto main … nop END
3 4 .5%
IV – Arithmétique : Multiplication 8 bits 3 ) ) ! ! = + <5 * = ! ! ( ;%% % ! $% #$ E F $$ ) $% $ % +% : % $% $ ,#$ 4 A 0$$2/ ! #include ; processor specific variable definitions __CONFIG __CONF IG _CP_OFF & _WDT _WDT_OFF _OFF & _PWRTE _PWRTE_ON _ON & _RC_OS _RC_OSC C ;***** 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 goto
0x0000 main
; processor reset vector ; 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 ; 1 cycle clrf m_h 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 movwf
.50 m_a
movlw movwf
.10 m_b
3 4 .5%
call Mul8x8 END
>
3 4 .5%
Annexes : Extraits de la documentation Microchip PIC16C84 ($!GG#($#G@44?$
& ' ( ) ** +, %,-. %,-.
8
3 4 .5%
& " ' /() ( +,%,-.0
3 4 .5%
& 1' /() ( $2
3 4 .5%
& . ' /( )3 (
3 4 .5%
& 4' /( 5 6 )3778 !"
@
3 4 .5%
& % ' /( 5 6 )3778 "!"
4
3 4 .5%
& ' 9 3(( +, %,:::
?
3 4 .5%
& - ' /( ()) (( 2;< ( 2<&