Exemple d'un programme écrit en langage d'assemblage PIC


Le programme suivant rassemblent les leçons décrites dans le 44-Pin Demo Board User's Guide de Microchip, 2007.

; Auteur : Richard St-Denis, Universite de Sherbrooke, 2013.

        LIST     P=18F45K20,F=INHX32   ; processeur, little-endian
        #include <P18F45K20.INC>       ; inclusion de symboles

        CONFIG FOSC=INTIO7, PBADEN=OFF, DEBUG=OFF, WDTEN=OFF, PWRT=OFF
;
; Definition des donnees
;
        CBLOCK 0x00C
               dcnt1 : 1       ; compteur de delai interne
               dcnt2 : 1       ; compteur de delai externe
               direction : 1   ; direction de rotation des DEL
               ledno : 1       ; numero de DEL a allumer
               tIntcnt : 1     ; compteur de delai de l'horloge (interruption)
               W_tmp : 1       ; espace de sauvegarde pour le contexte courant
               STATUS_tmp : 1
        ENDC

        ORG     0x000          ; point d'entre sur reinitialisation (reset)
        goto    main

        ORG     0x0008         ; adresse du vecteur d'interruption
        goto    ISR
;
; Configuration des DEL
;
InitLEDs:
        clrf    TRISD          ; positionner les broches E/S du port D en sortie
        clrf    LATD           ; eteindre les DEL
        return
;
; Configuration du bouton poussoir
;
InitSW:
        clrf    TRISB          ; positionner les broches E/S du port B en sortie
        bsf     TRISB,RB0      ; positionner la broche E/S numero 0 du port B en entree
        return
;
; Configuration du convertisseur analogue-digital (ADC)
;
InitAnalog:
        clrf    TRISA          ; positionner les broches E/S du port A en sortie
        bsf     TRISA,RA0      ; positionner la broche E/S numero 0 du port A en entree
        clrf    ANSEL
        bsf     ANSEL,ANS0     ; configurer le port A comme un dispositif analogue
        clrf    ADCON0         ; options : canal AN0
        bsf     ADCON0,6       ; A/D conversion : Fosc/8
        bsf     ADCON0,ADON    ; activer ADC
        clrf    ADCON1         ; options : justification à gauche, Vss et Vdd
        return
;
; Configurer l'horloge
;
InitTimer0:
        bsf     T0CON,TMR0ON   ; activer Timer0
        bsf     T0CON,T08BIT   ; horloge 8 bits (0=16 bits; 1=8 bits)
        bcf     T0CON,T0CS     ; source de l'horloge: horloge interne au processeur
        bcf     T0CON,PSA      ; choisir le compteur
        bsf     T0CON,T0PS2    ; positionner l'echelle du compteur 1:128 (110)
        bsf     T0CON,T0PS1
        bcf     T0CON,T0PS0

        bcf     INTCON,T0IF    ; nettoyer l'indicateur de debordement
        bsf     INTCON,TMR0IE  ; activer les interruptions du Timer0
        return
;
; Configuration de l'affichage d'une DEL
;
InitDisplay:
        movlw   D'1'
        movwf   direction      ; direction vers la gauche (0-7)
        movlw   0X80           ; choisir la DEL numero 7
        movwf   ledno
        return
;
; Fonction de delai implementee a l'aide de deux compteurs
;
DelayLoopC:
        movwf   dcnt2
dlc00:
        decfsz  dcnt1,f
        goto    dlc00
        decfsz  dcnt2,f
        goto    dlc00
        return
;
; Fonction de delai implementee a l'aide d'une horloge (interruption)
;
DelayLoopIntT:
        movlw   D'32'          ; pour environ 4 secondes
        movwf   tIntcnt
        clrf    TMR0           ; initialisation du compteur a 0
        bsf     INTCON,GIE     ; activer l'interruption globale
dlit00:
        movf    tIntcnt,w
        bnz     dlit00
        bcf     INTCON,GIE     ; inhiber l'interruption globale
        return
;
; Fonction de delai implementee a l'aide d'une horloge (interrogation)
;
DelayLoopT:
        movlw   D'32'          ; pour environ 4 secondes
        movwf   tIntcnt
dlt00:
        clrf    TMR0           ; initialisation du compteur a 0
dlt05:
        movf    TMR0,w
        xorlw   D'250'
        btfss   STATUS,Z
        goto    dlt05
        decfsz  tIntcnt,f
        goto    dlt00
        return
;
; Sous-programme de service d'interruption
;
ISR:
        movwf   W_tmp          ; sauvegarder le contexte courant
        movff   STATUS,STATUS_tmp

        btfsc   INTCON,T0IF    ; source de l'interruption != Timer0
        goto    Timer0_int
                               ; ignorer les autres sources d'interruption
        movf    STATUS_tmp,w   ; retablir le contexte
        movwf   STATUS
        swapf   W_tmp,f
        swapf   W_tmp,w
        return                 ; retour simple, sans activer les interruptions

Timer0_int:
        decf    tIntcnt
        bcf     INTCON,T0IF    ; nettoyer l'indicateur de debordement

        movf    STATUS_tmp,w   ; retablir le contexte
        movwf   STATUS
        swapf   W_tmp,f
        swapf   W_tmp,w
        retfie                 ; retour et activer l'interruption globale
;
; Programme principal
;
main:
        call    InitLEDs
        call    InitSW
        call    InitAnalog
        call    InitTimer0
        call    InitDisplay
main00:
        btfsc   PORTB,RB0      ; attendre un evenement du bouton-poussoir
        goto    main00
        call    DelayLoopT     ; OR DelayLoopIntT (pour test d'interruption)
main05:
        bsf     ADCON0,GO      ; demarrer ADC
main06:
        btfsc   ADCON0,GO_DONE ; ADC complete?
        goto    main06

        bcf     STATUS,C       ; nettoyer le bit de report
        btfsc   direction,0
        goto    RotateLeft
RotateRight:
        rrcf    ledno,f
        btfsc   STATUS,C       ; Fin d'un tour?
        bsf     ledno,7        ; positionner le bit numero 7
        goto    main10
RotateLeft:
        rlcf    ledno,f
        btfsc   STATUS,C       ; Fin d'un tour?
        bsf     ledno,0        ; positionner le bit numero 0
main10:
        movf    ledno,w
        movwf   LATD           ; eteindre une DEL
        movf    ADRESH,w       ; delai par rapport a ADC
        addlw   1              ; ajuster la valeur de conversion
        call    DelayLoopC     ; delai d'attente

        btfss   PORTB,RB0      ; tester le bouton-poussoir
        goto    main15
        goto    main05
main15:
        movlw   D'1'           ; changer de direction
        xorwf   direction,f
        goto    main05
        END


Sous MPLAB X IDE v1.00, les instructions suivantes permettent la création d'un fichier .asm.

  1. Choisissez le menu File
  2. Choisissez l'item New File...
  3. Choisissez l'onglet Assembler dans la sous-fenêtre Choose File Type (step 1)
  4. Choisissez l'extension asm dans la sous-fenêtre Name and Location (step 2)

Sous MPLAB X IDE v1.00, les instructions suivantes permettent la configuration du dispositif PIC18F45K20.

  1. Cliquez sur le bouton de droite de la souris sous le nom du projet
  2. Choisissez l'item Set Configuration dans le menu
  3. Choisissez l'item Customize... dans le sous-menu
  4. Choisissez Conf: [default] dans la sous-fenêtre Categories
    • Dans la sous-fenêtre Configuration, choisissez PIC18F45K20 comme Device
  5. Choisissez PICkit 3 dans la sous-fenêtre Categories
    • Dans l'option Memories to Program, choisissez Allow PICkit 3 to Select Memories pour Auto select memories and ranges
    • Dans l'option Power, cliquez sur la case à cocher Power target circuit from PICkit 3 et choisissez 3.25 for Voltage Level

Sous MPLAB X IDE v1.00, les instructions suivantes permettent la compilation, le chargement et l'exécution du programme.

  1. Choisissez le menu Run
  2. Choisissez l'item Clean and Build Project (project name)
  3. Cliquez sur l'icône Make and Program Device (Project name)
  4. Dans le dialogue d'alerte, cliquez sur le boutonOK, si PIC18F45K20 apparaît dans le message