Aprés une semaine courte mais intense, me revoila !
Oui, effectivement ça m'intéresse de savoir pourquoi un moteur avec codeur ?
en attendant voici le code dont je parlai :
Ce code tourne sur des PIC type 16Fxxx et attaque sur la sortie PWM un 4017 monté en décodeur.
le schéma est celui utilisé sur la carte UC_vidéo décrite sur notre site
sch4017.jpg
sur le schéma ci-dessus ( un peu ancien ) il gère 4 servos, mais le code en gère 8.
le principe est de générer un train de pulse dont la première, plus large, va provoquer le reset du 4017
ensuite le compteur fait le reste, le code doit juste ajuster le temps entre chaque front de façon à ce qu'il corresponde aux pulses demandées.
Tout d'abord, les déclarations :
Code : Tout sélectionner
// frequence horloge du PIC= 4MHz
// definitions pour commande servos
#define NB_SERVOS 8 // IMPERATIVEMENT >1 !!!
#define PULSERVO_REF 187 // 3 ms pour le timer 2 ( 16uS/top )
#define PULSERVO_MIN 31 // 0,5 mS
#define PULSERVO_MAX 94 // 1,5 mS
#define PULSERVO_NEUTRE 62 // 1 mS valeur du neutre
#define PERIODE_REF 219 // 3,5 mS
#define DUREE_PULSE 16 // 0.25 mS
unsigned char SERVO[NB_SERVOS] ; // table contenant les tps de pulse pour chaque servo
unsigned char IndServo ; // indice de parcours de la table des pulses ( 0 = sync )
Ensuite une petite fonction d'init :
Code : Tout sélectionner
// ------------------------------------------------------------------------
// fonction d'init de tout le HARD associe au servos
void INIT_SERVO(void)
{
for(IndServo=0 ; IndServo<8 ; IndServo++ ) SERVO[IndServo]=PULSERVO_NEUTRE ;
IndServo=0 ;
PR2=PERIODE_REF ; // pulse de raz 4017
CCPR1L=PULSERVO_REF ;
// on utilise le mode PWM : le timer 2 ( PR2 ) fixe la periode
// et CCPR1L fixe le temps ou la sortie est a 1
CCP1CON=0x0F ; // valide mode pwm et les deux bits sup ?0
TRISB &=~0x08 ; // pin RB3 en sortie
// valide timer 2 avec prediviseur=16 , post=1
// soit 1 top = 16uS ( 4MHz )
T2CON=0x06 ;
TMR2=0 ; // raz timer et prescaler
PIE1|=0x02 ; // valide IT timer 2 ( TMR2=PR2 )
}
puis la fonction de gestion de l'interruption :
Code : Tout sélectionner
// ------------------------------------------------------------------------
// fonction d'interuption pour gestion cde servos
// IndServo donne la valeur de l'impulsion en cours ( 0 = reset , 1=servo 0 , ... )
#INT_TIMER2
IT_SERVO()
{
switch( IndServo )
{
case 0: // les suivantes sont des pulses de servos
CCPR1L=DUREE_PULSE; // valeur pulse suivante = pulse std
PR2=PERIODE_REF ; // periode = impulsion de reset ( reference )
IndServo++ ;
break ;
case NB_SERVOS: // prochaine = Pulse de REF
CCPR1L=PULSERVO_REF ; // prochaine pulse = ref
PR2=SERVO[NB_SERVOS-1]; // periode actuelle = derniere pulse servo
IndServo=0 ; // raz indice servo
break ;
default: // cas standard des pulses de servos
PR2=SERVO[IndServo-1] ; // periode = pulse servo courant
IndServo++ ;
break ;
}
}
pour utiliser, Il suffit d'appeller la fonction d'init au debut du main et d'écrire dans le tableau SERVO[] les valeurs désirées !