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_3_04_00_00\device_support\f28002x\examples\hrpwm\hrpwm_ex2_prdupdown_sfo_v8.c例程时,PWM 5Mhz频率下通过示波器能清楚观测到周期边缘位置的变化,当PWM使用50Khz频率时,基本在示波器上看不到周期边缘有变化,请问是因为高精度PWM对于其频率有最低限度要求吗?如果不是的话为什么50Khz时观测不到变化
你好,感谢您的回复,现在情况是这样的,我在做一个等离子体电源的项目,PWM频率是50Khz,主要控制TBPRD寄存器来控制频率的变化,由于普通PWM的TBPRD寄存器未Uint16格式,因此我的频率只能50hz精度的调节,如果使用高精度PWM能够实现1hz精度的频率调节吗?还有之前问您的为什么在Demo中5Mhz使用高精度可以直接在示波器中观测到,而50Khz就看不见边缘有变化?
HRPWM是可以实现1Hz精度的频率调节的。至于为什么50KHz的时候没有变化,我可能需要咨询一下其他工程师讨论一下。你这边方便给出对应的配置和波形图吗
程序就是C2000ware中的demo程序C:\ti\c2000\C2000Ware_3_04_00_00\device_support\f28002x\examples\hrpwm\hrpwm_ex2_prdupdown_sfo_v8.c
在不同时刻暂停,示波器上观测到的都是周期为20us的PWM波,边缘没有变化
你好,目前还没有收到比较可靠的回复。不过我在例程主程序的开头注释中找到说明,这个例程需要在最大SYSCLKOUT下运行:
//! To load and run this example: //! -# **!!IMPORTANT!!** //! -# Run this example at maximum SYSCLKOUT //! -# Activate Real time mode //! -# Run the code //! -# Watch ePWM A / B channel waveforms on a Oscilloscope //! -# In the watch window: //! Set the variable UpdateFine = 1 to observe the ePWMxA & ePWMxB output //! with HRPWM capabilities (default) //! Observe the period/frequency of the waveform changes in fine MEP steps //! -# In the watch window: //! Change the variable UpdateFine to 0, to observe the //! ePWMxA & ePWMxB output without HRPWM capabilities //! Observe the period/frequency of the waveform changes in coarse //! SYSCLKOUT cycle steps.
您好,目前是运行在SYSCLKOUT下,程序默认配置了TBCLK = SYSCLK没有更改过,PWM的时钟是用的DSP的主频,能否和工程师确认下50Khz的PWM开关频率下能否使用高精度PWM?
你好,这边工程师回复,我怕翻译有误差,给你看一下原文:
It works at 50KHz. I just tested it on my setup. It is not easy to see it on the scope. You have to:
1. Trigger the scope on rising edge of the EPWM.
2. Zoom into the NEXT falling edge.
3. Change the TBPRDHR to see it changing.
50KHz works correctly.
//############################################################################# // // FILE: hrpwm_ex3_prdupdown_sfo.c // // TITLE: HRPWM Period Control. // //! \addtogroup driver_example_list //! <h1>HRPWM Period Control</h1> //! //! This example modifies the MEP control registers to show edge displacement //! for high-resolution period with ePWM in Up-Down count mode //! due to the HRPWM control extension of the respective ePWM module. //! //! This example calls the following TI's MEP Scale Factor Optimizer (SFO) //! software library V8 functions: //! //! \b int \b SFO(); \n //! - updates MEP_ScaleFactor dynamically when HRPWM is in use //! - updates HRMSTEP register (exists only in EPwm1Regs register space) //! with MEP_ScaleFactor value //! - returns 2 if error: MEP_ScaleFactor is greater than maximum value of 255 //! (Auto-conversion may not function properly under this condition) //! - returns 1 when complete for the specified channel //! - returns 0 if not complete for the specified channel //! //! This example is intended to explain the HRPWM capabilities. The code can be //! optimized for code efficiency. Refer to TI's Digital power application //! examples and TI Digital Power Supply software libraries for details. //! //! \b External \b Connections \n //! - Monitor ePWM1/2/3/4 A/B pins on an oscilloscope. // //############################################################################# // $TI Release: F28002x Support Library v3.04.00.00 $ // $Release Date: Fri Feb 12 18:58:34 IST 2021 $ // $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" #include "sfo_v8.h" // // Defines // #define EPWM_TIMER_TBPRD 1000UL #define LAST_EPWM_INDEX_FOR_EXAMPLE 5 #define MIN_HRPWM_PRD_PERCENT 0.2 // // Globals // float32_t periodFine = MIN_HRPWM_PRD_PERCENT; uint16_t status; int MEP_ScaleFactor; // Global variable used by the SFO library // Result can be used for all HRPWM channels // This variable is also copied to HRMSTEP // register by SFO() function. volatile uint32_t ePWM[] = {0, myEPWM1_BASE, myEPWM2_BASE, myEPWM3_BASE, myEPWM4_BASE}; // // Function Prototypes // void initHRPWM(uint32_t period); void error(void); // // Main // void main(void) { uint16_t i = 0; // // 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(); // // Initialize EPWM GPIOs and change XBAR inputs from using GPIO0 // Board_init(); // // Calling SFO() updates the HRMSTEP register with calibrated MEP_ScaleFactor. // HRMSTEP must be populated with a scale factor value prior to enabling // high resolution period control. // while(status == SFO_INCOMPLETE) { status = SFO(); if(status == SFO_ERROR) { error(); // SFO function returns 2 if an error occurs & # of MEP } // steps/coarse step exceeds maximum of 255. } // // Disable sync(Freeze clock to PWM as well) // SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); initHRPWM(EPWM_TIMER_TBPRD); // // Enable sync and clock to PWM // SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC); // // Enable Global Interrupt (INTM) and realtime interrupt (DBGM) // EINT; ERTM; for(;;) { // // Sweep DutyFine // //for(periodFine = MIN_HRPWM_PRD_PERCENT; periodFine < 0.9; periodFine += 0.01) //{ DEVICE_DELAY_US(1000); // for(i=1; i<LAST_EPWM_INDEX_FOR_EXAMPLE; i++) // { // float32_t count = ((EPWM_TIMER_TBPRD-1) << 8UL) + (float32_t)(periodFine * 256); // uint32_t compCount = count; // HRPWM_setTimeBasePeriod(ePWM[i], compCount); // } // // Call the scale factor optimizer lib function SFO() // periodically to track for any change due to temp/voltage. // This function generates MEP_ScaleFactor by running the // MEP calibration module in the HRPWM logic. This scale // factor can be used for all HRPWM channels. The SFO() // function also updates the HRMSTEP register with the // scale factor value. // status = SFO(); // in background, MEP calibration module // continuously updates MEP_ScaleFactor if (status == SFO_ERROR) { error(); // SFO function returns 2 if an error occurs & # // of MEP steps/coarse step } // exceeds maximum of 255. //} } } void initHRPWM(uint32_t period) { uint16_t j; // // ePWM channel register configuration with HRPWM // for (j=1;j<LAST_EPWM_INDEX_FOR_EXAMPLE;j++) { EPWM_setEmulationMode(ePWM[j], EPWM_EMULATION_FREE_RUN); // // Set-up TBCLK // EPWM_setPeriodLoadMode(ePWM[j], EPWM_PERIOD_SHADOW_LOAD); EPWM_setTimeBasePeriod(ePWM[j], period-1); EPWM_setPhaseShift(ePWM[j], 0U); EPWM_setTimeBaseCounter(ePWM[j], 0U); // // set duty 50% initially // HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_A, (period/2 << 8)); HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_B, (period/2 << 8)); // // Set up counter mode // EPWM_setTimeBaseCounterMode(ePWM[j], EPWM_COUNTER_MODE_UP_DOWN); EPWM_disablePhaseShiftLoad(ePWM[j]); EPWM_setClockPrescaler(ePWM[j], EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); // // Set up shadowing // EPWM_setCounterCompareShadowLoadMode(ePWM[j], EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO); EPWM_setCounterCompareShadowLoadMode(ePWM[j], EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); // // Set actions // EPWM_setActionQualifierAction(ePWM[j], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); EPWM_setActionQualifierAction(ePWM[j], EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); EPWM_setActionQualifierAction(ePWM[j], EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); EPWM_setActionQualifierAction(ePWM[j], EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB); HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE); HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_DUTY_PERIOD_CTRL); HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD); HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE); HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_DUTY_PERIOD_CTRL); HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_B, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD); HRPWM_enableAutoConversion(ePWM[j]); // // Turn on high-resolution period control. // HRPWM_enablePeriodControl(ePWM[j]); HRPWM_enablePhaseShiftLoad(ePWM[j]); EPWM_forceSyncPulse(ePWM[j]); } } // // error - Halt debugger when called // void error (void) { ESTOP0; // Stop here and handle error }
Again trigger on rising edge, zoom into the following falling edge.
Change the TBPRDHR from 0 tp 0xE000 and see the shift.