L’éditeur de liens ou « linker », intégré dans MPLAB, permet de relier plusieurs fichiers « .asm »;
autorisant ainsi la description d’une fonction complexe par assemblage de programmes simples. On pourra de cette manière créer et utiliser des bibliothèques de fonctions.
1 Directives d’assemblage
1.1 Code absolu
Jusqu’à présent, nous imposions à MPLAB :
- à quel endroit de la mémoire instructions nous souhaitions implanter notre code grâce à la directive « org »
org 0x0 ; Adresse de départ après reset goto debut
org 0x4 ; Adresse du vecteur d'interruption goto interrupt ; saut au sous programme d'interruption org 0x10 ; adresse de début du programme debut
- à quel endroit de la mémoire données et SFR nous souhaitions implanter nos variables grâce aux directives « EQU » et « CBLOK »
VAR EQU 0x20 ; VAR occupe l’adresse 20h
CBLOCK h'20' ; début de la zone en 20h en RAM INDEX :1 ;INDEX occupe un octet à l'adresse 20h
VAR1 :2 ;VAR1 occupe deux octets à l’adresse 21h et 22h
ENDC ; Fin de la zone
On parle alors de code absolu.
1.2 Code re localisable
Lorsque l’éditeur de liens doit lier plusieurs programmes, il faut lui préciser :
- où commence le code à mettre en mémoire instructions, au moyen de la directive « CODE » ; celle-ci laisse le champ libre à l’éditeur de lien de place le code qui suit où bon lui semble, excepté si une adresse est précisée (pour les resets et interruptions)
;********************************************************************************
; CODE ABSOLU *
;********************************************************************************
reset CODE 0x0000 ; Adresse de départ après reset goto debut
int CODE 0x0004 ; Adresse du vecteur d'interruption goto interrupt ; saut au sous programme d'interruption
;********************************************************************************
; PROGRAMME PRINCIPAL code re localisable *
;********************************************************************************
CODE
Denis Rabasté programmation des microcontrôleurs PIC 2/9 debut
instructions……….
- la déclaration des variables ; celle-ci se fait une seule fois par la directive « UDATA » dans un seul des fichiers ASM, même si cette variable est utilisée par d’autres fichiers :
UDATA
tension res 1 ; 1 octet réservé en RAM pour « tension » compteur res 2 ; 2 octets réservés en RAM pour « compteur »
Attention, il est impératif d’aller à la ligne après « UDATA » ;
- quelles ressources (variables, sous-programmes) sont utilisées par les autres programmes, au moyen de la directive « GLOBAL », même si la variable a été déclarée par « UDATA »
GLOBAL tension , init_can
; la variable tension et le sous-programme init_can sont utilisés dans un autre fichier
- quelles ressources sont générées par un autre programme, au moyen de la directive
« EXTERN »
EXTERN init_can , tension
; la variable tension est déclarée dans un autre fichier
; le sous-programme init_can est décrit dans autre fichier
L’éditeur de liens placera de lui-même tous ces éléments en mémoire, grâce à la description du plan mémoire du microcontrôleur, qui lui sera fournie dans un fichier « référence_micro.lkr ». Ce fichier se trouve dans « C:\ Program Files \ Microchip \ MPASM Suite \ LKR ».
2 Programmation d’une acquisition
Lors du TP sur la CAN, nous allumions les DELs du port B avec les bits de poids fort du résultat de l’acquisition par le CAN de la tension aux bornes du potentiomètre.
Nous allons reprendre cette fonction, mais cette fois en décomposant le fichier ASM en deux fichiers : - le premier initialisant les ports, le timer et gérant l’interruption générée par celui-ci ;
- le second initialisant le CAN et gérant l’acquisition des données.
Ouvrir un nouveau projet TP6_mplink pour PIC16F877A, y inclure les fichiers du répertoire
« Ressources \ TP6_mplink », ainsi que le fichier « 16f877a.lkr »( qui se trouve dans
« C:\ Program Files \ Microchip \ MPASM Suite \ LKR »), sauvegarder les fichiers ASM dans votre répertoire sous un nom différent, supprimer la version d’origine du projet.
Remarque :il est possible d’ajouter ultérieurement le fichier « 16f877a.lkr » dans le répertoire
« Linker Script » du navigateur de projet, grâce au menu contextuel de ce dossier. Le fait d’inclure ce fichier dans le projet active l’éditeur de liens.
Analyser les programme (reproduits en annexe), noter en particulier :
- dans quel fichiers sont déclarés les variables par la directive « UDATA » ;
- comment les ressources sont rendues utilisable par l’autre fichier grâce à la directive
« GLOBAL »’.
- comment sont déclarées les ressources arrivant de l’extérieur grâce à la directive
« EXTERN » ;
- l’utilisation de la directive « CODE » pour placer les instructions en mémoire programme, avec éventuellement l’imposition de l’adresse (pour le RESET et le vecteur d’interruption)
Compiler puis simuler le programme.
3 Programmer le circuit et vérifier le fonctionnement.
Programmation de l’affichage sur l’hyper terminal
Ajouter à votre projet le fichier « .asm » du TP précédent concernant l’envoi de données vers l’hyper terminal (sauvegarder sous un autre nom etc….).
Modifier les trois fichiers pour pouvoir afficher la valeur décimale de trois bits de poids fort sur l’hyper terminal.
Pour cela, il sera nécessaire de convertir la valeur binaire de ces trois bits en code ASCII (voir annexe 3) avant de l’envoyer.
Denis Rabasté programmation des microcontrôleurs PIC 4/9
Annexe 1 : programme
;********************************************************************************:
; programme principal,
; d'un ensemble permettant l'acquisition toutes les secondes
; par le CAN de la tension sur RA0
; dont les 4 bits de poids forts seront affichés sur les DEL du port B
;********************************************************************************
LIST P=16F877A ; directive qui définit le processeur utilisé
#include <P16F877A.INC> ; fichier de définition des constantes
;******************************************************************************
; BITS DE CONFIGURATION
;******************************************************************************
__CONFIG _HS_OSC & _WDT_OFF & _CP_OFF & _CPD_OFF & _LVP_OFF
;********************************************************************************
; DECLARATION DES RESSOURCES *
;********************************************************************************
EXTERN init_can , acquisition , tension
; ressources venant de l'extérieur
;********************************************************************************
; CODE ABSOLU *
;********************************************************************************
reset CODE 0x0000 ; Adresse de départ après reset goto debut
int CODE 0x0004 ; Adresse du vecteur d'interruption goto interrupt ; saut au sous programme d'interruption
;********************************************************************************
; PROGRAMME PRINCIPAL *
;********************************************************************************
CODE debut
call init_portb call init_timer call init_intrpt call init_can
boucle
goto boucle ; attente
;********************************************************************************
; SOUS PROGRAMMES *
;********************************************************************************
;********************************************************************************
; INITIALISATIONS *
;********************************************************************************
init_portb ; initialisation du PORTB en sortie
BANKSEL PORTB ; passage en banque 0
clrf PORTB ; RAZ des bascules D du port B
BANKSEL TRISB ; passage en banque 1
movlw b'00000000'
movwf TRISB ; PORTB en sortie
return
init_timer ; initialisation du Timer 1 :division par 8 BANKSEL T1CON ; passage en banque 0
movlw b'00110001' ; T1CGPS1=1 T1CGPS0=1 T1OSCEN=0 TMR1CS=0 TMR1ON=1 movwf T1CON ; predivision TMR1 timer 1:8, hor ext off, hor int
; timer on movlw 0x24
movwf TMR1L ; initialisation de TMR1L movlw 0xF4
movwf TMR1H ; initialisation de TMR1H return
init_intrpt ; initialisation des interruptions
BANKSEL PIE1 ; passage en banque 1
bsf PIE1,TMR1IE ; autorisation interruptions du timer 1
bsf INTCON,PEIE ; autorisation interruptions des périphériques bsf INTCON,GIE ; autorisation générale des interruptions return
;********************************************************************************
; INTERRUPTION *
;********************************************************************************
interrupt
call acquisition ; appel du sous programme d'acquisition swapf tension,w ; mise des 4 LSB dans les MSB de W movwf PORTB ; affichage en sortie
movlw 0x24
movwf TMR1L ; initialisation de TMR1L movlw 0xF4
movwf TMR1H ; initialisation de TMR1H
bcf PIR1,TMR1IF ; prépare pour l'interruption suivante retfie
;********************************************************************************
END
;********************************************************************************:
; Ce programme secondaire
; initialise le CAN et fait l'acquisition; *
;********************************************************************************
LIST P=16F877A ; directive qui définit le processeur utilisé
#include <P16F877A.INC> ; fichier de définition des constantes
;********************************************************************************
; DECLARATION DES RESSOURCES *
;********************************************************************************
UDATA
tension res 1 ; variable utilisée localement
GLOBAL tension , init_can, acquisition
; ressources utilisées dans un autre fichier
;********************************************************************************
; SOUS PROGRAMMES *
;********************************************************************************
CODE ; directive signalant le début des instructions
;********************************************************************************
; ACQUISITION *
Denis Rabasté programmation des microcontrôleurs PIC 6/9
;********************************************************************************
acquisition ; sous programme d'acquisition
bsf ADCON0,GO ; Lancement de la conversion Attente
btfsc ADCON0,GO ; fin de conversion ? goto Attente
movf ADRESH,w ; lecture résultat
movwf tension ; mise du résultat dans la variable tension return
;********************************************************************************
; INITIALISATION *
;********************************************************************************
init_can ; initialisation du CAN
BANKSEL ADCON0 ; passage en banque 0
movlw b'00000001' ; horloge Fosc/2 (ADCSx=0), sélection de RA0 (CHSx=0) movwf ADCON0 ; alimentation du CAN (ADON=0)
BANKSEL ADCON1 ; passage en banque 1
movlw b'00000000' ; 10 bits à gauche (ADFM=0) Fosc/2 (ADCS2=0)
movwf ADCON1 ; Entrée AN0 analogique Vref+=Vdd Vref-=Vss (PCFGx=0) BANKSEL ADCON0 ; retour en banque 0
return
;********************************************************************************
END
Annexe 2 : exemple de solutions
;********************************************************************************:
; programme principal,
; d'un ensemble permettant l'acquisition toute les secondes
; par le CAN de la tension sur RA0
; dont la valeur décimale des 3 bits de poids forts sera affichée
; sur l'hyper terminal windows *
;********************************************************************************
LIST P=16F877A ; directive qui définit le processeur utilisé
#include <P16F877A.INC> ; fichier de définition des constantes
;******************************************************************************
; BITS DE CONFIGURATION
;******************************************************************************
__CONFIG _HS_OSC & _WDT_OFF & _CP_OFF & _CPD_OFF & _LVP_OFF
;********************************************************************************
; DECLARATION DES RESSOURCES *
;********************************************************************************
UDATA
caract res 1 ; variable utilisée localement
EXTERN init_can , acquisition , init_usart, tension , emission
; ressources venant de l’extérieur
GLOBAL caract ; ressources utilisées par d'autres fichiers
;********************************************************************************
; CODE ABSOLU *
;********************************************************************************
reset CODE 0x0000 ; Adresse de départ après reset goto debut
int CODE 0x0004 ; Adresse du vecteur d'interruption goto interrupt ; saut au sous programme d'interruption
;********************************************************************************
; PROGRAMME PRINCIPAL *
;********************************************************************************
CODE debut
call init_portb call init_timer call init_intrpt call init_can call init_usart
boucle
goto boucle ; attente
;********************************************************************************
; SOUS PROGRAMMES *
;********************************************************************************
;********************************************************************************
; INITIALISATIONS *
;********************************************************************************
PAS DE CHANGEMENTS
Denis Rabasté programmation des microcontrôleurs PIC 8/9
;********************************************************************************
; INTERRUPTION *
;********************************************************************************
interrupt
call acquisition ; appel du sous programme d'acquisition swapf tension,f ; inversion 4 MSB /4 LSB
rrf tension, w ; les 3 MSB à droite
andlw b'00000111' ; suppression des autres bits
iorlw b'00110000' ; ajout de 30h pour avoir le caractère ascii movwf caract ; mise en place du caractère ascii
call emission ; envoi du caractère
movlw h'20' ; envoi d'un espace
movwf caract call emission movlw 0x24
movwf TMR1L ; initialisation de TMR1L movlw 0xF4
movwf TMR1L ; initialisation de TMR1H
bcf PIR1,TMR1IF ; prépare pour l'interruption suivante retfie
;********************************************************************************
END
;********************************************************************************:
; Ce programme secondaire envoi le code ASCII des 3 bits de poids fort
; de la tension à 9600 Bd via l'USART
;********************************************************************************
LIST P=16F877A F=INHX32 ; directive qui définit le processeur utilisé
; et le format des données envoyées
#include <P16F877A.INC> ; fichier de définition des constantes
;******************************************************************************
; DECLARATION DES RESSOURCES *
;******************************************************************************
GLOBAL init_usart , emission ; ressources utilisées dans un autre fichier EXTERN caract ; ressource arrivant d'un autre fichier
;********************************************************************************
; SOUS PROGRAMME *
;********************************************************************************
CODE ; directive signalant le début des instructions
;********************************************************************************
; INITIALISATION *
;********************************************************************************
init_usart
; initialisation du PORTC en entrée BANKSEL PORTC ; passage en banque 0
clrf PORTC ; RAZ des bascules D du port B BANKSEL TRISC ; passage en banque 1
movlw 0xFF
movwf TRISC ; PORTC en entrée pour utiliser l'usart
; initialisation de l'USART
BANKSEL SPBRG ; passage en banque 1
movlw d'25' ; avec BRGH=1, il faut 25 dans SPBRG pour 9,6 kBd movwf SPBRG
movlw h'24' ;
movwf TXSTA ; 8 bits, autorisé, asynchrone, haute vitesse BANKSEL RCSTA ; passage en banque 0
movlw h'80'
movwf RCSTA ; port série
return
;********************************************************************************
; EMISSION *
;********************************************************************************
emission
movf caract, w ; transfert de tension dans w
movwf TXREG ; le caractère dans W est prêt à être émis boucle_emission
btfss PIR1,TXIF ; attente de l'envoi du dernier bit goto boucle_emission
return END
Pas de changements sur le programme d’initialisation du CAN et d’acquisition des données.