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.
Hi,
i want to use the HRPWM module to generate a PWM signal at 2.5MHz. I tried the different configurations but their are still some problems.
By using the up-count mode the HR dutycycle works, if the PRDHR register is zero. But as soon as I set the PRDHR value to unequal zero, I get jitter on the generated signal.
I started with the hrpwm_ex2_prdupdown_sfo_v8 example and changed count mode and action qualifier configuration. Please see following code:
EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the EPWM EDIS; EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load EPwm1Regs.TBPRD = period; EPwm1Regs.TBPRDHR = (uint16_t)128 << 8; EPwm1Regs.CMPA.bit.CMPA = period / 2; // set duty 50% initially EPwm1Regs.CMPA.bit.CMPAHR = ((uint16_t)0 << 8); // initialize HRPWM extension EPwm1Regs.CMPB.bit.CMPB = period / 2; // set duty 50% initially EPwm1Regs.CMPB.all |= 0; EPwm1Regs.TBPHS.all = 0; EPwm1Regs.TBCTR = 0; EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Select up count mode EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT EPwm1Regs.TBCTL.bit.FREE_SOFT = 11; EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD; EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD; EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; EALLOW; EPwm1Regs.HRCNFG.all = 0x0; EPwm1Regs.HRCNFG.bit.EDGMODE = HR_BEP; // MEP control on both edges. EPwm1Regs.HRCNFG.bit.CTLMODE = HR_CMP; // CMPAHR and TBPRDHR HR control. EPwm1Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD EPwm1Regs.HRCNFG.bit.EDGMODEB = HR_BEP; // MEP control on both edges EPwm1Regs.HRCNFG.bit.CTLMODEB = HR_CMP; // CMPBHR and TBPRDHR HR control EPwm1Regs.HRCNFG.bit.HRLOADB = HR_CTR_ZERO_PRD; // load on CTR = 0 and CTR = TBPRD EPwm1Regs.HRCNFG.bit.AUTOCONV = 1; // Enable autoconversion for HR period EPwm1Regs.HRPCTL.bit.TBPHSHRLOADE = 1; // Enable TBPHSHR sync EPwm1Regs.HRPCTL.bit.HRPE = 1; // Turn on high-resolution period control. EPwm1Regs.TBCTL.bit.PHSEN = 1; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the EPWM EPwm1Regs.TBCTL.bit.SWFSYNC = 1; // Synchronize high resolution phase to start HR period EDIS;
For demonstration I set period to 40 and PRDHR to 128 (see code above). In the scope screenshoots you can see, that the second pulse jitters by 10ns (1Sysclk). The third pulse stay stabil. By other values the following pulses jitter also.
Can anybody help me with this? Is in the config a fault?
Is there a restriction by using HR dutycycle and period control at the same time? I found in the Reference Manual only Duty Cycle Range Limitation, but this is not concern this here (CMPx is period/2).
Thanks
Hi,
the config is the same as in the first post. See attached file.
Or should I attach the whole project?
//############################################################################# // // FILE: hrpwm_ex2_prdupdown_sfo_v8.c // // TITLE: HRPWM SFO V8 High-Resolution Period (Up-Down Count) example // //! \addtogroup bitfield_example_list //! <h1>HRPWM Period Up-Down Count</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. //! //! To run this example: //! -# Run this example at maximum SYSCLKOUT //! -# Activate Real time mode //! -# Run the code //! //! \b External \b Connections \n //! - Monitor ePWM1 A/B pins on an oscilloscope. //! //! \b Watch \b Variables \n //! - UpdateFine - Set to 1 use HRPWM capabilities and observe in fine MEP //! steps(default) //! Set to 0 to disable HRPWM capabilities and observe in //! coarse SYSCLKOUT cycle steps //! // //############################################################################# // $TI Release: F28004x Support Library v1.05.00.00 $ // $Release Date: Tue Jun 26 03:10:30 CDT 2018 $ // $Copyright: // Copyright (C) 2018 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 "F28x_Project.h" #include "SFO_V8.h" // // Defines // #define PWM_CH 3 // # of PWM channels - 1 #define STATUS_SUCCESS 1 #define STATUS_FAIL 0 // // Globals // uint16_t UpdateFine, PeriodFine, status, cmpfine; 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(0) function. // Used by SFO library (ePWM[0] is a dummy value that isn't used) volatile struct EPWM_REGS *ePWM[PWM_CH] = {&EPwm1Regs, &EPwm1Regs, &EPwm2Regs}; // // Function Prototypes // void initHRPWM1GPIO(void); void configHRPWM(uint16_t period); void error(void); // // Main // void main(void) { uint16_t i; // // Initialize device clock and peripherals // InitSysCtrl(); // // Initialize GPIO // InitGpio(); initHRPWM1GPIO(); ClkCfgRegs.CLKSRCCTL3.bit.XCLKOUTSEL = 2; //sysclk (0: pllsysclk) ClkCfgRegs.XCLKOUTDIVSEL.bit.XCLKOUTDIV = 0; // prescale /8 GPIO_SetupPinMux(16, 0, 11); // Finally, connect GPIO16 or GPIO18 to mux channel 11 using the GPIO configuration registers. // // Initialize PIE and clear PIE registers. Disables CPU interrupts. // DINT; InitPieCtrl(); IER = 0x0000; IFR = 0x0000; // // Initialize the PIE vector table with pointers to the shell Interrupt // Service Routines (ISR). // InitPieVectTable(); // // Setup example variables // UpdateFine = 1; PeriodFine = 0; status = SFO_INCOMPLETE; cmpfine = 0; // // Enable Global Interrupt (INTM) and realtime interrupt (DBGM) // EINT; ERTM; // // ePWM and HRPWM register initialization // for(i=1; i<PWM_CH; i++) { // Change clock divider to /1 // (PWM clock needs to be > 60MHz) (*ePWM[i]).TBCTL.bit.HSPCLKDIV = 0; } configHRPWM(40); // // 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. } for(;;) { PeriodFine++; if (PeriodFine > 0xFF){ PeriodFine = 0; } cmpfine++; if (cmpfine > 0xAFF){ cmpfine = 0x5FF; } for(i=1; i<PWM_CH; i++) { (*ePWM[i]).TBPRDHR = PeriodFine<<8; //In Q16 format // (*ePWM[i]).CMPA.bit.CMPAHR = (cmpfine << 8); //(*ePWM[i]).CMPA.bit.CMPA = (cmpfine >> 8); } // // Call the scale factor optimizer lib function SFO(0) // 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. HRMSTEP // register is automatically updated by the SFO function. // 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. } DELAY_US(1000*10); } // end infinite for loop } // // configHRPWM - Configures all ePWM channels and sets up HRPWM // on ePWMxA channels & ePWMxB channels // void configHRPWM(uint16_t period) { // // ePWM channel register configuration with HRPWM // ePWMxA toggle low/high with MEP control on Rising edge // EALLOW; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Disable TBCLK within the EPWM EDIS; EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW; // set Shadow load EPwm1Regs.TBPRD = period; // PWM frequency = 1/(2*TBPRD) EPwm1Regs.TBPRDHR = (uint16_t)128 << 8; EPwm1Regs.CMPA.bit.CMPA = period / 2; // set duty 50% initially EPwm1Regs.CMPA.bit.CMPAHR = ((uint16_t)1 << 8); // initialize HRPWM extension EPwm1Regs.CMPB.bit.CMPB = period / 2; // set duty 50% initially EPwm1Regs.CMPB.all |= 0; EPwm1Regs.TBPHS.all = 0; EPwm1Regs.TBCTR = 0; EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Select up-down // count mode EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_DISABLE; EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT EPwm1Regs.TBCTL.bit.FREE_SOFT = 11; EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_PRD; // LOAD CMPA on CTR = 0 EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_PRD; EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW; EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW; EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR; EPwm1Regs.AQCTLB.bit.ZRO = AQ_SET; EPwm1Regs.AQCTLB.bit.CBU = AQ_CLEAR; EALLOW; EPwm1Regs.HRCNFG.all = 0x0; EPwm1Regs.HRCNFG.bit.EDGMODE = HR_BEP; // MEP control on // both edges. EPwm1Regs.HRCNFG.bit.CTLMODE = HR_CMP; // CMPAHR and TBPRDHR // HR control. EPwm1Regs.HRCNFG.bit.HRLOAD = HR_CTR_ZERO_PRD; // load on CTR = 0 // and CTR = TBPRD EPwm1Regs.HRCNFG.bit.EDGMODEB = HR_BEP; // MEP control on // both edges EPwm1Regs.HRCNFG.bit.CTLMODEB = HR_CMP; // CMPBHR and TBPRDHR // HR control EPwm1Regs.HRCNFG.bit.HRLOADB = HR_CTR_ZERO_PRD; // load on CTR = 0 // and CTR = TBPRD EPwm1Regs.HRCNFG.bit.AUTOCONV = 1; // Enable autoconversion for // HR period EPwm1Regs.HRPCTL.bit.TBPHSHRLOADE = 1; // Enable TBPHSHR sync // (required for updwn // count HR control) EPwm1Regs.HRPCTL.bit.HRPE = 1; // Turn on high-resolution // period control. EPwm1Regs.TBCTL.bit.PHSEN = 1; CpuSysRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Enable TBCLK within the EPWM EPwm1Regs.TBCTL.bit.SWFSYNC = 1; // Synchronize high resolution phase to start HR period EDIS; } // // initHRPWM1GPIO - Initialize HRPWM1 GPIOs // void initHRPWM1GPIO(void) { EALLOW; // // Disable internal pull-up for the selected output pins // for reduced power consumption // Pull-ups can be enabled or disabled by the user. // GpioCtrlRegs.GPAPUD.bit.GPIO0 = 1; // Disable pull-up on GPIO0 (EPWM1A) GpioCtrlRegs.GPAPUD.bit.GPIO1 = 1; // Disable pull-up on GPIO1 (EPWM1B) // // Configure EPWM-1 pins using GPIO regs // This specifies which of the possible GPIO pins will be EPWM1 functional // pins. // GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // Configure GPIO0 as EPWM1A GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // Configure GPIO1 as EPWM1B GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // Configure GPIO2 as EPWM2A GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; // Configure GPIO3 as EPWM2B EDIS; } // // error - Halt debugger when error occurs // void error (void) { ESTOP0; // Stop here and handle error } // // End of file //
Hi,
do you have already found out anything?
I tried now to config the deadband module. On EPWM1 the deadband is enabled in "Active high complementary" mode. So the rising edge of EPWM1xA will be delayed. For channel B the falling edge of A will be delayed, and the signal will then be inverted. For comparison I enabled also EPWM2. EPWM2A is set on ZRO and cleared on CMPA, EPWM2B is set on CMPA ant cleared on PRD.
As you can see in the screenshot of the scope, there is some jitter at the rising edge of EPWM1B (point in time equivalent to Counter=Zero). In the image I overlayed screenshots of the two extreme cases, but there are also edges between them.
Here the PRDHR register is unequal 0. If PRDHR = 0, there is no jitter.
So this seems to be the same problem like above (Jitter when Action Qualifier on CTR = ZRO). But interesting is that the rising edge of EPMW1A is stable, which means that the Deadband Rising Edge Delay compensate the jitter on the zero edge. Is that right?
How can I avoid the Jitter on EPWM1B?
Thanks