⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stepper.c

📁 CNC.rar
💻 C
📖 第 1 页 / 共 3 页
字号:
//
//! The stepper state structure for the Z axis stepper.
//
//*****************************************************************************
static tStepperState g_sZStepper =
{
    0,
    PWM_GEN_2_OFFSET,
    STEPPER_Z_POL,
    STEPPER_Z_PHA_POL,
    STEPPER_Z_PHB_POL,
    { StepperZACurrent, 0 },
    { StepperZBCurrent, 0 }
};

//*****************************************************************************
//
//! A mapping between the four stepper states, in order, and the polarity of
//! the two windings for that state.  Bit zero of each byte corresponds to the
//! polarity of phase A and bit one of each byte corresponds to the polarity of
//! phase B.
//
//*****************************************************************************
static const unsigned char g_pucStepperStates[4] =
{
    0x00, 0x01, 0x03, 0x02
};

//*****************************************************************************
//
//! Change phase A of the X axis stepper to constant current mode.
//!
//! This function is called by a virtual timer when it is time to change phase
//! A of the X axis stepper from constant voltage mode to constant current
//! mode.  The time at which this occurs is purely a time delay and is not
//! driven from any observation of the actual current level in the winding
//! itself.
//!
//! \return None.
//
//*****************************************************************************
static void
StepperXACurrent(void)
{
    //
    // Reconfigure the PWM generator to produce PWM signals.
    //
    HWREG(PWM_BASE + PWM_GEN_0_OFFSET + PWM_O_X_GENA) =
        ((PWM_GEN_ACT_ONE << PWM_GEN_ACT_A_UP_SHIFT) |
         (PWM_GEN_ACT_ZERO << PWM_GEN_ACT_A_DN_SHIFT));

    //
    // Set the pulse width of this winding's PWM signal for the maximum rated
    // voltage of the motor winding (actually, the voltage that achieves the
    // maximum rated winding current).
    //
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_0,
                     ((g_ulPWMClock * STEPPER_MAX_VOLTAGE) /
                      STEPPER_SUPPLY_VOLTAGE));
}

//*****************************************************************************
//
//! Change phase B of the X axis stepper to constant current mode.
//!
//! This function is called by a virtual timer when it is time to change phase
//! B of the X axis stepper from constant voltage mode to constant current
//! mode.  The time at which this occurs is purely a time delay and is not
//! driven from any observation of the actual current level in the winding
//! itself.
//!
//! \return None.
//
//*****************************************************************************
static void
StepperXBCurrent(void)
{
    //
    // Reconfigure the PWM generator to produce PWM signals.
    //
    HWREG(PWM_BASE + PWM_GEN_0_OFFSET + PWM_O_X_GENB) =
        ((PWM_GEN_ACT_ONE << PWM_GEN_ACT_B_UP_SHIFT) |
         (PWM_GEN_ACT_ZERO << PWM_GEN_ACT_B_DN_SHIFT));

    //
    // Set the pulse width of this winding's PWM signal for the maximum rated
    // voltage of the motor winding (actually, the voltage that achieves the
    // maximum rated winding current).
    //
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_1,
                     ((g_ulPWMClock * STEPPER_MAX_VOLTAGE) /
                      STEPPER_SUPPLY_VOLTAGE));
}

//*****************************************************************************
//
//! Change phase A of the Y axis stepper to constant current mode.
//!
//! This function is called by a virtual timer when it is time to change phase
//! A of the Y axis stepper from constant voltage mode to constant current
//! mode.  The time at which this occurs is purely a time delay and is not
//! driven from any observation of the actual current level in the winding
//! itself.
//!
//! \return None.
//
//*****************************************************************************
static void
StepperYACurrent(void)
{
    //
    // Reconfigure the PWM generator to produce PWM signals.
    //
    HWREG(PWM_BASE + PWM_GEN_1_OFFSET + PWM_O_X_GENA) =
        ((PWM_GEN_ACT_ONE << PWM_GEN_ACT_A_UP_SHIFT) |
         (PWM_GEN_ACT_ZERO << PWM_GEN_ACT_A_DN_SHIFT));

    //
    // Set the pulse width of this winding's PWM signal for the maximum rated
    // voltage of the motor winding (actually, the voltage that achieves the
    // maximum rated winding current).
    //
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_2,
                     ((g_ulPWMClock * STEPPER_MAX_VOLTAGE) /
                      STEPPER_SUPPLY_VOLTAGE));
}

//*****************************************************************************
//
//! Change phase B of the Y axis stepper to constant current mode.
//!
//! This function is called by a virtual timer when it is time to change phase
//! B of the Y axis stepper from constant voltage mode to constant current
//! mode.  The time at which this occurs is purely a time delay and is not
//! driven from any observation of the actual current level in the winding
//! itself.
//!
//! \return None.
//
//*****************************************************************************
static void
StepperYBCurrent(void)
{
    //
    // Reconfigure the PWM generator to produce PWM signals.
    //
    HWREG(PWM_BASE + PWM_GEN_1_OFFSET + PWM_O_X_GENB) =
        ((PWM_GEN_ACT_ONE << PWM_GEN_ACT_B_UP_SHIFT) |
         (PWM_GEN_ACT_ZERO << PWM_GEN_ACT_B_DN_SHIFT));

    //
    // Set the pulse width of this winding's PWM signal for the maximum rated
    // voltage of the motor winding (actually, the voltage that achieves the
    // maximum rated winding current).
    //
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_3,
                     ((g_ulPWMClock * STEPPER_MAX_VOLTAGE) /
                      STEPPER_SUPPLY_VOLTAGE));
}

//*****************************************************************************
//
//! Change phase A of the Z axis stepper to constant current mode.
//!
//! This function is called by a virtual timer when it is time to change phase
//! A of the Z axis stepper from constant voltage mode to constant current
//! mode.  The time at which this occurs is purely a time delay and is not
//! driven from any observation of the actual current level in the winding
//! itself.
//!
//! \return None.
//
//*****************************************************************************
static void
StepperZACurrent(void)
{
    //
    // Reconfigure the PWM generator to produce PWM signals.
    //
    HWREG(PWM_BASE + PWM_GEN_2_OFFSET + PWM_O_X_GENA) =
        ((PWM_GEN_ACT_ONE << PWM_GEN_ACT_A_UP_SHIFT) |
         (PWM_GEN_ACT_ZERO << PWM_GEN_ACT_A_DN_SHIFT));

    //
    // Set the pulse width of this winding's PWM signal for the maximum rated
    // voltage of the motor winding (actually, the voltage that achieves the
    // maximum rated winding current).
    //
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_4,
                     ((g_ulPWMClock * STEPPER_MAX_VOLTAGE) /
                      STEPPER_SUPPLY_VOLTAGE));
}

//*****************************************************************************
//
//! Change phase B of the Z axis stepper to constant current mode.
//!
//! This function is called by a virtual timer when it is time to change phase
//! B of the Z axis stepper from constant voltage mode to constant current
//! mode.  The time at which this occurs is purely a time delay and is not
//! driven from any observation of the actual current level in the winding
//! itself.
//!
//! \return None.
//
//*****************************************************************************
static void
StepperZBCurrent(void)
{
    //
    // Reconfigure the PWM generator to produce PWM signals.
    //
    HWREG(PWM_BASE + PWM_GEN_2_OFFSET + PWM_O_X_GENB) =
        ((PWM_GEN_ACT_ONE << PWM_GEN_ACT_B_UP_SHIFT) |
         (PWM_GEN_ACT_ZERO << PWM_GEN_ACT_B_DN_SHIFT));

    //
    // Set the pulse width of this winding's PWM signal for the maximum rated
    // voltage of the motor winding (actually, the voltage that achieves the
    // maximum rated winding current).
    //
    PWMPulseWidthSet(PWM_BASE, PWM_OUT_5,
                     ((g_ulPWMClock * STEPPER_MAX_VOLTAGE) /
                      STEPPER_SUPPLY_VOLTAGE));
}

//*****************************************************************************
//
//! Step one of the stepper motors by one step.
//!
//! \param pStepper is a pointer to the stepper motor state structure for the
//! motor to be stepped.
//! \param lDir is the direction of the step to be taken.  This value should
//! only be 1 or -1 (other values will not have the desired effect).
//!
//! This function will step a motor by a single step in the positive or
//! negative direction.
//!
//! \return none.
//
//*****************************************************************************
static void
StepperStep(tStepperState *pStepper, long lDir)
{
    unsigned long ulState, ulDiff;

    //
    // Get the current polarity of the windings.
    //
    ulDiff = g_pucStepperStates[pStepper->ulStep];

    //
    // Move to the next step.
    //
    pStepper->ulStep = (pStepper->ulStep + lDir) & 3;

    //
    // Get the new polarity of the windings.
    //
    ulState = g_pucStepperStates[pStepper->ulStep];

    //
    // See which winding changed polarity.
    //
    ulDiff ^= ulState;

    //
    // Change the polarity of the winding, causing the motor to step.
    //
    GPIOPinWrite(GPIO_PORTD_BASE, pStepper->ucPhases,
                 (((ulState & 1) ? pStepper->ucPHA : 0) |
                  ((ulState & 2) ? pStepper->ucPHB : 0)));

    //
    // See if phase A or B changed polarity.
    //
    if(ulDiff & 1)
    {
        //
        // Phase A changed polarity, so set the corresponding PWM to always
        // drive a logic high, staring the constant voltage phase of the drive
        // sequence.
        //
        HWREG(PWM_BASE + pStepper->ucPWM + PWM_O_X_GENA) = 0xfff;

        //
        // Compute the time at which the winding should be changed from
        // constant voltage to constant current mode.
        //
        pStepper->sTimerA.ulTimeOut =
            (VirtualTimeGet() + (((g_ulSysClock / 1000) *
                                  STEPPER_START_DELAY) / 1000));

        //
        // Add a virtual timer to change the winding drive.
        //
        VirtualTimerAdd(&(pStepper->sTimerA));
    }
    else
    {
        //
        // Phase B changed polarity, so set the corresponding PWM to always
        // drive a logic high, staring the constant voltage phase of the drive
        // sequence.
        //
        HWREG(PWM_BASE + pStepper->ucPWM + PWM_O_X_GENB) = 0xfff;

        //
        // Compute the time at which the winding should be changed from
        // constant voltage to constant current mode.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -