//***************************************************************************** // //! 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; }
//***************************************************************************** // //! 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); }