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

📄 pwm_ctrl.c

📁 Luminary Micro BLDC motor control software
💻 C
📖 第 1 页 / 共 3 页
字号:
    //
    // Set the flag indicating that the duty cycles need to be updated.
    //
    HWREGBITW(&g_ulPWMFlags, PWM_FLAG_NEW_DUTY_CYCLE) = 1;

    //
    // Re-enable the PWM interrupt.
    //
    IntEnable(INT_PWM0);
}

//*****************************************************************************
//
//! Sets the PWM outputs to precharge the high side gate drives.
//!
//! This function configures the PWM outputs such that they will start charging
//! the bootstrap capacitor on the high side gate drives.  Without this step,
//! the high side gates will not turn on properly for the first several PWM
//! cycles when starting the motor drive.
//!
//! \return None.
//
//*****************************************************************************
void
PWMOutputPrecharge(void)
{
    //
    // Punch the watchdog to make sure we don't get reset.
    //
    WatchdogReloadSet(WATCHDOG_BASE, WATCHDOG_RELOAD_VALUE);

    //
    // Ensure that all outputs are not-inverted.
    //
    PWMOutputInvert(PWM_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT |
                               PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT),
                    false);

    //
    // Disable the high and low side switches.
    //
    PWMOutputState(PWM_BASE, PWM_OUT_0_BIT | PWM_OUT_2_BIT | PWM_OUT_4_BIT,
                   false);
    PWMOutputState(PWM_BASE, PWM_OUT_1_BIT | PWM_OUT_3_BIT | PWM_OUT_5_BIT,
                   false);

    //
    // Set the PWM duty cycles to 3% (negative side).
    //
    g_ulPWMDutyCycleA = ((97 * 65535) / 100);
    g_ulPWMDutyCycleB = ((97 * 65535) / 100);
    g_ulPWMDutyCycleC = ((97 * 65535) / 100);

    //
    // Set the PWM period based on the configured PWM frequency.
    //
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_0, g_ulPWMClock);
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_1, g_ulPWMClock);
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_2, g_ulPWMClock);

    //
    // Update the PWM duty cycles.
    //
    PWMUpdateDutyCycle();

    //
    // Indicate that a precharge has been started.
    //
    HWREGBITW(&g_ulPWMFlags, PWM_FLAG_NEW_PRECHARGE) = 1;
}

//*****************************************************************************
//
//! Turns on all the PWM outputs.
//!
//! This function turns on all of the PWM outputs, allowing them to be
//! propagated to the gate drivers.
//!
//! \return None.
//
//*****************************************************************************
void
PWMOutputOn(void)
{
    //
    // Punch the watchdog to make sure we don't get reset.
    //
    WatchdogReloadSet(WATCHDOG_BASE, WATCHDOG_RELOAD_VALUE);

    //
    // Ensure that all outputs are not-inverted.
    //
    PWMOutputInvert(PWM_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT |
                               PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT),
                    false);

    //
    // Enable all six PWM outputs.
    //
    PWMOutputState(PWM_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT |
                              PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT),
                   true);
}

//*****************************************************************************
//
//! Enable/Disable PWM outputs as needed for Trapezoid modulation.
//!
//! \param ulEnable is the bit-mapped value representing which phase(s)
//! of the motor drive should be active.
//!
//! This function turns off non-selected outputs and turns on selected
//! outputs.  If slow decay mode is enabled, the high side is driven in
//! complementary mode.
//!
//! \return None.
//
//*****************************************************************************
void
PWMOutputTrapezoid(unsigned long ulEnable)
{
    unsigned long ulHigh, ulLow;

    //
    // Disable ADC interrupts that reference the PWM output/invert states.
    //
    IntDisable(INT_ADC0);
    IntDisable(INT_ADC3);
    
    //
    // Punch the watchdog to make sure we don't get reset.
    //
    WatchdogReloadSet(WATCHDOG_BASE, WATCHDOG_RELOAD_VALUE);

    //
    // Determine the high and low phase outputs.
    //
    ulHigh = ulEnable & (PWM_OUT_0_BIT | PWM_OUT_2_BIT | PWM_OUT_4_BIT);
    ulLow = ulEnable & (PWM_OUT_1_BIT | PWM_OUT_3_BIT | PWM_OUT_5_BIT);

    //
    // If driving in slow decay mode, enable the low side of the high phase.
    //
    if(HWREGBITH(&(g_sParameters.usFlags), FLAG_DECAY_BIT) == FLAG_DECAY_SLOW)
    {
        ulHigh = ulHigh | (ulHigh << 1);
    }

    //
    // Disable inversion on non-selected low phase.
    //
    PWMOutputInvert(PWM_BASE,
                    ulLow ^ (PWM_OUT_1_BIT | PWM_OUT_3_BIT | PWM_OUT_5_BIT),
                    false);

    //
    // Disable the non-selected PWM outputs.
    //
    PWMOutputState(PWM_BASE,
                   ulHigh ^ (PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT |
                             PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT),
                   false);

    //
    // Enable the selected PWM high phase outputs.
    //
    PWMOutputState(PWM_BASE, ulHigh, true);

    //
    // Enable the low phase inverted output.
    //
    PWMOutputInvert(PWM_BASE, ulLow, true);

    //
    // Reenable the ADC interrupts that reference the PWM output/invert states.
    //
    IntEnable(INT_ADC3);
    IntEnable(INT_ADC0);
    
}

//*****************************************************************************
//
//! Turns off all the PWM outputs.
//!
//! This function turns off all of the PWM outputs, preventing them from being
//! propagates to the gate drivers.
//!
//! \return None.
//
//*****************************************************************************
void
PWMOutputOff(void)
{
    //
    // Disable all six PWM outputs.
    //
    PWMOutputState(PWM_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT |
                              PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT),
                   false);

    //
    // Ensure that all outputs are not-inverted.
    //
    PWMOutputInvert(PWM_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT |
                               PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT),
                    false);

    //
    // Set the PWM duty cycles to 50%.
    //
    g_ulPWMDutyCycleA = 32768;
    g_ulPWMDutyCycleB = 32768;
    g_ulPWMDutyCycleC = 32768;

    //
    // Set the PWM period so that the ADC runs at 1 KHz.
    //
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_0, PWM_CLOCK / 1000);
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_1, PWM_CLOCK / 1000);
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_2, PWM_CLOCK / 1000);

    //
    // Update the PWM duty cycles.
    //
    PWMUpdateDutyCycle();
}

//*****************************************************************************
//
//! Changes the update rate of the motor drive.
//!
//! \param ucUpdateRate is the number of PWM periods between updates.
//!
//! This function changes the rate at which the motor drive waveforms are
//! recomputed.  Lower update values recompute the waveforms more frequently,
//! providing more accurate waveforms at the cost of increased processor usage.
//!
//! \return None.
//
//*****************************************************************************
void
PWMSetUpdateRate(unsigned char ucUpdateRate)
{
    //
    // Temporarily disable the PWM period interrupt.  Once disabled, it is no
    // longer possible for the waveform update software interrupt to be
    // triggered.
    //
    IntDisable(INT_PWM0);

    //
    // Change the update rate parameter.
    //
    g_sParameters.ucUpdateRate = ucUpdateRate;

    //
    // Re-enable the PWM period interrupt.
    //
    IntEnable(INT_PWM0);
}

//*****************************************************************************
//
//! Initializes the PWM control routines.
//!
//! This function initializes the PWM module and the control routines,
//! preparing them to produce PWM waveforms to drive the power module.
//!
//! \return None.
//
//*****************************************************************************
void
PWMInit(void)
{
    //
    // Make the PWM pins be peripheral function.
    //
    GPIOPinTypePWM(PIN_PHASEA_LOW_PORT,
                   PIN_PHASEA_LOW_PIN | PIN_PHASEA_HIGH_PIN);
    GPIOPinTypePWM(PIN_PHASEB_LOW_PORT,
                   PIN_PHASEB_LOW_PIN | PIN_PHASEB_HIGH_PIN);
    GPIOPinTypePWM(PIN_PHASEC_LOW_PORT,
                   PIN_PHASEC_LOW_PIN | PIN_PHASEC_HIGH_PIN);

    //
    // Configure the three PWM generators for up/down counting mode,
    // synchronous updates, and to stop at zero on debug events.
    //
    PWMGenConfigure(PWM_BASE, PWM_GEN_0, (PWM_GEN_MODE_UP_DOWN |
                                          PWM_GEN_MODE_SYNC |
                                          PWM_GEN_MODE_DBG_STOP));
    PWMGenConfigure(PWM_BASE, PWM_GEN_1, (PWM_GEN_MODE_UP_DOWN |
                                          PWM_GEN_MODE_SYNC |
                                          PWM_GEN_MODE_DBG_STOP));
    PWMGenConfigure(PWM_BASE, PWM_GEN_2, (PWM_GEN_MODE_UP_DOWN |
                                          PWM_GEN_MODE_SYNC |
                                          PWM_GEN_MODE_DBG_STOP));

    //
    // Set the initial duty cycles to 50%.
    //
    g_ulPWMDutyCycleA = 32768;
    g_ulPWMDutyCycleB = 32768;
    g_ulPWMDutyCycleC = 32768;

    //
    // Configure the PWM period, duty cycle, and dead band.  The initial period
    // is 1 KHz (for triggering the ADC), which will be increased when the
    // motor starts running.
    //
    PWMSetDeadBand();
    PWMSetFrequency();
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_0, PWM_CLOCK / 1000);
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_1, PWM_CLOCK / 1000);
    PWMGenPeriodSet(PWM_BASE, PWM_GEN_2, PWM_CLOCK / 1000);
    PWMUpdateDutyCycle();

    //
    // Enable the PWM generators.
    //
    PWMGenEnable(PWM_BASE, PWM_GEN_0);
    PWMGenEnable(PWM_BASE, PWM_GEN_1);
    PWMGenEnable(PWM_BASE, PWM_GEN_2);

    //
    // Synchronize the time base of the generators.
    //
    PWMSyncTimeBase(PWM_BASE, PWM_GEN_0_BIT | PWM_GEN_1_BIT | PWM_GEN_2_BIT);

    //
    // Configure an interrupt on the zero event of the first generator, and an
    // ADC trigger on the load event of the first generator.
    //
    PWMGenIntClear(PWM_BASE, PWM_GEN_0, PWM_INT_CNT_ZERO);
    PWMGenIntTrigEnable(PWM_BASE, PWM_GEN_0,
                        PWM_INT_CNT_ZERO | PWM_TR_CNT_LOAD);
    PWMGenIntTrigEnable(PWM_BASE, PWM_GEN_1, 0);
    PWMGenIntTrigEnable(PWM_BASE, PWM_GEN_2, 0);
    IntEnable(INT_PWM0);
    IntEnable(INT_PWM1);
    IntEnable(INT_PWM2);

    //
    // Set all six PWM outputs to go to the inactive state when a fault event
    // occurs (which includes debug events).
    //
    PWMOutputFault(PWM_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT |
                              PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT),
                   true);

    //
    // Disable all six PWM outputs.
    //
    PWMOutputState(PWM_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT |
                              PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT),
                   false);

    //
    // Ensure that all outputs are not-inverted.
    //
    PWMOutputInvert(PWM_BASE, (PWM_OUT_0_BIT | PWM_OUT_1_BIT | PWM_OUT_2_BIT |
                               PWM_OUT_3_BIT | PWM_OUT_4_BIT | PWM_OUT_5_BIT),
                    false);
}

//*****************************************************************************
//
// Close the Doxygen group.
//! @}
//
//*****************************************************************************

⌨️ 快捷键说明

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