























| |
Test des servomoteurs
Pour tester notre servo modifié nous allons utiliser
l'Ensemble de développement pour PIC16F84 de chez Robots Loisirs.
L'ensemble se compose d'une carte d'expérimentation et d'un
programmateur de pic. La carte est équipée d'une plaque d'expérimentation sans soudure. Ceci
permet d'effectuer des montages de test en un temps record.
On effectue le raccordement du servo en fil volant. Le PIC pourra être
reprogrammé en quelques secondes et à volonté.

Ci-dessous le schéma de raccordement du servo et la forme du signal en sortie
B0.

Pour ceux qui n'ont pas la notion du microcontrôleur PIC16F84, visitez la page http://perso.wanadoo.fr/yves.heilig/ElecRob/page1.htm
Comme dit, nous allons utiliser le compilateur CCS pour écrire notre programme
de test en C.
Le programme de test va faire tourner le servo dans un sens, puis va l'arrêter,
puis va le faire tourner dans l'autre sens. Dans un premier temps à la vitesse
maxi puis à vitesse réduite. Et ceci indéfiniment.
Voici le programme.
//*************************************
// CCS Compiler
// Commande servomoteur
//
// Auteur : HEILIG Yves
//*************************************
#include <16f84.h>
#fuses HS,NOWDT,NOPROTECT
#use delay(clock=20000000)
//*******************
// variables globales
//*******************
int16 COMPTEUR1;
int COMPTEUR2, SENS;
int1 SIGNAL;
//******************
// DEFINE
//******************
#define TIME 4 // TIMER=3 --> 256-3=253 pas
#define 18MS 360 // 360*50=18000µs
#define AV 40 // 40*50 =2000µs
#define AR 20 // 20*50 =1000µs
#define AVP 32 // 32*50 =1600µs
#define ARP 28 // 28*50 =1400µs
#define STOP 30 // 30*50 =1500µs
#define PORT_SIGNAL PIN_B0
//******************
//Interruptions
//******************
#int_timer0 // Interruption toutes les (4*250)/20000000 = 50µs
main_int () {
set_timer0(TIME);
if (++COMPTEUR1 == 360) {
COMPTEUR1=0;
COMPTEUR2=0;
SIGNAL=1;
output_high(PORT_SIGNAL);
}
else {
if (SIGNAL==1) {
if (COMPTEUR2++ == SENS) {
SIGNAL=0;
output_low(PORT_SIGNAL);
}
}
}
}
//**********************
// Fonctions
//**********************
void init_timer () {
set_timer0(TIME);
setup_counters(RTCC_INTERNAL,WDT_18MS);
enable_interrupts(INT_RTCC);
enable_interrupts(GLOBAL);
}
//**********************
// Programme principal
//**********************
main() {
init_timer();
while (TRUE) { // boucle sans fin
SENS=AV; // en avant pendant 3"
delay_ms(3000);
SENS=STOP; // stop 1"
delay_ms(1000);
SENS=AR; // en arrière 3"
delay_ms(3000);
SENS=STOP; // stop
delay_ms(1000);
SENS=AVP; // en avant petite vitesse 3"
delay_ms(3000);
SENS=STOP; // stop
delay_ms(1000);
SENS=ARP; // en arrière petite vitesse
delay_ms(3000);
SENS=STOP; // stop
delay_ms(1000);
}
}
Quelques explications s'imposent.
Le principe utilisé est de générer une interruption toutes les 50µs. Lors de
chaque interruption l'on incrémente COMPTEUR1. Lorsque COMPTEUR1 atteint la
valeur de 360, 18ms (360*50) se seront écoulées.
On met la sortie B0 à 1 et on démarre un deuxième compeur COMPTEUR2 qui lui
aussi est incrémenté toutes les 50µs. COMPTEUR2 détermine la durée de
l'impulsion (entre 1 et 2ms). Lorsque COMPTEUR2 aura atteint la valeur seuil
(ex: 30 pour 1.5ms (30*50)) la sortie B0 repasse à 0.
En ce qui concerne la structure du programme. Tout ce qui est après les // est
du commentaire.
Le programme principal démarre à "main ()".
On configure le TIMER0 (init_timer) afin qu'il génère une interruption à
chaque passage par 0. Le TIMER est un compteur 8bits qui est incrémenté à
chaque cycle d'instruction (1 cycle d'intruction = 4 cycles d'horloge). Il
compte de 0 jusqu'à 255, puis repasse à 0 et ainsi de suite...
Dans notre cas on le fait compter de 4 jusqu'à 255, puis 0. Ceci afin d'obtenir
notre interruption toutes les 50µs.
La formule est la suivante (4*250/20000000)=50µs. Vous me direz (enfin pour
ceux qui suivent )
255-4 ne donne pas 250, mais 251. Il faut faire une légère correction, car
lorsque la routine d'interruption est appelée il se passe quelques ns avant que
le TIMER soit assigné à 4 et recommence à s'incrémenter.
A chaque interruption du programme principal la routine "main_int()"
est appelée. C'est cette routine qui génère le signal pour notre servo.
Notre servo tourne bien comme prévu. Nous allons pouvoir passer à la suite.
|