lundi 15 juillet 2013

msp430 launchpad, partie 7

Contrôle d'un servo-moteur

Sujets traités:

  • Ajustement fin de la fréquence du DCO
  • Utilisation d'une minuterie pour contrôler un servo-moteur

Dans cet article je traite de 2 sujets, le premier consiste à ajuster la fréquence du DCO pour obtenir une fréquence en dehors des calibrations fournis par TI. Le deuxième consiste à utiliser une minuterie pour générer le signal PWM qui contrôle le servo-moteur. Le programme démo consiste à lire le voltage d'un potentiomètre branché sur P1.0 et à faire en sorte que la position du servo-moteur suive la position du potentiomètre. Les impulsions qui contrôle le servo sont sortie sur P2.1.

schéma du circuit

La rotation du servo-moteur suis la rotation de RV1.

Configuration de la minuterie

Les registres spéciaux utilisés par une minuterie de type A sont les suivants:

  • TAxCTL fonctionnement général de la minuterie, choix de l'horloge du diviseur, etc.
  • TAxR c'est le compteur 16 bits utilisé par la minuterie.
  • TAxCCTLy registre de contrôle du mode capture ou comparateur pour le registre CCRy
  • CCRy registre qui contient la valeur de comparaison avec TAxR
  • TAxIV registre identifiant la source de l'interruption puisqu'un seul vecteur partage 3 interruptions.
NOTE: 'x' identifie la minuterie 0 ou 1. 'y' identifie le registre comparateur 0,1,2.

Le programme utilise la minuterie no. 1 (TA1). Comme expliqué précédemment chaque minuterie à 3 registres de comparaisons CCRy. Les étapes de configurations d'une minuterie sont les suivantes:
configuration générale de la minuterie par le registre TA1CTL

  1. Choisir le signal source horloge qui va contrôler la minuterie.
  2. Choisir un diviseur pour ce signal.
  3. Choisir le mode de contrôle de la minuterie:
    1. STOP la minuterie est arrêté.
    2. UP TAxR est incrémenté jusqu'à la valeur de CCR0 et recommence à zéro. CCR0 détermine donc la période=Tclk*CCR0
    3. CONTINUOUS TAxR est incrémenté jusqu'à la valeur maximale 0xFFFF et recommence à zéro. Période fixe de longueur maximale=Tclk*65536.
    4. UP/DOWN TAxR est incrémenté jusqu'à la valeur de CCR0 et ensuite décrémenté vers zéro. Période=Tclk*2*CCR0
  4. Choisir s'il y aura une interruption sur débordement du compteur.

Ensuite pour chacun des registres CCRy il y a un registre à configurer TA1CCTLy
  1. Type d'utilisation capture ou comparateur
  2. Pour le mode comparaison choisir le type de sortie. C'est à dire ce qui arrive lorsque le compteur atteint la valeur qui est dans CCRy
    • Mode 0 output, la valeur de la broche de sortie est déterminée par le bit OUTx du registre TAxCCTLy.
    • Mode 1 set, lorsque TAxR atteint CCRy la sortie passe à 1 et y reste jusqu'à un reset du MCU ou un changement de configuration du mode minuterie.
    • Mode 2, Toggle/Reset, la sortie est inversée lorsque TAxR==CCRy et remise à zéro lorsque TAxR==CCR0 (fin de période).
    • Mode 3, Set/Reset, la sortie est mise à 1 lorsque TAxR==CCRy et remise à zéro lorsque TAxR==CCR0.
    • Mode 4, Toggle, la sortie est inversée à chaque fois que TAxR==CCRy. La période du signal de sortie est donc le double de la période du compteur TAxR.
    • Mode 5, Reset, la sortie est mise à zéro lorsque TAxR==CCRy et y reste jusqu'à réinitialisation du MCU ou reprogrammation de la minuterie.
    • Mode 6, Toggle/Set, la sortie est inversée lorsque TAxR==CCRy et est mise à 1 lorsque TAxR==CCR0, on obtient donc un signal complémentaire à celui du mode 2.
    • Mode 7, Reset/Set, la sortie est mise à zéro lorsque TAxR==CCRy et mise à 1 lorsque TAxR==CCR0, on obtient donc un signal complémentaire du mode 3.
  3. Choisir si on veut déclencher une interruption lorsqu'il y a égalité TAxR==CCRy

Code source

Description

La minuterie TA1 est alimenté par SMCLK et fonctionne en mode UP. La sortie est en mode reset/set ce qui donne un signal inverse de celui utilisé par le servo-moteur. Ceci est nécessaire car le transistor Q1 va réinverser ce signal de sorte que le la ligne de contrôle du servo-moteur aura le bon signal, soit une série d'impulsions d'une durée qui varie de 400µsec à 2400µsec se répétant à toutes les 20millisecondes.

Le périphérique ADC10 est utilisé pour lire la valeur du potentiomètre branché sur P1.0. A chaque période du signal servo, une série de 8 lectures du potentiomètre est faite et la moyenne est utilisée pour contrôler la largeur de l'impulstion PWM du servo.

Quelques calculs simples

Le servo-moteur utilisé (Hitec HS-420) est conçu pour être contrôlé par une série d'impulsions dont la largeur minimale est de 400µsec et la largeur maximal de 2400µsec. La valeur centrale est de 1500µsec. Ces impulsions doivent se répétées à toutes les 20millisecondes. Pour que le PWM puisse utiliser les 16 bits du compteur TA1R il faut que la fréquence qui alimente TA1R soit exactement de 65536*Tclk. Où Tclk est la période du signal SMCLK. On obtient donc que le DCO doit fonctionner à 3,28Mhz. Dans le manuel du MSP430G2553 il y a une table avec les valeurs qui servent à configurer les registres DCOCTL et BCSCTL1 pour obtenir la fréquence désirée. Notez que ces valeurs sont approximatives et ne servent qu'à titre indicatif. A partir de cette table DCO frequency j'ai utilisé les valeurs RSELx=10 (range select), DCOx=2 (step selector) et en utilisant un oscilloscope j'ai mesuré la fréquence de sortie du signal PWM sur P2.1. J'ai ajusté la valeur MODx (modulator) pour obtenir 50Hz.

Pour calculer les valeurs MIN_PULSE, MAX_PULSE et CENTER_PULSE il s'agit d'une simple règle de 3.
N=pulse_width/20000*65536
N valeur à mettre dans TA1CCR1.
pulse_width largeur de l'impulsion en µsec.
20000 période PWM en µsec.

la ligne de code suivante nécessite peut-être une explication:

TA1CCR1=MIN_PULSE+(v_mean>>1)+(v_mean>>2);

v_mean contient la somme des 8 échantillons ADC10. Pour obtenir la valeur moyenne il faut diviser cette valeur par 8. Mais je dois multiplier cette valeur moyenne par 6 pour ajuster correctement la valeur à mettre dans TA1CCR1. donc au lieu de divisé par 8, je divise par 2 et par 4 et j'additionne les 2 valeurs ainsi obtenues1. Le résultat est le même mais j'ai éviter l'utilisation de routines de multiplication et division qui auraient occupées plus d'espace de code et seraient plus lentes d'exécution.
NOTE 1: multiplié par 6 = *4 + *2 et diviser par 8 pour ensuite multiplier par 4 est idem à diviser par 2...

Quant à la valeur 6 il s'agit simplement du rapport entre l'intervalle des lectures ADC10 (1023) et de l'intervalle MAX_PULSE - MIN_PULSE. Donc en prenant la valeur lu par ADC10 puis en la multipliant par 6 et en ajoutant à MIN_PULSE, la largeur des impulsions est maintenue dans les spécifications du servo-moteur.

Aucun commentaire:

Publier un commentaire