📄 stepper.c
字号:
//
//! 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 + -