This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
我正在尝试修改代码 C:\ti\c2000\C2000Ware_4_00_00\driverlib\f28004x\examples\epwm\epwm_ex3_synchronization.c
我的目标是将 PWM 占空比从1%缓慢增加到50%。 目前、我没有任何设定点或 ADC 输入。 我只是想逐渐更新占空比。
如果可能、我会很乐意提供帮助。
Ashik
您好!
您可以根据 PWM 上升/下降沿在常规事件上发出中断。 在中断服务例程中、您可以选择使用 CMPA/B 逐渐更新 EPWM 占空比
C2000Ware 中确实有一个示例、您可以参阅- epwm_ex2_updown_AQ
谢谢。
Aditya.
感谢您提供的信息。 目前、我需要2组 PWM。 我尝试做的是在 PWM 1和2之间给出相移。 最初、PWM 1和2都将从0%/1%占空比开始。 此时、相移将为零。 随着相移的增加、占空比将增加、它将达到最大50%。 我正在尝试将 PWM 占空比与相移的增量同步、这似乎非常困难。 我们将感谢您提供任何帮助。
您好!
我不确定 C2000Ware 中是否提供了确切的示例。 最初使用的示例- epwm_ex3_synchronous 是我可以在您的应用中看到的最接近您的应用的值。 您可以合并示例2和3、这将非常符合您的要求。
Aditya.
您好、Aditya:
我现在正在使用代码 epwm_ex13_up_aq.c。我已在此处附加了代码。 我现在可以将占空比更改至50%。 我还可以使用看门狗中的变量"Ph"放置相移。 但是、要更改"Ph"、我需要在看门狗中使 AshikFlag 和 loop_counter===2900。 但我希望使代码独立于这两个变量(AshikFlag 和 loop_counter)。 当 PWM 达到50%占空比时、我要从看门狗更改变量的相位。 但我不知道如何在 PWM 达到50%占空比时编写条件。 希望您可以帮助解决这个问题。 谢谢
//########################################################################### // // FILE: epwm_ex13_up_aq.c // // TITLE: Action Qualifier Module - Using up count. // //! \addtogroup driver_example_list //! <h1> EPWM Action Qualifier (epwm_up_aq)</h1> //! //! This example configures ePWM1, ePWM2, ePWM3 to produce an //! waveform with independent modulation on EPWMxA and //! EPWMxB. //! //! The compare values CMPA and CMPB are modified within the ePWM's ISR. //! //! The TB counter is in up count mode for this example. //! //! View the EPWM1A/B(GPIO0 & GPIO1), EPWM2A/B(GPIO2 & GPIO3) //! and EPWM3A/B(GPIO4 & GPIO5) waveforms via an oscilloscope. //! // //########################################################################### // // // $Copyright: // Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //########################################################################### // // Included Files // #include "driverlib.h" #include "device.h" #include "board.h" // // Defines // #define EPWM1_TIMER_TBPRD 2000 // Period register #define EPWM1_MAX_CMPA 1000 #define EPWM1_MIN_CMPA 0 #define EPWM1_MAX_CMPB 1000 #define EPWM1_MIN_CMPB 0 #define EPWM2_TIMER_TBPRD 2000 // Period register #define EPWM2_MAX_CMPA 1000 //1950 #define EPWM2_MIN_CMPA 0 //50 #define EPWM2_MAX_CMPB 1000 //1950 #define EPWM2_MIN_CMPB 0 //50 #define EPWM3_TIMER_TBPRD 2000 // Period register #define EPWM3_MAX_CMPA 950 #define EPWM3_MIN_CMPA 50 #define EPWM3_MAX_CMPB 1950 #define EPWM3_MIN_CMPB 1050 #define EPWM_CMP_UP 1 #define EPWM_CMP_DOWN 0 // // Globals // typedef struct { uint32_t epwmModule; uint16_t epwmCompADirection; uint16_t epwmCompBDirection; uint16_t epwmTimerIntCount; uint16_t ePWMDone; uint16_t epwmMaxCompA; uint16_t epwmMinCompA; uint16_t epwmMaxCompB; uint16_t epwmMinCompB; } epwmInfo; epwmInfo epwm1Info; epwmInfo epwm2Info; epwmInfo epwm3Info; uint16_t AshikFlag = 0 ; //Ashik Added uint16_t Ph = 0 ; //Ashik Added uint16_t loop_counter = 0 ; //Ashik Added volatile uint16_t compAVal, compBVal; // // Function Prototypes // void initEPWM1(void); void initEPWM2(void); void initEPWM3(void); __interrupt void epwm1ISR(void); __interrupt void epwm2ISR(void); __interrupt void epwm3ISR(void); void updateCompare(epwmInfo*); // // Main // void main(void) { // // Initialize device clock and peripherals // Device_init(); // // Disable pin locks and enable internal pull-ups. // Device_initGPIO(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3 // Board_init(); // // Interrupts that are used in this example are re-mapped to // ISR functions found within this file. // Interrupt_register(INT_EPWM1, &epwm1ISR); Interrupt_register(INT_EPWM2, &epwm2ISR); Interrupt_register(INT_EPWM3, &epwm3ISR); // // Disable sync(Freeze clock to PWM as well) // SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // Initialize PWM1 without phase shift as master initEPWM1(); // Initialize PWM2 with phase shift of X initEPWM2(); //EPWM_selectPeriodLoadEvent(myEPWM2_BASE, EPWM_SHADOW_LOAD_MODE_SYNC); //EPWM_setPhaseShift(myEPWM2_BASE, Ph); //ashik added Ph // EPWM_setTimeBaseCounter(myEPWM2_BASE, Ph); //ashik added Ph initEPWM3(); EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO); // // ePWM2 uses the ePWM 1 SYNCO as its SYNCIN. // ePWM2 SYNCO is generated from its SYNCIN, which is ePWM1 SYNCO // EPWM_setSyncOutPulseMode(myEPWM2_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN); // // ePWM4 uses the ePWM 1 SYNCO as its SYNCIN. // //SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM4, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT); // // Enable all phase shifts. // EPWM_enablePhaseShiftLoad(myEPWM2_BASE); // // Enable sync and clock to PWM // SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // // Enable interrupts required for this example // Interrupt_enable(INT_EPWM1); Interrupt_enable(INT_EPWM2); Interrupt_enable(INT_EPWM3); // // Enable global Interrupts and higher priority real-time debug events: // EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM // // IDLE loop. Just sit and loop forever (optional): // for(;;) { asm (" NOP"); } } // // epwm1ISR - EPWM1 ISR to update compare values // __interrupt void epwm1ISR(void) { // // Update the CMPA and CMPB values // updateCompare(&epwm1Info); // // Clear INT flag for this timer // EPWM_clearEventTriggerInterruptFlag(myEPWM1_BASE); // // Acknowledge this interrupt to receive more interrupts from group 3 // Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3); } // // epwm2ISR - EPWM2 ISR to update compare values // __interrupt void epwm2ISR(void) { // // Update the CMPA and CMPB values // if (loop_counter!=AshikFlag) { updateCompare(&epwm2Info); } else { //Ph=300; EPWM_selectPeriodLoadEvent(myEPWM2_BASE, EPWM_SHADOW_LOAD_MODE_SYNC); EPWM_setPhaseShift(myEPWM2_BASE, Ph); //ashik added Ph EPWM_setTimeBaseCounter(myEPWM2_BASE, Ph); //ashik added Ph } // // Clear INT flag for this timer // EPWM_clearEventTriggerInterruptFlag(myEPWM2_BASE); // // Acknowledge this interrupt to receive more interrupts from group 3 // Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3); } // // epwm3ISR - EPWM3 ISR to update compare values // __interrupt void epwm3ISR(void) { // // Update the CMPA and CMPB values // updateCompare(&epwm3Info); // // Clear INT flag for this timer // EPWM_clearEventTriggerInterruptFlag(myEPWM3_BASE); // // Acknowledge this interrupt to receive more interrupts from group 3 // Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3); } // // initEPWM1 - Initialize EPWM1 values // void initEPWM1() { // // Setup TBCLK // EPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_UP); EPWM_setTimeBasePeriod(myEPWM1_BASE, EPWM1_TIMER_TBPRD); EPWM_disablePhaseShiftLoad(myEPWM1_BASE); EPWM_setPhaseShift(myEPWM1_BASE, 0U); EPWM_setTimeBaseCounter(myEPWM1_BASE, 0U); // // Set ePWM clock pre-scaler // EPWM_setClockPrescaler(myEPWM1_BASE, EPWM_CLOCK_DIVIDER_2, EPWM_HSCLOCK_DIVIDER_2); // // Setup shadow register load on ZERO // EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); // // Set Compare values // EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM1_MIN_CMPA); EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, EPWM1_MIN_CMPB); // // Set actions for ePWM1A & ePWM1B // // Set PWM1A on Zero EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); // Clear PWM1A on event A, up count EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); // Set PWM1B on Zero EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); // Clear PWM1B on event B, up count EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); // // Set PWM1B on Zero // EPWM_setActionQualifierAction(myEPWM1_BASE, // EPWM_AQ_OUTPUT_B, // EPWM_AQ_OUTPUT_HIGH, // EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); // // Clear PWM1B on event B, up count // EPWM_setActionQualifierAction(myEPWM1_BASE, // EPWM_AQ_OUTPUT_B, // EPWM_AQ_OUTPUT_LOW, // EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); // // Interrupt where we will change the Compare Values // EPWM_setInterruptSource(myEPWM1_BASE, EPWM_INT_TBCTR_ZERO); EPWM_enableInterrupt(myEPWM1_BASE); EPWM_setInterruptEventCount(myEPWM1_BASE, 3U); // // Information this example uses to keep track // of the direction the CMPA/CMPB values are // moving, the min and max allowed values and // a pointer to the correct ePWM registers // // Start by increasing CMPA & CMPB epwm1Info.epwmCompADirection = EPWM_CMP_UP; epwm1Info.epwmCompBDirection = EPWM_CMP_UP; // Clear interrupt counter epwm1Info.epwmTimerIntCount = 0; epwm1Info.ePWMDone = 0; // Set base as ePWM1 epwm1Info.epwmModule = myEPWM1_BASE; // Setup min/max CMPA/CMP values epwm1Info.epwmMaxCompA = EPWM1_MAX_CMPA; epwm1Info.epwmMinCompA = EPWM1_MIN_CMPA; epwm1Info.epwmMaxCompB = EPWM1_MAX_CMPB; epwm1Info.epwmMinCompB = EPWM1_MIN_CMPB; } // // initEPWM2 - Initialize EPWM2 values // void initEPWM2() { // // Setup TBCLK // EPWM_setTimeBaseCounterMode(myEPWM2_BASE, EPWM_COUNTER_MODE_UP); EPWM_setTimeBasePeriod(myEPWM2_BASE, EPWM2_TIMER_TBPRD); EPWM_disablePhaseShiftLoad(myEPWM2_BASE); EPWM_setPhaseShift(myEPWM2_BASE, 0U); EPWM_setTimeBaseCounter(myEPWM2_BASE, 0U); // // Set ePWM clock pre-scaler // EPWM_setClockPrescaler(myEPWM2_BASE, EPWM_CLOCK_DIVIDER_2, EPWM_HSCLOCK_DIVIDER_2); // // Setup shadow register load on ZERO // EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); // // Set Compare values // EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A, EPWM2_MIN_CMPA); EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_B, EPWM2_MIN_CMPB); //EPWM2_MAX_CMPB // // Set actions for ePWM1A & ePWM1B // // Clear PWM2A on period and set on event A, up-count // EPWM_setActionQualifierAction(myEPWM2_BASE, // EPWM_AQ_OUTPUT_A, // EPWM_AQ_OUTPUT_LOW, // EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); // EPWM_setActionQualifierAction(myEPWM2_BASE, // EPWM_AQ_OUTPUT_A, // EPWM_AQ_OUTPUT_HIGH, // EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); // Clear PWM2A on period and set on event A, up-count EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);// EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); // Clear PWM2B on Period & set on event B, up-count EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);// EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); // // Interrupt where we will change the Compare Values // EPWM_setInterruptSource(myEPWM2_BASE, EPWM_INT_TBCTR_ZERO); EPWM_enableInterrupt(myEPWM2_BASE); EPWM_setInterruptEventCount(myEPWM2_BASE, 3U); // // Information this example uses to keep track // of the direction the CMPA/CMPB values are // moving, the min and max allowed values and // a pointer to the correct ePWM registers // // Start by increasing CMPA & decreasing CMPB epwm2Info.epwmCompADirection = EPWM_CMP_UP; epwm2Info.epwmCompBDirection = EPWM_CMP_DOWN; // Clear interrupt counter epwm2Info.epwmTimerIntCount = 0; // Set base as ePWM2 epwm2Info.epwmModule = myEPWM2_BASE; // Setup min/max CMPA/CMP values epwm2Info.epwmMaxCompA = EPWM2_MAX_CMPA; epwm2Info.epwmMinCompA = EPWM2_MIN_CMPA; epwm2Info.epwmMaxCompB = EPWM2_MAX_CMPB; epwm2Info.epwmMinCompB = EPWM2_MIN_CMPB; } // // initEPWM3 - Initialize EPWM3 values // void initEPWM3(void) { // // Setup TBCLK // EPWM_setTimeBaseCounterMode(myEPWM3_BASE, EPWM_COUNTER_MODE_UP); EPWM_setTimeBasePeriod(myEPWM3_BASE, EPWM3_TIMER_TBPRD); EPWM_disablePhaseShiftLoad(myEPWM3_BASE); EPWM_setPhaseShift(myEPWM3_BASE, 0U); EPWM_setTimeBaseCounter(myEPWM3_BASE, 0U); // // Set ePWM clock pre-scaler // EPWM_setClockPrescaler(myEPWM3_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); // // Setup shadow register load on ZERO // EPWM_setCounterCompareShadowLoadMode(myEPWM3_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareShadowLoadMode(myEPWM3_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); // // Set Compare values // EPWM_setCounterCompareValue(myEPWM3_BASE, EPWM_COUNTER_COMPARE_A, EPWM3_MIN_CMPA); EPWM_setCounterCompareValue(myEPWM3_BASE, EPWM_COUNTER_COMPARE_B, EPWM3_MAX_CMPB); // // Set actions for ePWM1A & ePWM1B // // Set PWM3A on event B, up-count & clear on event B, up-count EPWM_setActionQualifierAction(myEPWM3_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(myEPWM3_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); // Toggle EPWM3B on counter = zero EPWM_setActionQualifierAction(myEPWM3_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_TOGGLE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); // // Interrupt where we will change the Compare Values // EPWM_setInterruptSource(myEPWM3_BASE, EPWM_INT_TBCTR_ZERO); EPWM_enableInterrupt(myEPWM3_BASE); EPWM_setInterruptEventCount(myEPWM3_BASE, 3U); // // Information this example uses to keep track // of the direction the CMPA/CMPB values are // moving, the min and max allowed values and // a pointer to the correct ePWM registers // // Start by increasing CMPA & decreasing CMPB epwm3Info.epwmCompADirection = EPWM_CMP_UP; epwm3Info.epwmCompBDirection = EPWM_CMP_UP; // Start the count at 0 epwm3Info.epwmTimerIntCount = 0; // Set base as ePWM1 epwm3Info.epwmModule = myEPWM3_BASE; // Setup min/max CMPA/CMP values epwm3Info.epwmMaxCompA = EPWM3_MAX_CMPA; epwm3Info.epwmMinCompA = EPWM3_MIN_CMPA; epwm3Info.epwmMaxCompB = EPWM3_MAX_CMPB; epwm3Info.epwmMinCompB = EPWM3_MIN_CMPB; } // // updateCompare - Update the compare values for the specified EPWM // void updateCompare(epwmInfo *epwm_info) { // // Every 10'th interrupt, change the CMPA/CMPB values // if(epwm_info->epwmTimerIntCount == 10) { epwm_info->epwmTimerIntCount = 0; compAVal = EPWM_getCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_A); compBVal = EPWM_getCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_B); // if (compAVal==epwm_info->epwmMaxCompA) {epwm1Info.ePWMDone = 1;} // // If we were increasing CMPA, check to see if // we reached the max value. If not, increase CMPA // else, change directions and decrease CMPA // if(epwm_info->epwmCompADirection == EPWM_CMP_UP) { if(compAVal < epwm_info->epwmMaxCompA) { EPWM_setCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_A, ++compAVal); AshikFlag = AshikFlag+1; } else { // epwm_info->epwmCompADirection = EPWM_CMP_DOWN; // EPWM_setCounterCompareValue(epwm_info->epwmModule, // EPWM_COUNTER_COMPARE_A, --compAVal); // epwm1Info.ePWMDone = 1; } } // // If we were decreasing CMPA, check to see if // we reached the min value. If not, decrease CMPA // else, change directions and increase CMPA // else { if(compAVal == epwm_info->epwmMinCompA) { epwm_info->epwmCompADirection = EPWM_CMP_UP; EPWM_setCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_A, ++compAVal); } else { EPWM_setCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_A, --compAVal); } } // // If we were increasing CMPB, check to see if // we reached the max value. If not, increase CMPB // else, change directions and decrease CMPB // if(epwm_info->epwmCompBDirection == EPWM_CMP_UP) { if(compBVal < epwm_info->epwmMaxCompB) { EPWM_setCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_B, ++compBVal); } else { // epwm_info->epwmCompBDirection = EPWM_CMP_DOWN; // EPWM_setCounterCompareValue(epwm_info->epwmModule, // EPWM_COUNTER_COMPARE_B, --compBVal); } } // // If we were decreasing CMPB, check to see if // we reached the min value. If not, decrease CMPB // else, change directions and increase CMPB // else { if(compBVal == epwm_info->epwmMinCompB) { epwm_info->epwmCompBDirection = EPWM_CMP_UP; EPWM_setCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_B, ++compBVal); } else { EPWM_setCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_B, --compBVal); } } } // // Increment interrupt count if < 10 // else { epwm_info->epwmTimerIntCount++; } return; } // // End of file //
您好 Ashik:
很高兴您能够获得所需的占空比。 对于相位要求、您可以在 PWM 的中断子例程中添加一个检查、检查占空比是否达到50%。 达到50%后、您可以选择更改相位值。
实际上、如果不会给计时计算带来麻烦、那么当前的方法也没有问题。
更通用的方法是、您可以在 ISR 中读取比较器值并检查它是否达到50%、然后可以根据这种方法选择更新相位值。
谢谢。
Aditya.
感谢 Aditya
您能告诉我、除了更改 TBPRD 值外、如何更改开关频率? 目前、ePWM_Timer_TBPRD 值为2000、给出的频率为12.5kHz。 我需要100kHz 的开关频率。
//########################################################################### // // FILE: epwm_ex13_up_aq.c // // TITLE: Action Qualifier Module - Using up count. // //! \addtogroup driver_example_list //! <h1> EPWM Action Qualifier (epwm_up_aq)</h1> //! //! This example configures ePWM1, ePWM2, ePWM3 to produce an //! waveform with independent modulation on EPWMxA and //! EPWMxB. //! //! The compare values CMPA and CMPB are modified within the ePWM's ISR. //! //! The TB counter is in up count mode for this example. //! //! View the EPWM1A/B(GPIO0 & GPIO1), EPWM2A/B(GPIO2 & GPIO3) //! and EPWM3A/B(GPIO4 & GPIO5) waveforms via an oscilloscope. //! // //########################################################################### // // // $Copyright: // Copyright (C) 2021 Texas Instruments Incorporated - http://www.ti.com/ // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: // // Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // // Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the // distribution. // // Neither the name of Texas Instruments Incorporated nor the names of // its contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // $ //########################################################################### // // Included Files // #include "driverlib.h" #include "device.h" #include "board.h" // // Defines // #define EPWM1_TIMER_TBPRD 100 // Period register //2000 #define EPWM1_MAX_CMPA 50 //1000 #define EPWM1_MIN_CMPA 0 #define EPWM1_MAX_CMPB 50 //1000 #define EPWM1_MIN_CMPB 0 #define EPWM2_TIMER_TBPRD 100 // Period register #define EPWM2_MAX_CMPA 50 //1950 #define EPWM2_MIN_CMPA 0 //50 #define EPWM2_MAX_CMPB 50 //1950 #define EPWM2_MIN_CMPB 0 //50 #define EPWM3_TIMER_TBPRD 100 // Period register #define EPWM3_MAX_CMPA 50 #define EPWM3_MIN_CMPA 0 #define EPWM3_MAX_CMPB 50 #define EPWM3_MIN_CMPB 0 #define EPWM_CMP_UP 1 #define EPWM_CMP_DOWN 0 // // Globals // typedef struct { uint32_t epwmModule; uint16_t epwmCompADirection; uint16_t epwmCompBDirection; uint16_t epwmTimerIntCount; uint16_t ePWMDone; uint16_t epwmMaxCompA; uint16_t epwmMinCompA; uint16_t epwmMaxCompB; uint16_t epwmMinCompB; } epwmInfo; epwmInfo epwm1Info; epwmInfo epwm2Info; epwmInfo epwm3Info; uint16_t AshikFlag = 0 ; //Ashik Added uint16_t Ph = 0 ; //Ashik Added uint16_t loop_counter = 0 ; //Ashik Added volatile uint16_t compAVal, compBVal; // // Function Prototypes // void initEPWM1(void); void initEPWM2(void); void initEPWM3(void); __interrupt void epwm1ISR(void); __interrupt void epwm2ISR(void); __interrupt void epwm3ISR(void); void updateCompare(epwmInfo*); // // Main // void main(void) { // // Initialize device clock and peripherals // Device_init(); // // Disable pin locks and enable internal pull-ups. // Device_initGPIO(); // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // Interrupt_initModule(); // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // Interrupt_initVectorTable(); // // For this case just init GPIO pins for ePWM1, ePWM2, ePWM3 // Board_init(); // // Interrupts that are used in this example are re-mapped to // ISR functions found within this file. // Interrupt_register(INT_EPWM1, &epwm1ISR); Interrupt_register(INT_EPWM2, &epwm2ISR); Interrupt_register(INT_EPWM3, &epwm3ISR); // // Disable sync(Freeze clock to PWM as well) // SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // Initialize PWM1 without phase shift as master initEPWM1(); // Initialize PWM2 with phase shift of X initEPWM2(); //EPWM_selectPeriodLoadEvent(myEPWM2_BASE, EPWM_SHADOW_LOAD_MODE_SYNC); //EPWM_setPhaseShift(myEPWM2_BASE, Ph); //ashik added Ph // EPWM_setTimeBaseCounter(myEPWM2_BASE, Ph); //ashik added Ph initEPWM3(); EPWM_setSyncOutPulseMode(EPWM1_BASE, EPWM_SYNC_OUT_PULSE_ON_COUNTER_ZERO); // // ePWM2 uses the ePWM 1 SYNCO as its SYNCIN. // ePWM2 SYNCO is generated from its SYNCIN, which is ePWM1 SYNCO // EPWM_setSyncOutPulseMode(myEPWM2_BASE, EPWM_SYNC_OUT_PULSE_ON_EPWMxSYNCIN); // // ePWM4 uses the ePWM 1 SYNCO as its SYNCIN. // //SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM4, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT); // // Enable all phase shifts. // EPWM_enablePhaseShiftLoad(myEPWM2_BASE); // // Enable sync and clock to PWM // SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // // Enable interrupts required for this example // Interrupt_enable(INT_EPWM1); Interrupt_enable(INT_EPWM2); Interrupt_enable(INT_EPWM3); // // Enable global Interrupts and higher priority real-time debug events: // EINT; // Enable Global interrupt INTM ERTM; // Enable Global realtime interrupt DBGM // // IDLE loop. Just sit and loop forever (optional): // for(;;) { asm (" NOP"); } } // // epwm1ISR - EPWM1 ISR to update compare values // __interrupt void epwm1ISR(void) { // // Update the CMPA and CMPB values // updateCompare(&epwm1Info); // // Clear INT flag for this timer // EPWM_clearEventTriggerInterruptFlag(myEPWM1_BASE); // // Acknowledge this interrupt to receive more interrupts from group 3 // Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3); } // // epwm2ISR - EPWM2 ISR to update compare values // __interrupt void epwm2ISR(void) { // // Update the CMPA and CMPB values // if (loop_counter!=AshikFlag) { updateCompare(&epwm2Info); } else { //Ph=300; EPWM_selectPeriodLoadEvent(myEPWM2_BASE, EPWM_SHADOW_LOAD_MODE_SYNC); EPWM_setPhaseShift(myEPWM2_BASE, Ph); //ashik added Ph EPWM_setTimeBaseCounter(myEPWM2_BASE, Ph); //ashik added Ph } // // Clear INT flag for this timer // EPWM_clearEventTriggerInterruptFlag(myEPWM2_BASE); // // Acknowledge this interrupt to receive more interrupts from group 3 // Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3); } // // epwm3ISR - EPWM3 ISR to update compare values // __interrupt void epwm3ISR(void) { // // Update the CMPA and CMPB values // updateCompare(&epwm3Info); // // Clear INT flag for this timer // EPWM_clearEventTriggerInterruptFlag(myEPWM3_BASE); // // Acknowledge this interrupt to receive more interrupts from group 3 // Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3); } // // initEPWM1 - Initialize EPWM1 values // void initEPWM1() { // // Setup TBCLK // EPWM_setTimeBaseCounterMode(myEPWM1_BASE, EPWM_COUNTER_MODE_UP); EPWM_setTimeBasePeriod(myEPWM1_BASE, EPWM1_TIMER_TBPRD); EPWM_disablePhaseShiftLoad(myEPWM1_BASE); EPWM_setPhaseShift(myEPWM1_BASE, 0U); EPWM_setTimeBaseCounter(myEPWM1_BASE, 0U); // // Set ePWM clock pre-scaler // EPWM_setClockPrescaler(myEPWM1_BASE, EPWM_CLOCK_DIVIDER_2, EPWM_HSCLOCK_DIVIDER_2); // // Setup shadow register load on ZERO // EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareShadowLoadMode(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); // // Set Compare values // EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_A, EPWM1_MIN_CMPA); EPWM_setCounterCompareValue(myEPWM1_BASE, EPWM_COUNTER_COMPARE_B, EPWM1_MIN_CMPB); // // Set actions for ePWM1A & ePWM1B // // Set PWM1A on Zero EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); // Clear PWM1A on event A, up count EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); // Set PWM1B on Zero EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); // Clear PWM1B on event B, up count EPWM_setActionQualifierAction(myEPWM1_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); // // Set PWM1B on Zero // EPWM_setActionQualifierAction(myEPWM1_BASE, // EPWM_AQ_OUTPUT_B, // EPWM_AQ_OUTPUT_HIGH, // EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); // // Clear PWM1B on event B, up count // EPWM_setActionQualifierAction(myEPWM1_BASE, // EPWM_AQ_OUTPUT_B, // EPWM_AQ_OUTPUT_LOW, // EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); // // Interrupt where we will change the Compare Values // EPWM_setInterruptSource(myEPWM1_BASE, EPWM_INT_TBCTR_ZERO); EPWM_enableInterrupt(myEPWM1_BASE); EPWM_setInterruptEventCount(myEPWM1_BASE, 3U); // // Information this example uses to keep track // of the direction the CMPA/CMPB values are // moving, the min and max allowed values and // a pointer to the correct ePWM registers // // Start by increasing CMPA & CMPB epwm1Info.epwmCompADirection = EPWM_CMP_UP; epwm1Info.epwmCompBDirection = EPWM_CMP_UP; // Clear interrupt counter epwm1Info.epwmTimerIntCount = 0; epwm1Info.ePWMDone = 0; // Set base as ePWM1 epwm1Info.epwmModule = myEPWM1_BASE; // Setup min/max CMPA/CMP values epwm1Info.epwmMaxCompA = EPWM1_MAX_CMPA; epwm1Info.epwmMinCompA = EPWM1_MIN_CMPA; epwm1Info.epwmMaxCompB = EPWM1_MAX_CMPB; epwm1Info.epwmMinCompB = EPWM1_MIN_CMPB; } // // initEPWM2 - Initialize EPWM2 values // void initEPWM2() { // // Setup TBCLK // EPWM_setTimeBaseCounterMode(myEPWM2_BASE, EPWM_COUNTER_MODE_UP); EPWM_setTimeBasePeriod(myEPWM2_BASE, EPWM2_TIMER_TBPRD); EPWM_disablePhaseShiftLoad(myEPWM2_BASE); EPWM_setPhaseShift(myEPWM2_BASE, 0U); EPWM_setTimeBaseCounter(myEPWM2_BASE, 0U); // // Set ePWM clock pre-scaler // EPWM_setClockPrescaler(myEPWM2_BASE, EPWM_CLOCK_DIVIDER_2, EPWM_HSCLOCK_DIVIDER_2); // // Setup shadow register load on ZERO // EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareShadowLoadMode(myEPWM2_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); // // Set Compare values // EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_A, EPWM2_MIN_CMPA); EPWM_setCounterCompareValue(myEPWM2_BASE, EPWM_COUNTER_COMPARE_B, EPWM2_MIN_CMPB); //EPWM2_MAX_CMPB // // Set actions for ePWM1A & ePWM1B // // Clear PWM2A on period and set on event A, up-count // EPWM_setActionQualifierAction(myEPWM2_BASE, // EPWM_AQ_OUTPUT_A, // EPWM_AQ_OUTPUT_LOW, // EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); // EPWM_setActionQualifierAction(myEPWM2_BASE, // EPWM_AQ_OUTPUT_A, // EPWM_AQ_OUTPUT_HIGH, // EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); // Clear PWM2A on period and set on event A, up-count EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);// EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); // Clear PWM2B on Period & set on event B, up-count EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO);// EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD EPWM_setActionQualifierAction(myEPWM2_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); // // Interrupt where we will change the Compare Values // EPWM_setInterruptSource(myEPWM2_BASE, EPWM_INT_TBCTR_ZERO); EPWM_enableInterrupt(myEPWM2_BASE); EPWM_setInterruptEventCount(myEPWM2_BASE, 3U); // // Information this example uses to keep track // of the direction the CMPA/CMPB values are // moving, the min and max allowed values and // a pointer to the correct ePWM registers // // Start by increasing CMPA & decreasing CMPB epwm2Info.epwmCompADirection = EPWM_CMP_UP; epwm2Info.epwmCompBDirection = EPWM_CMP_DOWN; // Clear interrupt counter epwm2Info.epwmTimerIntCount = 0; // Set base as ePWM2 epwm2Info.epwmModule = myEPWM2_BASE; // Setup min/max CMPA/CMP values epwm2Info.epwmMaxCompA = EPWM2_MAX_CMPA; epwm2Info.epwmMinCompA = EPWM2_MIN_CMPA; epwm2Info.epwmMaxCompB = EPWM2_MAX_CMPB; epwm2Info.epwmMinCompB = EPWM2_MIN_CMPB; } // // initEPWM3 - Initialize EPWM3 values // void initEPWM3(void) { // // Setup TBCLK // EPWM_setTimeBaseCounterMode(myEPWM3_BASE, EPWM_COUNTER_MODE_UP); EPWM_setTimeBasePeriod(myEPWM3_BASE, EPWM3_TIMER_TBPRD); EPWM_disablePhaseShiftLoad(myEPWM3_BASE); EPWM_setPhaseShift(myEPWM3_BASE, 0U); EPWM_setTimeBaseCounter(myEPWM3_BASE, 0U); // // Set ePWM clock pre-scaler // EPWM_setClockPrescaler(myEPWM3_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); // // Setup shadow register load on ZERO // EPWM_setCounterCompareShadowLoadMode(myEPWM3_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareShadowLoadMode(myEPWM3_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); // // Set Compare values // EPWM_setCounterCompareValue(myEPWM3_BASE, EPWM_COUNTER_COMPARE_A, EPWM3_MIN_CMPA); EPWM_setCounterCompareValue(myEPWM3_BASE, EPWM_COUNTER_COMPARE_B, EPWM3_MAX_CMPB); // // Set actions for ePWM1A & ePWM1B // // Set PWM3A on event B, up-count & clear on event B, up-count EPWM_setActionQualifierAction(myEPWM3_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(myEPWM3_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); // Toggle EPWM3B on counter = zero EPWM_setActionQualifierAction(myEPWM3_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_TOGGLE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); // // Interrupt where we will change the Compare Values // EPWM_setInterruptSource(myEPWM3_BASE, EPWM_INT_TBCTR_ZERO); EPWM_enableInterrupt(myEPWM3_BASE); EPWM_setInterruptEventCount(myEPWM3_BASE, 3U); // // Information this example uses to keep track // of the direction the CMPA/CMPB values are // moving, the min and max allowed values and // a pointer to the correct ePWM registers // // Start by increasing CMPA & decreasing CMPB epwm3Info.epwmCompADirection = EPWM_CMP_UP; epwm3Info.epwmCompBDirection = EPWM_CMP_UP; // Start the count at 0 epwm3Info.epwmTimerIntCount = 0; // Set base as ePWM1 epwm3Info.epwmModule = myEPWM3_BASE; // Setup min/max CMPA/CMP values epwm3Info.epwmMaxCompA = EPWM3_MAX_CMPA; epwm3Info.epwmMinCompA = EPWM3_MIN_CMPA; epwm3Info.epwmMaxCompB = EPWM3_MAX_CMPB; epwm3Info.epwmMinCompB = EPWM3_MIN_CMPB; } // // updateCompare - Update the compare values for the specified EPWM // void updateCompare(epwmInfo *epwm_info) { // // Every 10'th interrupt, change the CMPA/CMPB values // if(epwm_info->epwmTimerIntCount == 10) { epwm_info->epwmTimerIntCount = 0; compAVal = EPWM_getCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_A); compBVal = EPWM_getCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_B); // if (compAVal==epwm_info->epwmMaxCompA) {epwm1Info.ePWMDone = 1;} // // If we were increasing CMPA, check to see if // we reached the max value. If not, increase CMPA // else, change directions and decrease CMPA // if(epwm_info->epwmCompADirection == EPWM_CMP_UP) { if(compAVal < epwm_info->epwmMaxCompA) { EPWM_setCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_A, ++compAVal); AshikFlag = AshikFlag+1; } else { // epwm_info->epwmCompADirection = EPWM_CMP_DOWN; // EPWM_setCounterCompareValue(epwm_info->epwmModule, // EPWM_COUNTER_COMPARE_A, --compAVal); // epwm1Info.ePWMDone = 1; } } // // If we were decreasing CMPA, check to see if // we reached the min value. If not, decrease CMPA // else, change directions and increase CMPA // else { if(compAVal == epwm_info->epwmMinCompA) { epwm_info->epwmCompADirection = EPWM_CMP_UP; EPWM_setCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_A, ++compAVal); } else { EPWM_setCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_A, --compAVal); } } // // If we were increasing CMPB, check to see if // we reached the max value. If not, increase CMPB // else, change directions and decrease CMPB // if(epwm_info->epwmCompBDirection == EPWM_CMP_UP) { if(compBVal < epwm_info->epwmMaxCompB) { EPWM_setCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_B, ++compBVal); } else { // epwm_info->epwmCompBDirection = EPWM_CMP_DOWN; // EPWM_setCounterCompareValue(epwm_info->epwmModule, // EPWM_COUNTER_COMPARE_B, --compBVal); } } // // If we were decreasing CMPB, check to see if // we reached the min value. If not, decrease CMPB // else, change directions and increase CMPB // else { if(compBVal == epwm_info->epwmMinCompB) { epwm_info->epwmCompBDirection = EPWM_CMP_UP; EPWM_setCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_B, ++compBVal); } else { EPWM_setCounterCompareValue(epwm_info->epwmModule, EPWM_COUNTER_COMPARE_B, --compBVal); } } } // // Increment interrupt count if < 10 // else { epwm_info->epwmTimerIntCount++; } return; } // // End of file //
尊敬的 Aditya:
我现在的 PWM 频率是250kHz。 但当我使 AshikFlag 和 loop_counter==150时、EPWM2就会变得不稳定。 我可以更改相位、但 PWM 不稳定。 对这一点的任何见解都将有所帮助。
Ashik
您能告诉我除了更改 TBPRD 值之外、如何更改开关频率吗? 目前、ePWM_Timer_TBPRD 值为2000、给出的频率为12.5kHz。 我需要100kHz 的开关频率。
1.可以更改 TBPRD 以获得所需的开关频率。 在本例中、我认为根据电流配置所需的值为250。
2. 如果 HSPCLKDIV 和 CLKDIV 位当前不是最大值,则可以选择更新 HSPCLKDIV 和 CLKDIV 位,即它还不是/1
谢谢。
Aditya.