예제 #1
0
//*****************************************************************************
//
//! Handles the ADC sample sequence zero interrupt.
//!
//! This function is called when sample sequence zero asserts an interrupt.  It
//! handles clearing the interrupt and processing the new ADC data in the FIFO.
//!
//! \return None.
//
//*****************************************************************************
void
ADC0IntHandler(void)
{
    unsigned long ulIdx;
    unsigned short pusADCData[8];

    //
    // Clear the ADC interrupt.
    //
    ADCIntClear(ADC0_BASE, 0);

    //
    // Read the samples from the ADC FIFO.
    //
    ulIdx = 0;
    while(!(HWREG(ADC0_BASE + ADC_O_SSFSTAT0) & ADC_SSFSTAT0_EMPTY) &&
          (ulIdx < 8))
    {
        //
        // Read the next sample.
        //
        pusADCData[ulIdx] = HWREG(ADC0_BASE + ADC_O_SSFIFO0);

        //
        // Increment the count of samples read.
        //
        ulIdx++;
    }

    //
    // See if five samples were read.
    //
    if(ulIdx != 5)
    {
        //
        // Since there were not precisely five samples in the FIFO, it is not
        // known what analog signal is represented by each sample.  Therefore,
        // return without doing any processing on these samples.
        //
        return;
    }

    //
    // Filter the new samples.
    //
    for(ulIdx = 0; ulIdx < 5; ulIdx++)
    {
        //
        // Pass the new data sample through a single pole IIR low pass filter
        // with a coefficient of 0.75.
        //
        g_pusFilteredData[ulIdx] = (((g_pusFilteredData[ulIdx] * 3) +
                                     pusADCData[ulIdx]) / 4);
    }

    //
    // Convert the ADC DC bus reading to volts.  Each volt at the ADC input
    // corresponds to 150 volts of bus voltage.
    //
    g_usBusVoltage = ((unsigned long)g_pusFilteredData[3] * 450) / 1024;

    //
    // Convert the ADC junction temperature reading to ambient case temperature
    // in Celsius.
    //
    g_sAmbientTemp = (59960 - (g_pusFilteredData[4] * 100)) / 356;

    //
    // See if the motor drive is running.
    //
    if(!MainIsRunning())
    {
        //
        // Since the motor drive is not running, there is no current through
        // the motor.
        //
        g_pusPhaseCurrentRMS[0] = 0;
        g_pusPhaseCurrentRMS[1] = 0;
        g_pusPhaseCurrentRMS[2] = 0;
        g_usMotorCurrent = 0;

        //
        // There is nothing further to be done since the motor is not running.
        //
        return;
    }

    //
    // See if the drive angle just crossed zero in either direction.
    //
    if(((g_ulAngle > 0xf0000000) && (g_ulPrevAngle < 0x10000000)) ||
       ((g_ulAngle < 0x10000000) && (g_ulPrevAngle > 0xf0000000)))
    {
        //
        // Loop through the three phases of the motor drive.
        //
        for(ulIdx = 0; ulIdx < 3; ulIdx++)
        {
            //
            // Convert the maximum reading detected during the last cycle into
            // amperes.  The phase current is measured as the voltage dropped
            // across a 0.04 Ohm resistor, so current is 25 times the voltage.
            // This is then passed through an op amp that multiplies the value
            // by 11.  The resulting phase current is put into a 8.8 fixed
            // point representation and must therefore be multiplied by 256.
            // This is the peak current, which is then divided by 1.4 to get
            // the RMS current.  Since the ADC reading is 0 to 1023 for
            // voltages between 0 V and 3 V, the final equation is:
            //
            //     A = R * (25 / 11) * (3 / 1024) * (10 / 14) * 256
            //
            // Reducing the constants results in R * 375 / 308.
            //
            g_pusPhaseCurrentRMS[ulIdx] = (((long)g_pusPhaseMax[ulIdx] * 375) /
                                           308);

            //
            // Reset the maximum phase current seen to zero to prepare for the
            // next cycle.
            //
            g_pusPhaseMax[ulIdx] = 0;
        }

        //
        // See if this is a single phase or three phase motor.
        //
        if(HWREGBITH(&(g_sParameters.usFlags), FLAG_MOTOR_TYPE_BIT) ==
           FLAG_MOTOR_TYPE_1PHASE)
        {
            //
            // Average the RMS current of the two phases to get the RMS motor
            // current.
            //
            pusADCData[0] = g_pusPhaseCurrentRMS[0];
            pusADCData[1] = g_pusPhaseCurrentRMS[1];
            g_usMotorCurrent = ((pusADCData[0] + pusADCData[1]) / 2);
        }
        else
        {
            //
            // Average the RMS current of the three phases to get the RMS motor
            // current.
            //
            pusADCData[0] = g_pusPhaseCurrentRMS[0];
            pusADCData[1] = g_pusPhaseCurrentRMS[1];
            pusADCData[2] = g_pusPhaseCurrentRMS[2];
            g_usMotorCurrent = ((pusADCData[0] + pusADCData[1] +
                                 pusADCData[2]) / 3);
        }
    }

    //
    // Loop through the three phases of the motor drive.
    //
    for(ulIdx = 0; ulIdx < 3; ulIdx++)
    {
        //
        // See if this ADC reading is larger than any previous ADC reading.
        //
        if(g_pusFilteredData[ulIdx] > g_pusPhaseMax[ulIdx])
        {
            //
            // Save this ADC reading as the maximum.
            //
            g_pusPhaseMax[ulIdx] = g_pusFilteredData[ulIdx];
        }
    }

    //
    // Save the current motor drive angle for the next set of samples.
    //
    g_ulPrevAngle = g_ulAngle;
}
예제 #2
0
//*****************************************************************************
//
//! Sets the frequency of the generated PWM waveforms.
//!
//! This function configures the frequency of the generated PWM waveforms.  The
//! frequency update will not occur immediately; the change will be registered
//! for synchronous application to the output waveforms to avoid
//! discontinuities.
//!
//! \return None.
//
//*****************************************************************************
void
PWMSetFrequency(void)
{
    //
    // Disable the PWM interrupt temporarily.
    //
    IntDisable(INT_PWM0_0);

    //
    // Determine the configured PWM frequency.
    //
    switch(g_sParameters.usFlags & FLAG_PWM_FREQUENCY_MASK)
    {
        //
        // The PWM frequency is 8 KHz.
        //
        case FLAG_PWM_FREQUENCY_8K:
        {
            //
            // Set the PWM frequency variable.
            //
            g_ulPWMFrequency = 8000;

            //
            // Get the number of PWM clocks in a 8 KHz period.
            //
            g_ulPWMClock = PWM_CLOCK / 8000;

            //
            // Done with this PWM frequency.
            //
            break;
        }

        //
        // The PWM frequency is 12.5 KHz.
        //
        case FLAG_PWM_FREQUENCY_12K:
        {
            //
            // Set the PWM frequency variable.
            //
            g_ulPWMFrequency = 12500;

            //
            // Get the number of PWM clocks in a 12.5 KHz period.
            //
            g_ulPWMClock = PWM_CLOCK / 12500;

            //
            // Done with this PWM frequency.
            //
            break;
        }

        //
        // The PWM frequency is 16 KHz.
        //
        case FLAG_PWM_FREQUENCY_16K:
        {
            //
            // Set the PWM frequency variable.
            //
            g_ulPWMFrequency = 16000;

            //
            // Get the number of PWM clocks in a 16 KHz period.
            //
            g_ulPWMClock = PWM_CLOCK / 16000;

            //
            // Done with this PWM frequency.
            //
            break;
        }

        //
        // The PWM frequency is 25 KHz.
        //
        case FLAG_PWM_FREQUENCY_25K:
        {
            //
            // Set the PWM frequency variable.
            //
            g_ulPWMFrequency = 25000;

            //
            // Get the number of PWM clocks in a 25 KHz period.
            //
            g_ulPWMClock = PWM_CLOCK / 25000;

            //
            // Done with this PWM frequency.
            //
            break;
        }

        //
        // The PWM frequency is 40 KHz.
        //
        case FLAG_PWM_FREQUENCY_40K:
        {
            //
            // Set the PWM frequency variable.
            //
            g_ulPWMFrequency = 40000;

            //
            // Get the number of PWM clocks in a 40 KHz period.
            //
            g_ulPWMClock = PWM_CLOCK / 40000;

            //
            // Done with this PWM frequency.
            //
            break;
        }

        //
        // The PWM frequency is 50 KHz.
        //
        case FLAG_PWM_FREQUENCY_50K:
        {
            //
            // Set the PWM frequency variable.
            //
            g_ulPWMFrequency = 50000;

            //
            // Get the number of PWM clocks in a 50 KHz period.
            //
            g_ulPWMClock = PWM_CLOCK / 50000;

            //
            // Done with this PWM frequency.
            //
            break;
        }

        //
        // The PWM frequency is 80 KHz.
        //
        case FLAG_PWM_FREQUENCY_80K:
        {
            //
            // Set the PWM frequency variable.
            //
            g_ulPWMFrequency = 80000;

            //
            // Get the number of PWM clocks in a 80 KHz period.
            //
            g_ulPWMClock = PWM_CLOCK / 80000;

            //
            // Done with this PWM frequency.
            //
            break;
        }

        //
        // The PWM frequency is 20 KHz.
        //
        case FLAG_PWM_FREQUENCY_20K:
        default:
        {
            //
            // Set the PWM frequency variable.
            //
            g_ulPWMFrequency = 20000;

            //
            // Get the number of PWM clocks in a 20 KHz period.
            //
            g_ulPWMClock = PWM_CLOCK / 20000;

            //
            // Done with this PWM frequency.
            //
            break;
        }
    }

    if(MainIsRunning())
    {
        //
        // Indicate that the PWM frequency needs to be updated.
        //
        HWREGBITW(&g_ulPWMFlags, PWM_FLAG_NEW_FREQUENCY) = 1;
    }

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