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

📄 main.c

📁 Luminary Micro BLDC motor control software
💻 C
📖 第 1 页 / 共 5 页
字号:
static long g_lSpeedIntegrator;

//*****************************************************************************
//
//! The maximum value that of the PI controller accumulator
//! (#g_lSpeedIntegrator).  This limit is based on the I coefficient and
//! the maximum duty cycle of the motor drive, and is used to avoid
//! "integrator windup", a potential pitfall of PI controllers.
//
//*****************************************************************************
static long g_lSpeedIntegratorMax;

//*****************************************************************************
//
//! The current state of the motor drive state machine.  This state machine
//! controls acceleration, deceleration, starting, stopping, braking, and
//! reversing direction of the motor drive.
//
//*****************************************************************************
static unsigned long g_ulState = STATE_STOPPED;

//*****************************************************************************
//
//! The current speed of the motor.  This value is updated based on whether
//! the encoder or Hall sensors are being used.
//
//*****************************************************************************
unsigned long g_ulMeasuredSpeed = 0;

//*****************************************************************************
//
//! The previous value of the "Hall" state for trapezoid modulation.
//
//*****************************************************************************
static unsigned long g_ulHallPrevious = 8;

//*****************************************************************************
//
//! The Stall Detection Count.
//
//*****************************************************************************
static unsigned long g_ulStallDetectCount = 0;

//*****************************************************************************
//
//! The Sine modulation target speed.
//
//*****************************************************************************
static unsigned long g_ulSineTarget = 0;

//*****************************************************************************
//
//! Handles errors from the driver library.
//!
//! This function is called when an error is encountered by the driver library.
//! Typically, the errors will be invalid parameters passed to the library's
//! APIs.
//!
//! In this application, nothing is done in this function.  It does provide a
//! convenient location for a breakpoint that will catch all driver library
//! errors.
//!
//! \return None.
//
//*****************************************************************************
#ifdef DEBUG
void
__error__(char *pcFilename, unsigned long ulLine)
{
}
#endif

//*****************************************************************************
//
//! Multiplies two 16.16 fixed-point numbers.
//!
//! \param lX is the first multiplicand.
//! \param lY is the second multiplicand.
//!
//! This function takes two fixed-point numbers, in 16.16 format, and
//! multiplies them together, returning the 16.16 fixed-point result.  It is
//! the responsibility of the caller to ensure that the dynamic range of the
//! integer portion of the value is not exceeded; if it is exceeded the result
//! will not be correct.
//!
//! \return Returns the result of the multiplication, in 16.16 fixed-point
//! format.
//
//*****************************************************************************
#if defined(ewarm) || defined(DOXYGEN)
static long
MainLongMul(long lX, long lY)
{
    //
    // The assembly code to efficiently perform the multiply (using the
    // instruction to multiply two 32-bit values and return the full 64-bit
    // result).
    //
    __asm("    smull   r0, r1, r0, r1\n"
          "    lsrs    r0, r0, #16\n"
          "    orr     r0, r0, r1, lsl #16\n"
          "    bx      lr");

    //
    // This return is never reached but is required to avoid a compiler
    // warning.
    //
    return(0);
}
#endif
#if defined(gcc) || defined(sourcerygxx)
static long __attribute__((naked))
MainLongMul(long lX, long lY)
{
    //
    // The assembly code to efficiently perform the multiply (using the
    // instruction to multiply two 32-bit values and return the full 64-bit
    // result).
    //
    __asm("    smull   r0, r1, r0, r1\n"
          "    lsrs    r0, r0, #16\n"
          "    orr     r0, r0, r1, lsl #16\n"
          "    bx      lr");

    //
    // This return is never reached but is required to avoid a compiler
    // warning.
    //
    return(0);
}
#endif
#if defined(rvmdk) || defined(__ARMCC_VERSION)
__asm long
MainLongMul(long lX, long lY)
{
    //
    // The assembly code to efficiently perform the multiply (using the
    // instruction to multiply two 32-bit values and return the full 64-bit
    // result).
    //
    smull   r0, r1, r0, r1;
    lsrs    r0, r0, #16;
    orr     r0, r0, r1, lsl #16;
    bx      lr;
}
#endif

//*****************************************************************************
//
//! Changes the PWM frequency of the motor drive.
//!
//! This function changes the period of the PWM signals produced by the motor
//! drive.  It is simply a wrapper function around the PWMSetFrequency()
//! function; the PWM frequency-based timing parameters of the motor drive are
//! adjusted as part of the PWM frequency update.
//!
//! \return None.
//
//*****************************************************************************
void
MainSetPWMFrequency(void)
{
    //
    // Disable the update interrupts temporarily.
    //
    IntDisable(INT_PWM1);
    IntDisable(INT_PWM2);

    //
    // Set the new PWM frequency.
    //
    PWMSetFrequency();

    //
    // Compute the new angle delta based on the new PWM frequency and the
    // number of poles in the motor.
    // 
    g_ulAngleDelta = (((g_ulSpeed / 60) << 9) / g_ulPWMFrequency) << 9;
    g_ulAngleDelta *= (g_sParameters.ucNumPoles + 1);

    //
    // Re-enable the update interrupts.
    //
    IntEnable(INT_PWM1);
    IntEnable(INT_PWM2);
}

//*****************************************************************************
//
//! Changes the target speed of the motor drive.
//!
//! This function changes the target speed of the motor drive.  If
//! required, the state machine will be transitioned to a new state in order to
//! move the motor drive to the target speed.
//!
//! \return None.
//
//*****************************************************************************
void
MainSetSpeed(void)
{
    //
    // Clip the target speed to the minimum speed if it is too small.
    //
    if(g_ulTargetSpeed < g_sParameters.ulMinSpeed)
    {
        g_ulTargetSpeed = g_sParameters.ulMinSpeed;
    }

    //
    // Clip the target speed to the maximum speed if it is too large.
    //
    if(g_ulTargetSpeed > g_sParameters.ulMaxSpeed)
    {
        g_ulTargetSpeed = g_sParameters.ulMaxSpeed;
    }
}

//*****************************************************************************
//
//! Sets the direction of the motor drive.
//!
//! \param bForward is a boolean that is true if the motor drive should be
//! run in the forward direction.
//!
//! This function changes the direction of the motor drive.  If required, the
//! state machine will be transitioned to a new state in order to change the
//! direction of the motor drive.
//!
//! \return None.
//
//*****************************************************************************
void
MainSetDirection(tBoolean bForward)
{
    //
    // Temporarily disable the millisecond interrupt.
    //
    IntDisable(INT_PWM2);

    //
    // See if the motor should be running in the forward direction.
    //
    if(bForward)
    {
        //
        // See if the motor is presently running backward.
        //
        if(g_ulState == STATE_BACK_RUN)
        {
            //
            // If not already decelerating, then set the initial deceleration
            // rate based on the configured parameter value.
            //
            if(g_ucMotorStatus != MOTOR_STATUS_DECEL)
            {
                g_ulDecelRate = g_sParameters.usDecel << 16;
            }

            //
            // Advance the state machine to the decelerate to reverse direction
            // state.
            //
            g_ulState = STATE_BACK_REV;
        }

        //
        // See if the motor is presently running forward but in the process of
        // reversing to the backward direction.
        //
        if(g_ulState == STATE_REV)
        {
            //
            // Leave the motor drive running in the forward direction.
            //
            g_ulState = STATE_RUN;
        }
    }

    //
    // Otherwise the motor should be running in the backward direction.
    //
    else
    {
        //
        // See if the motor is presently running forward.
        //
        if(g_ulState == STATE_RUN)
        {
            //
            // If not already decelerating, then set the initial deceleration
            // rate based on the configured parameter value.
            //
            if(g_ucMotorStatus != MOTOR_STATUS_DECEL)
            {
                g_ulDecelRate = g_sParameters.usDecel << 16;
            }

            //
            // Advance the state machine to the decelerate to reverse direction
            // state.
            //
            g_ulState = STATE_REV;
        }

        //
        // See if the motor is presently running backward but in the process of
        // reversing to the forward direction.
        //
        if(g_ulState == STATE_BACK_REV)
        {
            //
            // Leave the motor drive running in the backward direction.
            //
            g_ulState = STATE_BACK_RUN;
        }
    }

    //
    // Re-enable the millisecond interrupt.
    //
    IntEnable(INT_PWM2);
}

//*****************************************************************************
//
//! Updates the I coefficient of the speed PI controller.
//!
//! \param lNewFAdjI is the new value of the I coefficient.
//!
//! This function updates the value of the I coefficient of the duty cycle PI
//! controller.  In addition to updating the I coefficient, it recomputes the
//! maximum value of the integrator and the current value of the integrator in
//! terms of the new I coefficient (eliminating any instantaneous jump in the
//! output of the PI controller).
//!
//! \return None.
//
//*****************************************************************************
void
MainUpdateFAdjI(long lNewFAdjI)
{
    //
    // Temporarily disable the millisecond interrupt.
    //
    IntDisable(INT_PWM2);

    //
    // See if the new I coefficient is zero.
    //
    if(lNewFAdjI == 0)
    {
        //
        // Since the I coefficient is zero, the integrator and integrator
        // maximum are also zero.
        //
        g_lSpeedIntegratorMax = 0;
        g_lSpeedIntegrator = 0;
    }
    else
    {
        //
        // Compute the maximum value of the integrator.  This is the value that
        // results in the maximum output duty cycle (i.e. integrator max * I =
        // max speed).
        //
        g_lSpeedIntegratorMax = 65536 * 100;

        //
        // Adjust the current value of the integrator to account for the new
        // value of the I coefficient.  This satisfies the equation "old
        // integrator * old I = new integrator * new I", so that the output
        // doesn't immediately change (in a drastic way) as a result of the
        // change in the I coefficient.
        //
        g_lSpeedIntegrator = ((g_lSpeedIntegrator / lNewFAdjI) *
                                  g_sParameters.lFAdjI);
    }

    //
    // Save the new I coefficient.
    //
    g_sParameters.lFAdjI = lNewFAdjI;

    //
    // Re-enable the millisecond interrupt.
    //
    IntEnable(INT_PWM2);
}

//*****************************************************************************
//
//! Handles the waveform update software interrupt.
//!
//! This function is periodically called as a result of the waveform update
//! software interrupt being asserted.  This interrupt is asserted at the
//! requested rate (based on the update rate parameter) by the PWM interrupt
//! handler.
//!

⌨️ 快捷键说明

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