Documente Academic
Documente Profesional
Documente Cultură
GOMBERT Benjamin
VENCE Eric
Gp. P205
A – DESCRIPTION DU PROJET 04
PRINCIPE DE FONCTIONNEMENT 04
GUIDE D’UTILISATION 06
B – CONCEPTION MATÉRIELLE 08
SCHÉMA BLOC 09
DÉTAILS TECHNIQUES 09
Adaptateur d’entrée 09
CAN 11
Microcontrôleur 18
Afficheur et Driver 19
Clavier 19
CNA 20
Adaptateur de sortie 27
RÉALISATION 29
Nomenclature 29
Schéma de câblage 30
Procédures de tests 31
Montage final 33
ORGANISATION DU PROGRAMME
ET FORMATAGE DES DONNÉES 34
CONFIGURATION DU PIC 38
Affectation des entrées/sorties 39
Assignation des registres de configuration 40
INITIALISATIONS 54
Initialisation des ports 54
Initialisation des registres d’interruptions 55
Initialisation des variables 55
ROUTINES 56
CAN 56
Addition 57
Soustraction 58
Multiplication 58
Calcul du P.I.D. 60
Conversion de chiffres en digits 66
Conversion des paramètres en digits 68
Affichage (transmission série des données) 69
PROGRAMME PRINCIPAL 71
D – SYNTHÈSE 72
AMÉLIORATIONS ENVISAGÉES 72
E – SOURCES 73
e e Micro- s
+ CNA MCC
- Contrôleur
r
Capteur
Principe de fonctionnement
Un correcteur alliant la combinaison des trois actions P.I.D. peut être assimilé à
un correcteur série au sein d’un système.
La première consiste à dire que plus l'erreur est grande et positive et plus il faut
augmenter la tension aux bornes du moteur (pour rattraper cette erreur). La
tension aux bornes du moteur est alors directement proportionnelle à l'erreur.
On a donc : u( t ) = K p .e( t )
Kp étant un coefficient de proportionnalité.
On voit cependant apparaître des problèmes. Il faut une certaine tension aux
† du moteur pour que celui-ci puisse se lancer. En régime permanent,
bornes
l'erreur ne sera plus assez grande pour pouvoir faire avancer le moteur. Il y aura
donc une erreur qui subsistera et nous n'atteindrons pas exactement la position
souhaitée (erreur d'ordre 0). De même, pour qu'il puisse y avoir un mouvement,
il sera nécessaire que le moteur soit alimenté, et donc qu'il y ait une erreur.
C'est pourquoi, on ajoute un autre élément qui va augmenter la tension aux
bornes du moteur lorsque l'erreur reste constante. À chaque période, on va
sommer l'erreur (intégration de l'erreur). Donc, si l'erreur reste constante, sa
somme va augmenter au fil du temps. On a alors :
1 t
u( t ) = K p .e( t ) + Ú e(t )dt
Ki 0
La valeur Ki est un coefficient qui va déterminer l'influence de ce paramètre
intégral.
† une tension au moteur, il met un certain temps à réagir
Lorsque l'on applique
(constante de temps mécanique). Pendant ce temps l’erreur continue à
augmenter et la tension aux bornes du moteur croît alors que cela n'est pas
nécessaire. Pour diminuer ce phénomène, nous introduisons un 3ème élément
qui permet d'en limiter les effets (il est souvent fait référence pour ce terme à la
notion de viscosité, en augmentant ce terme c'est comme si on augmentait la
viscosité de la réaction, on trempe le tout dans un liquide de plus en plus
visqueux). On se base sur la différence (la variation) de l'erreur entre 2
mesures. Il s'agit de la dérivée de l'erreur. On obtient au final l’équation du
P.I.D. :
1 t de ( t )
u( t ) = K p .e( t ) + Ú
Ki 0
e(t ) dt + K d
dt
Avec Kd étant le coefficient du paramètre dérivé.
Il faut s’assurer que toutes les alimentations sont bien branchées, surtout au
niveau du +12 et –12V (jaune et bleue) afin de ne pas créer de différences de
potentiels trop importantes au sein du circuit général. C’est à partir de ce
moment-là que l’on peut allumer l’alimentation et basculer l’interrupteur général
du montage sur la position ON.
Après avoir réglé le GBF, on le relie à l’aide de câbles coaxiaux branchés sur
les fiches BNC. On branche un oscilloscope en sortie pour visualiser le signal
corrigé. Le signal d’entrée ne peut excéder +5V et –5V et il doit rester en basses
fréquences (50 Hz par exemple).
Une fois la maquette alimentée et un signal d’entrée injecté, il faut appuyer sur
le bouton “Reset” pour démarrer la conversion analogique-numérique et par
conséquent la correction P.I.D. Les paramètres sont directement visualisés sur
l’afficheur LCD. Quatre digits sont utilisés, de gauche à droite : Kp, Ki, Kd et la
limite d’intégration de l’asservissement. Le clavier est composé de 3 boutons
(“+”, “-“, “v” pour valider). Une première pression sur “v” permet d’activer le
mode de sélection du paramètre à modifier. On se déplace sur l’afficheur à
l’aide des boutons “+” pour aller à gauche, et “-“ pour aller à droite. Une fois le
Le cahier des charges nous impose d’utiliser certains composants. Ils ont été
choisis pour leurs caractéristiques techniques et les performances nécessaires
à la bonne exécution du système.
Détails techniques
Adaptateurs d’entrée
Conversion [+5v ; -5v] => [+5v ; 0v]
Équation à réaliser : Vs =
(Ve + 5)
2
R1 = R2 = R5= R6
R3 = R4
R3 = 2 R1
Une fois les calculs théoriques effectués, nous avons simulé l’ensemble du
montage d’adaptation à l’aide du logiciel Design Capture. Voici les courbes que
nous obtenons après simulation :
Par exemple, si on utilise un CAN 8 bits, ce CAN ne pourra fournir que 255
valeurs différentes. La plus petite différence de tension mesurable à ses bornes
va être fonction de la plage de mesure en tension utilisée. Si la tension est
comprise entre 0 et 5V, la mesure minimale correspond à : 5/255 = 19,6mV. On
dira que la résolution d’un CAN 8 bits pour une tension de plage de mesure de
5V est de 19,6mV.
On utilise dans ce projet un CAN 10 bits (celui contenu dans le PIC 16F876)
pour convertir le signal d’entrée. Néanmoins un CAN 8 bits aurait suffi car on
néglige les deux bits les moins significatif lors de la correction effectuée par le
PIC.
Le registre ADCON0 :
- Bits CHS2, CHS1, CHS0 : les bits de sélection du canal analogique à mesurer.
Avant toute conversion, il faut définir quel est le canal qui va être utilisé pour
cette conversion. Ceci se fait grâce à ces 3 bits selon le tableau suivant :
Ce bit n’est actif que si le bit ADON=1, c'est-à-dire si le module CAN est actif. Il
sert à lancer la conversion : en mettant ce bit à 1, on lance la conversion à partir
de la voie analogique sélectionnée par les bits CHS2, CHS1 et CHS0.
Ce bit sert à “allumer” le module CAN. Si ADON=0, le module CAN est inactif. Si
le bit ADON=1, le module est opérationnel.
Le registre ADCON0 :
- Bits PCFG0 , CFG1, PCFG2 et PCFG3 : Bits de configuration des ports A (en
analogique ou numérique).
Les broches des ports A (à l’exception de PA4) peuvent être configurées soit en
analogique soit en numérique.
Lorsqu’une broche de ce port est configurée en analogique, elle devient un des
canaux de mesure utilisables par le CAN. Lorsqu’elle est configurée en
numérique, elle est une broche E/S comme les autres broches des autres ports.
Le microcontrôleur que nous utilisons est un 16F876. Il a été choisi pour ses
caractéristiques techniques intéressantes.
Il possède une mémoire RAM de 368 octets, une EEPROM de 256 octets ainsi
qu’une FLASH de 8 kilo-octets. Cela nous assure un espace suffisant pour
stocker et exécuter le programme afin de traiter le signal à corriger.
En plus des entrées/sorties programmables et des interruptions, il possède
certaines ressources internes telles que :
- Un convertisseur analogique-numérique 10 bits qui envoie directement les
échantillons du signal à traiter aux registres internes du PIC afin
d’effectuer la correction P.I.D. L’intégration de ce CAN simplifie le
routage, évite des problèmes de compatibilité et fait gagner de la place
au montage.
- Des timers. Nous utiliserons le timer 1 pour gérer le clignotement du
curseur. Le timer 1 est un compteur 16 bits. Lorsqu’il est couplé à notre
oscillateur de 4MHz avec un pré-diviseur égal à 8 on obtient une
interruption toutes les 0,5 secondes. La période de clignotement sera
donc d’une seconde.
- Des liaisons séries SCI, I2C, SPI qui ne sont pas utilisées dans le cadre de
ce projet.
- Des sorties P.W.M. (Modulation de Largeur d'Impulsion) si l’on veut
effectuer une commande numérique par exemple.
Il est piloté par le PIC qui lui transmet un signal d’horloge qui cadence l’envoi
des données à afficher.
Clavier
CNA
Principe de fonctionnement
Définitions
Résolution
Plage de conversion
Dynamique
La dynamique d'un signal est le rapport entre la tension maxi et la tension mini
que pourra prendre ce signal.
Mise en relation
D'après ce qui a été dit sur la plage de conversion, la relation entre le pas de
quantification (1 LSB), la plage de conversion VMAX et le nombre de bits du
convertisseur sera légèrement différente de l'équation suivante en pratique. La
figure du paragraphe suivant va éclairer cette équation :
DVMAX
LSB =
2N
Cette figure montre la fonction de transfert d'un CNA 3 bits ayant une résolution
de 1V. On voit clairement ici ce qui a été dit pour la plage de conversion : la
plage s'étend de 0 à 7V, et non pas 8V comme pour le CAN, car le dernier état
numérique est "7".
ERREURS DE CONVERSION
Erreur de gain
Erreur d'offset
Erreur d'offset.
Erreurs de linéarité
L'erreur de linéarité est due au fait que la résolution des convertisseurs n'est
pas constante. On distingue deux formes de non-linéarité :
La valeur donnée dans les spécifications des constructeurs est la plus grande
valeur constatée sur toute la plage de conversion.
La non linéarité différentielle est plus gênante que la non linéarité intégrale,
surtout dans le cas de mesures comparatives effectuées sur une faible partie de
la plage de conversion. En général, et pour des causes technologiques, le
maximum de non linéarité différentielle se trouve à la moitié de la pleine échelle
(passage du MSB – bit le plus significatif - de 0 à 1), et ensuite à moindre
degré à 1/4 et 3/4 de la pleine échelle. Il faut donc rester vigilant lors de
mesures dans ces zones.
Monotonicité
Temps d'établissement
Temps d'établissement
Précision du convertisseur
Adaptateur de sortie
†
ESME Sudria p.26/72
2003
On utilise à nouveau deux AOP en série. Le premier en tant qu’amplificateur
inverseur et le second en montage sommateur.
La borne V-, du premier AOP, reçoit en entrée le signal de sortie du CNA, et
celle du second AOP est connectée à la sortie du premier. Les bornes V+ des
deux AOP sont reliées à la masse.
R2 = 4 R1
et
R3 = R4 = R5
Une fois de plus après avoir effectué les calculs théoriques nous avons simulé
l’ensemble et voici les résultats obtenus :
Réalisation
Nomenclature
Nb Référence Désignation
1 PIC 16F876 Microcontrôleur RISC 8 bits
1 AD557 Convertisseur Numérique Analogique 8 bits
1 MM5452 Contrôleur LCD
1 vi-502 Afficheur LCD 7 segments - 4 digits
1 TL084 AOP jfet (x4 AOP)
1 Support tulipe 28 broches
1 Support tulipe 16 broches (7,5 mm)
2 Support tulipe 40 broches
1 Support tulipe 14 broches (7,5 mm)
6 Support tulipe 8 broches (7,5 mm)
2 Support tulipe barrette de 32 broches
2 470 Ω Résistance
1 5 kΩ Résistance
10 10 kΩ Résistance
3 20 kΩ Résistance
1 50 kΩ Résistance
2 15 pF Condensateur
1 15 pF Condensateur
1 10 nF Condensateur
1 47 µF Condensateur
1 100 µF Condensateur
5 100 nF Condensateur
1 Quartz 4MHz
1 Interrupteur ON/OFF
4 Bouton poussoir
1 Led verte Ø3 mm
1 Led rouge Ø3 mm
15 m Fil rouge (5V)
15 m Fil noir (5V)
15 m Fil vert (5V)
1 Bornier ( IN & OUT coax. / +5v / +12v / -12v / GND )
Pour tester l’action dérivée il faut injecter un signal triangulaire en entrée et nous
devons récupérer en sortie un signal carré.
Recto
Verso
La tension du signal d’entrée du module P.I.D. réalisé varie entre -5V et +5V. Il
est donc nécessaire grâce à un adaptateur d’étalonner ce signal entre 0 et 5V
pour l’injecter dans le CAN. À chaque valeur de tension correspondra une
valeur numérique. Le paragraphe suivant à pour but d’expliquer le processus de
formatage des données et les correspondances entre les valeurs analogiques et
numériques.
Le CAN échantillonne sur 10 bits un signal initial compris entre -5V et +5V.
-5V 0
-5V 0
-5V -127
0 -5V
Configuration du PIC :
Création d’une en-tête regroupant les principales
informations du programme :
Celle-ci est facultative, mais elle peut s’avérer très utile pour la mise en œuvre
du PIC dans un circuit. Elle regroupe des informations essentielles :
- le nom du fichier (celui ci doit être compilé puis injecté dans le PIC),
- la liste des fichiers à inclure dans le projet pour que la compilation soit
possible (dans notre cas, il s’agit du fichier librairie : « P16F876.inc »),
- la fréquence de l’oscillateur externe pour laquelle est conçu ce programme
(ici : 4 MHz),
- l’affectation des ports d’entrées-sorties pour le câblage du PIC.
;***************************************************************************************
;* *
;* Réalisation d'un asservissement PID *
;* *
;***************************************************************************************
;* *
;* NOM: projet.asm *
;* Date: 23/05/2003 *
;* Auteurs: BRUYERE Philippe - GOMBERT Benjamin - VENCE Eric *
;* Groupe de projet : P205 *
;* *
;***************************************************************************************
;* *
;* Fichiers requis: P16F876.inc *
;* *
;***************************************************************************************
;* *
;* Notes: On utilise un oscillateur 4 MHz *
;* Les 8 bits de sortie sont disponibles après correction sur le PORTC *
;* L'affichage des paramètres est transmis par la sortie série du PORTB *
;* Les boutons poussoir génèrent des interruptions sur les entrées *
;* RB4 à RB6 du PORTB *
;* *
;***************************************************************************************
Directive “CONFIG” :
La directive CONFIG permet de configurer le compilateur pour que celui-ci
reconnaisse chacun des paramètres de programmation du PIC sans qu’il ne soit
nécessaire de les préciser à chaque fois. Cette directive permet notamment de
déclarer le type d’oscillateur utilisé ainsi que les différents modes de protection
utilisés par le PIC et sa mémoire.
__CONFIG _CP_OFF & _DEBUG_OFF & _WRT_ENABLE_OFF & _CPD_OFF & _LVP_OFF &
_BODEN_OFF & _PWRTE_ON & _WDT_OFF & _XT_OSC
; _CP_OFF Pas de protection
; _DEBUG_OFF RB6 et RB7 en utilisation normale
; _WRT_ENABLE_OFF Le programme ne peut pas écrire dans la flash
; _CPD_OFF Mémoire EEprom déprotégée
; _LVP_OFF RB3 en utilisation normale
; _BODEN_OFF Reset tension hors service
; _PWRTE_ON Démarrage temporisé
; _WDT_OFF Watchdog hors service
; _XT_OSC Oscillateur XT
;*********************************************************************************
;* ASSIGNATIONS SYSTEME *
;*********************************************************************************
;*********************************************************************************
;* MACROS *
;*********************************************************************************
; Changement de banques
; --------------------------------
;****************************************************************************
; VARIABLES ZONE COMMUNE *
;****************************************************************************
; Zone de 16 bytes
; -----------------------
CBLOCK 0x70 ; Début de la zone (0x70 à 0x7F)
w_temp : 1 ; Sauvegarde registre W
status_temp : 1 ; Sauvegarde registre STATUS
digit1 : 1 ; définition des 7 segments (+ virgule) du 1er digit
digit2 : 1 ; définition des 7 segments (+ virgule) du 2nd digit
digit3 : 1 ; définition des 7 segments (+ virgule) du 3ème digit
digit4 : 1 ; définition des 7 segments (+ virgule) du 4ème digit
ENDC ; Fin de la zone
;****************************************************************************
;* DECLARATIONS DES VARIABLES *
;****************************************************************************
; Zone de 80 bytes
; ----------------------- ; Allocation de l'espace mémoire de la bank0 et déclaration des variables
CBLOCK 0x20 ; Début de la zone (0x20 à 0x6F)
menu : 1 ; pointeur de menu
choixParam : 1 ; Variable de choix du paramètre à modifier
; u(k) = Kp £(k) + Ki [u(k-1)+£(k)] + Kd [£(k)-£(k-1)]
cligno : 1 ; Variable d'état de clignotement
parametre1 : 1 ; paramètre n°1 : Kp
parametre2 : 1 ; paramètre n°2 : Ki
parametre3 : 1 ; paramètre n°3 : Kd
parametre4 : 1 ; paramètre n°4 : Limite d'intégration
cmpt1 : 1 ; compteur n°1
cmpt2 : 1 ; compteur n°2
resultConv : 1 ; résultat 8 bits de la conversion Analogique -> Numérique
resultConv2 : 1 ; ancien résultat 8 bits de la conversion Analogique -> Numérique
result1 : 1 ; résultat du calcul de la proportionnelle
result2 : 1 ; résultat du calcul de la dérivée
result3 : 1 ; résultat du calcul de l'intégrale
result4 : 1 ; somme de result1 et result2
;*************************************************************************
;* DEMARRAGE SUR RESET *
;*************************************************************************
org 0x000 ; Adresse de départ après reset
goto INIT ; Initialiser
;*************************************************************************
;* ROUTINE INTERRUPTION *
;*************************************************************************
;sauvegarder les registres
;-------------------------------
org 0x004 ; adresse d'interruption
movwf w_temp ; sauver registre W
swapf STATUS,w ; swap status avec résultat dans w
movwf status_temp ; sauver status swappé
BANK0 ; passer en banque0
Pour tester les interruptions générées par le « TIMER1 », il faut vérifier que le
masque d’interruption « TMR1IE » soit activé (attention, ce registre se trouve
dans la banque 1). Il suffit ensuite de lire le « flag » d’interruption « TMR1IF »
(banque 0). Si une interruption sur le timer 1 est détectée, la sous-routine de
traitement « INTTMR » est appelée puis le flag d’interruption est effacé.
; Interruption TMR1
INT2 ; -----------------------
bsf STATUS,RP0 ; sélectionner banque1
btfss PIE1,TMR1IE ; tester si interruption autorisée
goto RESTORE ; non sauter
bcf STATUS,RP0 ; oui, sélectionner banque0
btfss PIR1,TMR1IF ; oui, tester si interruption en cours
goto RESTORE ; non sauter
call INTTMR1 ; oui, traiter interruption TMR1
bcf PIR1,TMR1IF ; effacer flag interruption
; Restaurer registres
RESTORE ; -----------------------
swapf status_temp,w ; swap ancien status, résultat dans w
movwf STATUS ; restaurer status
swapf w_temp,f ; Inversion L et H de l'ancien W sans modifier Z
swapf w_temp,w ; Ré-inversion de L et H dans W (W restauré sans modifier status)
retfie ; return from interruption
TESTMENU2
decfsz menu,f ; décrémenter le pointeur de menu
goto TESTMENU3 ; menu != 0 ?
goto TESTV2
TESTM2
btfss sourceInt,5 ; bit RB5=1 ?
goto TESTV2
movf parametre2,w
btfsc STATUS,Z ; tester si W = 0
movlw 0x0A ; si parametre2 = 0, on boucle le menu en remettant parametre2 = 10
movwf parametre2
decf parametre2,f ; oui -> interruption sur le PB2 [-] -> on décrémente le paramètre 2
TESTV2
movlw 0x02
btfss sourceInt,6 ; bit RB6=1 ?
goto TESTF2
movlw 0x00 ; oui -> interruption sur le PB3 [V] -> on passe au menu 0
clrf choixParam
TESTF2
movwf menu ; passage au menu en vigueur
goto FINMENU
TESTMENU3
decfsz menu,f ; décrémenter le pointeur de menu
goto TESTMENU4 ; menu != 0 ?
goto TESTV3
TESTM3
btfss sourceInt,5 ; bit RB5=1 ?
goto TESTV3
movf parametre3,w
btfsc STATUS,Z ; tester si W = 0
movlw 0x0A ; si parametre3 = 0, on boucle le menu en remettant parametre3 = 10
movwf parametre3
decf parametre3,f ; oui -> interruption sur le PB2 [-] -> on décrémente le paramètre 3
TESTV3
movlw 0x03
btfss sourceInt,6 ; bit RB6=1 ?
goto TESTF3
movlw 0x00 ; oui -> interruption sur le PB3 [V] -> on passe au menu 0
clrf choixParam
TESTF3
movwf menu ; passage au menu en vigueur
goto FINMENU
TESTMENU4
decfsz menu,f ; décrémenter le pointeur de menu
goto TESTMENU5 ; menu != 0 ?
goto TESTV4
TESTM4
btfss sourceInt,5 ; bit RB5=1 ?
goto TESTV4
movf parametre4,w
btfsc STATUS,Z ; tester si W = 0
movlw 0x0A ; si parametre4 = 0, on boucle le menu en remettant parametre4 = 10
movwf parametre4
decf parametre4,f ; oui -> interruption sur le PB2 [-] -> on décrémente le paramètre 4
TESTV4
movlw 0x04
btfss sourceInt,6 ; bit RB6=1 ?
goto TESTF4
movlw 0x00 ; oui -> interruption sur le PB3 [V] -> on passe au menu 0
clrf choixParam
TESTF4
movwf menu ; passage au menu en vigueur
goto FINMENU
TESTMENU5
decfsz menu,f ; décrémenter le pointeur de menu
goto TESTMENU0 ; menu != 0 ?
goto FINMENU
TESTMENU0
; MENU 0 : Menu de statique : attente d'une interruption
; --------------------------------------------------------------------------
btfss sourceInt,6 ; bit RB6=1 ?
goto FINMENU
movlw 0x05
movwf menu ; passage au choix du paramètre à modifier (menu 5)
movlw 0x01
movwf choixParam ; initialisation du pointeur du paramètre à modifier
FINMENU
TESTMENU0
; MENU 0 : Menu de statique : attente d'une interruption
; ------------------------------------------------------------------------
btfss sourceInt,6 ; bit RB6=1 ?
goto FINMENU
movlw 0x05
movwf menu ; passage au choix du paramètre à modifier (menu 5)
movlw 0x01
movwf choixParam ; initialisation du pointeur du paramètre à modifier
Une fois toutes les possibilités de menus testées, et une fois le menu en cours
traité, le programme appelle la routine « AFFICHAGE » pour qu’elle rafraîchisse
les valeurs transmises à l’afficheur LCD.
FINMENU
;*************************************************************************
;* INTERRUPTION TIMER 1 *
;*************************************************************************
INTTMR1
decfsz cligno,f ; tester la valeur de "cligno"
goto TESTPARAM0 ; cligno != 1
movf choixParam,w ; cligno = 1
movwf varparam
movlw 0x02
movwf cligno ; passage au choix du paramètre à modifier (menu 5)
TESTPARAM2
decfsz varparam,f ; décrémenter le pointeur de paramètre
goto TESTPARAM3 ; choixParam != 0 ?
movf parametre2,w ; conversion de parametre2 (chiffres) en digit2 (7 segments)
movwf vardigit
call CONVDIGIT
movwf digit2
movlw 0x00
movwf digit1 ; digit1 vide
movwf digit3 ; digit3 vide
movwf digit4 ; digit4 vide
goto FINPARAM
TESTPARAM3
decfsz varparam,f ; décrémenter le pointeur de paramètre
goto TESTPARAM4 ; choixParam != 0 ?
movf parametre3,w ; conversion de parametre3 (chiffres) en digit3 (7 segments)
movwf vardigit
call CONVDIGIT
movwf digit3
movlw 0x00
movwf digit1 ; digit1 vide
movwf digit2 ; digit2 vide
movwf digit4 ; digit4 vide
goto FINPARAM
TESTPARAM4
decfsz varparam,f ; décrémenter le pointeur de paramètre
goto TESTPARAM0 ; choixParam != 0 ?
goto FINPARAM
TESTPARAM0
call CONVPARAM
FINPARAM
Initialisations :
Initialisation des ports :
Dans cette partie, tous les registres nécessaires à la configuration des ports
sont initialisés avec les valeurs qui leur ont été assignées au début du
programme. Ainsi les entrées et sorties de chaque port sont définies (registres
« TRISA », « TRISB » et « TRISC »). L’entrée analogique est configurée par les
registres « ADCON0 » et « ADCON1 ». Les sorties sont mises à ‘0’ pour éviter
les valeurs aléatoires.
;*************************************************************************
;* INITIALISATIONS *
;*************************************************************************
INIT
; initialisation PORTS (banques 0 et 1)
; -------------------------------------------------
BANK0 ; sélectionner la banque0
clrf PORTA ; Sorties PORTA à 0
clrf PORTB ; Sorties PORTB à 0
clrf PORTC ; Sorties PORTC à 0
movlw ADCON0VAL ; Configuration du mode digital/analogique
movwf ADCON0 ; écriture dans le registre de contrôle A/D
bsf STATUS,RP0 ; sélectionner banque1
movlw ADCON1VAL ; PORTA en mode digital/analogique
movwf ADCON1 ; écriture dans le registre de contrôle A/D
movlw DIRPORTA ; Direction PORTA
movwf TRISA ; écriture dans le registre direction
movlw DIRPORTB ; Direction PORTB
movwf TRISB ; écriture dans le registre direction
movlw DIRPORTC ; Direction PORTC
movwf TRISC ; écriture dans le registre direction
; initialisation variables
; -----------------------------
clrf menu ; initialisation de « menu » pour qu’il pointe vers le menu général
clrf choixParam ; initialisation du de la variable de choix du paramètre à modifier
clrf parametre1 ; initialisation du paramètre n°1 : Kp
clrf parametre2 ; initialisation du paramètre n°2 : Ki
clrf parametre3 ; initialisation du paramètre n°3 : Kd
clrf parametre4 ; initialisation du paramètre n°4 : Limite d'intégration
movlw 0x02
movwf cligno ; initialisation de la variable d'état de clignotement
clrf resultConv ; initialisation de la variable de conversion A/N
clrf resultPID2 ; initialisation de la variable de calcul du PID
Conversion analogique-numérique :
Cette routine réalise l’échantillonnage sur une entrée analogique. La conversion
se fait en plusieurs étapes :
- la valeur de l’échantillon précédent est mémorisée (car elle est nécessaire au
calcul du PID),
- le convertisseur est activé par la mise à ‘1’ de « ADON »,
- attente de la fin de l’acquisition (le convertisseur intégré au PIC a un temps
d’acquisition Tacq = 19,7µs),
- la conversion analogique numérique débute lors de la mise à ‘1’ de « GO »,
- attente de la fin de la conversion (le convertisseur intégré au PIC a un temps
de conversion Tad = 3,2µs),
- lecture de la valeur de l’échantillon. Chaque échantillon est stocké sur 10 bits
dans la paire de registres « ADRESH » et « ADRESL ». La justification étant
faite à gauche, et pour des raisons de commodité, on n’exploite que les 8 bits
de poids fort que l’on trouve dans le registre « ADRESH ».
;*****************************************************************
;* CONVERSION Analogique -> Numérique *
;*****************************************************************
;* entrée : *
;* *
;* sortie : resultConv *
;* *
;*****************************************************************
CONV
movf resultConv,w ; Chargement du résultat de la conversion précédente
movwf resultConv2 ; Stockage de l'ancien résultat de la conversion
bsf ADCON0,ADON
bsf ADCON0,GO
Addition :
La routine « ADDI » réalise l’addition des chiffres stockés dans les variables
« var1 » et « var2 ». L’addition est effectuée par l’instruction « addwf », mais
l’utilisation de cette routine permet de détecter les dépassements en
interrogeant le registre « STATUS,C ». Le résultat est alors stocké dans deux
octets, « sommeL » contenant les 8 bits de poids faible et « sommeH »
contenant les éventuels dépassements.
;*****************************************************************
;* ADDITION 8 bits *
;* avec gestion du dépassement *
;*****************************************************************
;* entrées : var1 (8 bits) ] variables d'entrée non *
;* var2 (8 bits) ] modifiées par le programme *
;* *
;* sortie : sommeL (8 bits) *
;* sommeH (8 bits pour le dépassement de capacité) *
;* *
;*****************************************************************
;* var1 + var2 -> [sommeL ; sommeH] *
;*****************************************************************
ADDI
clrf sommeH ; effacer dépassement
movf var1,w ; charger la variable n°1 dans w
movwf sommeL ; sauver dans sommeL
movf var2,w ; charger la variable n°2 dans w
addwf sommeL,f ; ajouter w et sommeL puis stocker dans somme
btfsc STATUS,C ; tester si bit de dépassement = 1
incfsz sommeH,f ; oui, ajouter au résultat poids fort
return
;*****************************************************************
;* SOUSTRACTION 8 bits *
;*****************************************************************
;* entrées : var1 (8 bits) ] variables d'entrée non *
;* var2 (8 bits) ] modifiées par le programme *
;* *
;* sorties : diffL (8 bits) *
;* signe,0 bit de signe du résultat *
;* *
;*****************************************************************
;* var1 - var2 -> (signe) diffL *
;*****************************************************************
SOUSTRAC
bcf signe,0 ; effacer le bit de signe
movf var1,w ; charger la variable n°1 dans w
movwf diffL ; sauver dans diffL
movf var2,w ; charger la variable n°2 dans w
subwf diffL,f ; soustraire w à diffL puis stocker dans diffL
btfss STATUS,C ; tester si bit de dépassement = 0 , le résultat est donc négatif
goto COMP ; si résultat <0 , on cherche le complément à 2
return
return
Multiplication :
La routine « MULTI » multiplie « var1 » et « var2 ». Le résultat nécessite donc
16 bits, donc 2 octets « produitH » et « produitL ».
Pour illustrer le principe de fonctionnement, voici la réalisation d’une
multiplication manuelle. Nous multiplions ici 12 par 13, c’est une opération de
4x4 bits avec un résultat sur 8 bits. Ceci afin de simplifier l’explication.
Le tableau suivant montre que pour programmer une multiplication, il suffit de
multiplier les bits un à un en effectuant un décalage à gauche lors du
chargement d’un nouveau bit multiplicateur.
1 1 0 0 12
0 0 0 0 0 0
1 1 0 0 0 0 48
1 1 0 0 0 0 0 96
1 0 0 1 1 1 0 0 156
;*****************************************************************
;* MULTIPLICATION 8 x 8 bits *
;*****************************************************************
;* entrées : var1 (8 bits) ] variables d'entrée non *
;* var2 (8 bits) ] modifiées par le programme *
;* *
;* résultat sur 16 bits : produitH (8 bits de poids fort) *
;* produitL (8 bits de poids faible) *
;* *
;*****************************************************************
;* var1 * var2 -> [produitH ; produitL] *
;*****************************************************************
MULTI
clrf produitH ; effacer le résultat poids fort
clrf produitL ; effacer le résultat poids faible
movlw 0x08 ; pour 8 bits
movwf cmpt1 ; initialiser compteur de boucles
movf var1,w ; charger le multiplicateur n°1 dans w
movwf vartemp ; sauver dans vartemp
movf var2,w ; charger le multiplicateur n°2 dans w
LOOPMULTI
rrf vartemp,f ; décaler le multiplicateur vers la droite
btfsc STATUS,C ; tester si bit sorti = 1
addwf produitH,f ; oui, ajouter au résultat poids fort
rrf produitH,f ; décaler le résultat poids fort
rrf produitL,f ; décaler le résultat poids faible
decfsz cmpt1,f ; décrémenter le compteur de boucles
goto LOOPMULTI ; pas fini, bit suivant
return
;*****************************************************************
;* Calcul du PID *
;*****************************************************************
;* entrées : resultConv, resultConv2, resultPID2 *
;* parametre1, parametre2, parametre3, parametre4 *
;* signe *
;* *
;* sorties : resultPID *
;* signe, resultPID2, resultConv2 *
;*****************************************************************
;* u(k) = Kp £(k) + Ki [u(k-1)+£(k)] + Kd [£(k)-£(k-1)] *
;*****************************************************************
PID ; resultPID = [ parametre1 + parametre2 + parametre3 ] * resultConv
; + parametre2 * resultPID2 - parametre3 * resultConv2
; -1 < parametre1, parametre2, parametre3 < 10
; signe,1 contient le signe de resultConv centré sur 0 = signe de result1
; signe,2 contient le signe de resultConv2 centré sur 0 = signe de result3
; signe,3 contient le signe de resultPID centré sur 0
; signe,4 contient le signe de resultPID2 centré sur 0 = signe de result2
; signe,5 contient le signe de result4
La valeur des échantillons est codée sur 8 bits (registre « ADRESH »). Cette
valeur correspond à une tension comprise entre –5V et +5V. Il est donc
nécessaire d’étalonner les données avant de commencer à résoudre l’équation.
L’étalonnage est effectué comme nous l’avons précédemment défini dans la
partie « étalonnage des données ». Cela consiste simplement à recentrer les
données sur ‘0’, c’est-à-dire soustraire ‘127’ à la variable d’entrée.
incf resultDep,f
decfsz resultDep,f ; tester la valeur de resultDep
goto TRAITDEP3 ; resultDep =! 0
goto SKIPDEP3 ; resultDep = 0
TRAITDEP3
movf resultDep,w ; charger resultDep dans w
btfsc STATUS,Z ; tester si w = 0
goto DEPASSNEG ; resultDep < 0 => on écrète le signal à sa valeur min : 0
; resultDep > 0 => on écrète le signal à sa valeur max : 255
movlw D'255' ; il y a dépassement positif => charger '255' dans w
goto SUITECR4
DEPASSNEG
movlw D'0' ; il y a dépassement négatif => charger '0' dans w
goto SUITECR4
SKIPDEP3
Le calcul du PID est maintenant réalisé, cependant cette valeur doit être
décentrée conformément au formatage des données défini précédemment.
; 7) Décentrer la valeur du signal corrigé pour qu'il soit compris entre 0 et 255
; ---------------------------------------------------------------------------------------------------
; -127 < resultPID < +128 => 0 < resultPID + 127 < 255
; => -5V < E(k) < +5V
return
;*****************************************************************
;* CONVERSION Chiffres -> Digits *
;*****************************************************************
;* entrée : vardigit *
;* *
;* sortie : w *
;*****************************************************************
CONVDIGIT
btfss STATUS,Z ; tester si W = 0
goto DIGITUN
movlw ZERO
goto FINCONV
DIGITUN
decfsz vardigit,f ; décrémenter le chiffre à traiter
goto DIGITDEUX
movlw UN ; var1 = 0 ?
goto FINCONV
DIGITDEUX
decfsz vardigit,f ; décrémenter le chiffre à traiter
goto DIGITTROIS
movlw DEUX ; var1 = 0 ?
goto FINCONV
DIGITTROIS
decfsz vardigit,f ; décrémenter le chiffre à traiter
goto DIGITQUATRE
movlw TROIS ; var1 = 0 ?
goto FINCONV
DIGITQUATRE
decfsz vardigit,f ; décrémenter le chiffre à traiter
goto DIGITCINQ
movlw QUATRE ; var1 = 0 ?
goto FINCONV
DIGITCINQ
decfsz vardigit,f ; décrémenter le chiffre à traiter
goto DIGITSIX
movlw CINQ ; var1 = 0 ?
goto FINCONV
DIGITSEPT
decfsz vardigit,f ; décrémenter le chiffre à traiter
goto DIGITHUIT
movlw SEPT ; var1 = 0 ?
goto FINCONV
DIGITHUIT
decfsz vardigit,f ; décrémenter le chiffre à traiter
goto DIGITNEUF
movlw HUIT ; var1 = 0 ?
goto FINCONV
DIGITNEUF
decfsz vardigit,f ; décrémenter le chiffre à traiter
goto DIGITERROR
movlw NEUF ; var1 = 0 ?
goto FINCONV
DIGITERROR
movlw TRAIT
FINCONV
return
;*****************************************************************
;* CONVERSION des paramètres en digits *
;*****************************************************************
;* entrées : parametre1, parametre2, parametre3, parametre4 *
;* *
;* sorties : digit1, digit2, digit3, digit4 *
;* *
;*****************************************************************
CONVPARAM
return
;*****************************************************************
;* AFFICHAGE (transmission série des données) *
;*****************************************************************
;* entrées : digit1, digit2, digit3, digit4 *
;* *
;* sortie : *
;* *
;*****************************************************************
AFFICHAGE
movlw B'00000100' ; charger les bits permettants de compléter la série de 36 bits transmis
movwf vartemp ; stocker l'octet à transmettre dans vartemp
movlw 0x03 ; 3 boucles pour transmettre les 3 bits manquants
movwf cmpt1 ; initialiser compteur de boucles
LOOPAFF2
rrf vartemp,f ; décaler vers la droite
bcf PORTB,0 ; Mise à 0 du signal CLOCK
btfsc STATUS,C ; tester le bit de dépassement C
bsf PORTB,1 ; C=1 -> Mise à 1 du signal DATA
btfss STATUS,C ; tester le bit de dépassement C
bcf PORTB,1 ; C=0 -> Mise à 0 du signal DATA
nop
bsf PORTB,0 ; Mise à 1 du signal CLOCK
return
AFFDIGIT
movwf vartemp ; stocker l'octet à transmettre dans vartemp
return
;*********************************************************************************
;* PROGRAMME PRINCIPAL *
;*********************************************************************************
START
org 0x300
CALL AFFICHAGE ; routine d'affichage des paramètres sur l'afficheur LCD (initialisation)
movwf PORTC ; Ecriture sur le PORTC des 8 bits du résultat du calcul du PID
goto LOOP
end
- La programmation du P.I.D.
- Les conversions analogique-numérique et numérique-analogique.
- Les adaptateurs de tensions.
- La gestion des boutons-poussoirs.
- L’affichage, sur un écran LCD à 4 digits, des paramètres de correction du
P.I.D. par l’intermédiaire d’un driver LCD.
Améliorations envisagées
- www.abcelectronique.com
- kudelsko.free.fr
- fribotte.free.fr/bdtech/PidSurPic/PidSurPic1.html
- perso.wanadoo.fr/yves.heilig/ElecRob/page1.htm
REMERCIEMENTS
Nous tenons à remercier M. Touseau et M. Aït Abderrahim pour leur aide, leurs
conseils, leur disponibilité et l’encadrement qu’ils nous ont accordé tout au long
de ce projet.