Question du signal d’horloge du contrôleur de moteur pas à pas L297

20317

Question du signal d’horloge du contrôleur de moteur pas à pas L297


Comment puis-je générer un signal d’horloge vers le contrôleur de moteur pas à pas L297 avec un microcontrôleur PIC16f877?:

entrez la description de l'image ici

Réponses


 Oli Glaser

Si vous voulez dire l’entrée HORLOGE, alors pour une seule étape, vous pouvez simplement régler la broche basse pendant une courte période (pour un minimum de 0,5us selon la fiche technique , donc quelque chose comme 10us ferait), puis régler à nouveau haut.

Pour un flux d’impulsions, vous pouvez alors utiliser le périphérique PWM (ou Timer). Vous pouvez écrire une fonction qui prend le nombre d’étapes et la vitesse comme arguments, puis définit le périphérique pour pulser ce nombre de fois, incrémentant le nombre dans la routine de service d’interruption (ISR)

Cela libère votre boucle principale de tout le travail.

Si vous avez besoin d’un exemple de code, faites-le moi savoir et je posterai quelque chose.

Exemple de code

Voici un code basé sur le périphérique Timer 1 et Compare Peripheral.

Le
stepper_step(5, 50);configure 5 impulsions à 50 Hz. Fondamentalement, il définit la broche au début de la période de minuterie (ajustée par la variable de vitesse) puis l’efface en utilisant le périphérique de comparaison 1/10 de la période plus tard. Une variable de comptage garde une trace du nombre d’étapes. J’ai utilisé le compilateur XC8:

/* 
 * File:   stepper_pulse_example_2.c
 * Author: Oli Glaser
 *
 * Created on 26 March 2013, 08:00
 */

#include <xc.h>
// Turn the Watchdog Timer off
#pragma config WDTE = OFF

/* Defines */
#define FOSC 4000000L
#define FCY (FOSC/4)L
#define TMR_MAX 65535
#define HZ 62500

/* Function definitions */
void delay(int d);
void init(void);
void stepper_step(unsigned int count, unsigned int speed);

/* Global variables */
unsigned int stepper_count = 0;
unsigned int stepper_speed = 0;
unsigned int stepper_pulse = 0;

/* Main */
int main(int argc, char** argv) {

    // Initialisation routine
    init(); 

    while(1) // Infinite loop
    {
        delay(1000);
        // Step 5 times at 50Hz
        stepper_step(5, 50);
    }
}

/* Interrupt Service Routine */
void interrupt int_routine(void)
{
    // Check it's Timer 1 that has interrupted
    if (PIE1bits.TMR1IE && PIR1bits.TMR1IF)
    {
        PIR1bits.TMR1IF = 0;            // Clear interrupt flag
        T1CONbits.TMR1ON = 0;           // Turn timer off to reset count register
        TMR1H = (stepper_speed >> 8);   // Set Timer registers
        TMR1L = (stepper_speed & 0x00FF);
        T1CONbits.TMR1ON = 1;           // Turn timer back on

        stepper_count--;        // decrement pulse count
        PIR1bits.CCP1IF = 0;    // Clear compare flag
        CCP1CON = 0x00;         // Reset Compare peripheral
        // Set for Compare mode: set pin and then clear pin on match
        if(stepper_count) CCP1CONbits.CCP1M = 0b1001; 
        CCPR1H = (stepper_pulse >> 8);  // Set clear pin timing
        CCPR1L = (stepper_pulse & 0x00FF);

        // Have pulses completed?
        if(stepper_count == 0)
        {
            T1CONbits.TMR1ON = 0;   // Turn Timer 1 off
            CCP1CON = 0x00;         // Reset Compare peripheral
            PORTCbits.RC5 = 0;      // Make sure pin is left low
        }
    }
    // process other interrupt sources here, if required
}

/* Initialisation routine */
void init(void)
{
    // Make all pins digital
    ANSEL = 0;
    ANSELH = 0;
    TRISCbits.TRISC5 = 1; // Disable RC5 output driver till PWM configured
    CCP1CON = 0x00; // Reset CCP Peripheral    
    PIR1bits.TMR1IF = 0;    // Clear Timer 1 interrupt flag
    PIR1bits.CCP1IF = 0;    // Clear Compare interrupt flag

    // Setup Timer 1 
    T1CON = 0;
    T1CONbits.T1CKPS0 = 1;  // T1CKPS = 11 = 1:8 prescaler
    T1CONbits.T1CKPS1 = 1;  // so timer clock = 1MHz / 8 = 125kHz
    /* Timer 1 clock is 125kHz, so for example if we want 2Hz,
     * we divide 125kHz by 2 = 62,500.
     * Then we subtract this from the rollover value of 65,535,
     * so 65,535 - 62,500 = 3035 which is 0x0BDB in hex.
     * Timer 1 has two 8-bit high and low registers,
     * so we put 0x0B in the high and 0xDB in the low */
    INTCONbits.GIE = 1;     // Enable global interrupts
    INTCONbits.PEIE = 1;    // Enable peripheral interrupts
    PIR1bits.TMR1IF = 0;    // Clear Timer 1 interrupt flag
    PIE1bits.TMR1IE = 1;    // Enable Timer 1 interrupt
    PORTCbits.RC5 = 0;      // Clear RC5
    TRISCbits.TRISC5 = 0;   // Sets pin RC5 to output
}

 /* This routine works well for slow steps
  * from 2Hz - 1kHz or so.
  * Above this using the PWM is better.
  * count = number of pulses
  * speed = pulse speed in Hz */
void stepper_step(unsigned int count, unsigned int speed)
{
    unsigned int temp_speed = HZ / (speed / 2);
    stepper_count = count;
    if(stepper_count < 1) stepper_count = 1;
    stepper_speed = (TMR_MAX - (temp_speed));
    // Make duty cycle 1:10
    stepper_pulse = (stepper_speed + ((temp_speed) / 10));
    // Split 16-bit integer over the two 8-bit Timer 1 registers
    TMR1H = (stepper_speed >> 8);
    TMR1L = (stepper_speed & 0x00FF);
    // Do the same for the compare registers
    CCPR1H = (stepper_pulse >> 8);
    CCPR1L = (stepper_pulse & 0x00FF);
    PIR1bits.CCP1IF = 0;
    CCP1CON = 0x00;             // Reset CCP Peripheral
    CCP1CONbits.CCP1M = 0b1001; // Set up for Compare mode, clear pin on match
    T1CONbits.TMR1ON = 1;
}

/* Rough delay routine */
void delay(int d)
{
    int i;  // Declare variable to be used in the loop

    while(d)    // While d > 0
    {
        i = 100;    // set i to 100 for inner loop
        while(i)    // while i > 0
        {
            i--;    // decrement i (e.g. i will equal 99, 98, 97,...)
        }
        d--;        // decrement d
    }
}

Voici un aperçu des 5 impulsions à 50 Hz (remarquez la mesure du curseur de 50 Hz dans la case de gauche)

Capture de portée

20317

J’aurai besoin d’un flux d’impulsions donc je serais très heureux si vous pouviez poster un exemple afin de le comprendre et le changer pour mon projet. J’utilise le code assembleur, mais si vous n’avez pas quelque chose dans l’assemblage, je peux changer le code C. Merci!

Oli Glaser

@ 20317 – pas de problème, je posterai quelque chose dans quelques heures quand j’aurai fini de travailler. Mon assemblage est un peu trop rouillé pour le faire rapidement, donc il sera en C cependant (vous pouvez toujours espérer avoir l’idée – peut-être le compiler et le démonter)

Oli Glaser

@ 20317 – Désolé, ça fait longtemps, je n’ai pas fini tard hier soir. J’ai ajouté un exemple approximatif en utilisant les périphériques Timer et Compare. Vous pouvez également utiliser le périphérique PWM (mieux à des vitesses plus rapides). J’essaierai d’ajouter un autre extrait pour cela plus tard.

20317

Tu es le meilleur! Merci beaucoup! Je vais comprendre puis passer au code assembleur. J’ai beaucoup apprécié ce que vous avez fait!

 

(question, #à, #de, #pas, Contrôleur, d’horloge, du, L297, moteur, Signal

 

google

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *