Other Parts Discussed in Thread: TMDSCNCD280049C, TMS320F280049C, C2000WARE, SYSCONFIG
主题中讨论的其他器件:TMDSCNCD280049C、 C2000WARE、 SysConfig
大家好、
我正在尝试使用 C2000微控制器生成 PWM 信号。 但是、当我使用 HRPWM 时、我看到输出抖动。 对于配置、我在 CCS 中使用了.syscfg、我不知道我做了什么错误。
我使用的是集成在控制卡(TMDSCNCD280049C)中的 TMS320F280049C。 我使用 Code Composer Studio 版本12.1.0.00007进行编程。
我想实现高达10MHz 的 PWM 频率、恒定占空比为50%、死区时间可配置。 频率需要设置为高分辨率。 当我启用 HRPWM 周期控制(在.syscfg 中或通过 driverlib 函数 HRPWM_enablePeriodControl (PWM_base))时、我会获得抖动。
我知道、当存在同步事件或时基周期发生变化时、可能会发生抖动、但在我的情况下、两者都不会发生。 (至少我认为我已禁用所有同步事件)。
请在下面找到一个最小示例、其中我尝试实现2.10MHz 的 HRPWM。 我使用向上向下计数模式、并在计数器的值等于 CMPA 时设置输出引脚。 为了生成精确的 PWM 信号、启用了 CMPA 的高分辨率(MEP 控制上升沿和下降沿)以及具有自动 HRMSTEP 缩放功能的高分辨率周期。 我用示波器显示抖动的屏幕截图。
测量抖动的时间偏差会得到10ns 的增量 t、这正是所用 C2000的时钟。 因此、在我看来、HRPWM 根本不起作用。
此外、我注意到仅在启用 HR 周期控制时才会发生抖动-与 CMPAHR 无关。
非常感谢!
###代码:###
main.c:
// main.c
#include "board.h"
void main(void)
{
// Device Initialization
Device_init();
Board_init();
while(1)
{
}
}
自动生成 board.h:
/* * Copyright (c) 2020 Texas Instruments Incorporated - http://www.ti.com * All rights reserved. * * 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. * */ #ifndef BOARD_H #define BOARD_H // // Included Files // #include "driverlib.h" #include "device.h" #define GPIO_PIN_EPWM1_A 0 #define GPIO_PIN_EPWM1_B 1 #define PWM_BASE EPWM1_BASE void Board_init(); void EPWM_init(); void SYNC_init(); void PinMux_init(); #endif // end of BOARD_H definition
自动生成 board.c:
/* * Copyright (c) 2020 Texas Instruments Incorporated - http://www.ti.com * All rights reserved. * * 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. * */ #include "board.h" void Board_init() { EALLOW; PinMux_init(); SYNC_init(); EPWM_init(); EDIS; } void PinMux_init() { // // EPWM1 -> PWM Pinmux // GPIO_setPinConfig(GPIO_0_EPWM1_A); GPIO_setPinConfig(GPIO_1_EPWM1_B); } void EPWM_init(){ HRPWM_setEmulationMode(PWM_BASE, EPWM_EMULATION_FREE_RUN); HRPWM_setClockPrescaler(PWM_BASE, EPWM_CLOCK_DIVIDER_1, EPWM_HSCLOCK_DIVIDER_1); EPWM_setTimeBasePeriod(PWM_BASE, 23); HRPWM_setTimeBaseCounter(PWM_BASE, 0); HRPWM_setTimeBaseCounterMode(PWM_BASE, EPWM_COUNTER_MODE_UP_DOWN); HRPWM_disablePhaseShiftLoad(PWM_BASE); HRPWM_setPhaseShift(PWM_BASE, 0); HRPWM_setSyncOutPulseMode(PWM_BASE, EPWM_SYNC_OUT_PULSE_DISABLED); EPWM_setCounterCompareValue(PWM_BASE, EPWM_COUNTER_COMPARE_A, 11); HRPWM_setCounterCompareShadowLoadMode(PWM_BASE, EPWM_COUNTER_COMPARE_A, EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD); EPWM_setCounterCompareValue(PWM_BASE, EPWM_COUNTER_COMPARE_B, 0); HRPWM_setCounterCompareShadowLoadMode(PWM_BASE, EPWM_COUNTER_COMPARE_B, EPWM_COMP_LOAD_ON_CNTR_ZERO); HRPWM_setActionQualifierAction(PWM_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); HRPWM_setActionQualifierAction(PWM_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); HRPWM_setActionQualifierAction(PWM_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_HIGH, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); HRPWM_setActionQualifierAction(PWM_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_LOW, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); HRPWM_setActionQualifierAction(PWM_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); HRPWM_setActionQualifierAction(PWM_BASE, EPWM_AQ_OUTPUT_A, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB); HRPWM_setActionQualifierAction(PWM_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_ZERO); HRPWM_setActionQualifierAction(PWM_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD); HRPWM_setActionQualifierAction(PWM_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPA); HRPWM_setActionQualifierAction(PWM_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPA); HRPWM_setActionQualifierAction(PWM_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_UP_CMPB); HRPWM_setActionQualifierAction(PWM_BASE, EPWM_AQ_OUTPUT_B, EPWM_AQ_OUTPUT_NO_CHANGE, EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB); HRPWM_setDeadBandDelayPolarity(PWM_BASE, EPWM_DB_FED, EPWM_DB_POLARITY_ACTIVE_LOW); HRPWM_setDeadBandDelayMode(PWM_BASE, EPWM_DB_RED, true); HRPWM_setRisingEdgeDelayCount(PWM_BASE, 10); HRPWM_setDeadBandDelayMode(PWM_BASE, EPWM_DB_FED, true); HRPWM_setFallingEdgeDelayCount(PWM_BASE, 10); HRPWM_setDeadBandCounterClock(PWM_BASE, EPWM_DB_COUNTER_CLOCK_HALF_CYCLE); HRPWM_enableAutoConversion(PWM_BASE); HRPWM_setMEPEdgeSelect(PWM_BASE, HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE); HRPWM_setHiResCounterCompareValueOnly(PWM_BASE, HRPWM_COUNTER_COMPARE_A, 230); HRPWM_setCounterCompareShadowLoadEvent(PWM_BASE, HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD); HRPWM_enablePeriodControl(PWM_BASE); HRPWM_setHiResTimeBasePeriodOnly(PWM_BASE, 205); } void SYNC_init(){ SysCtl_setSyncOutputConfig(SYSCTL_SYNC_OUT_SRC_EPWM1SYNCOUT); // For EPWM1, the sync input is: SYSCTL_SYNC_IN_SRC_EXTSYNCIN1 SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM4, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT); SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_EPWM7, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT); SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_ECAP1, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT); SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_ECAP4, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT); SysCtl_setSyncInputConfig(SYSCTL_SYNC_IN_ECAP6, SYSCTL_SYNC_IN_SRC_EPWM1SYNCOUT); // SOCA SysCtl_enableExtADCSOCSource(0); // SOCB SysCtl_enableExtADCSOCSource(0); }
SYSCFG-文件:
/**
* These arguments were used when this file was generated. They will be automatically applied on subsequent loads
* via the GUI or CLI. Run CLI with '--help' for additional information on how to override these arguments.
* @cliArgs --device "F28004x" --package "F28004x_100PZ" --part "F28004x_100PZ" --product "C2000WARE@4.01.00.00"
* @versions {"tool":"1.14.0+2667"}
*/
/**
* Import the modules used in this configuration.
*/
const epwm = scripting.addModule("/driverlib/epwm.js");
const epwm1 = epwm.addInstance();
const sync = scripting.addModule("/driverlib/sync.js");
/**
* Write custom configuration values to the imported modules.
*/
epwm1.epwmTimebase_hsClockDiv = "EPWM_HSCLOCK_DIVIDER_1";
epwm1.epwmTimebase_counterMode = "EPWM_COUNTER_MODE_UP_DOWN";
epwm1.epwmTimebase_syncOutPulseMode = "EPWM_SYNC_OUT_PULSE_DISABLED";
epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_A_shadowMode = true;
epwm1.epwmDeadband_polarityFED = "EPWM_DB_POLARITY_ACTIVE_LOW";
epwm1.epwmDeadband_controlShadowMode = true;
epwm1.epwmDeadband_deadbandCounterClockRate = "EPWM_DB_COUNTER_CLOCK_HALF_CYCLE";
epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_UP_CMPA = "EPWM_AQ_OUTPUT_HIGH";
epwm1.epwmActionQualifier_EPWM_AQ_OUTPUT_A_ON_TIMEBASE_DOWN_CMPA = "EPWM_AQ_OUTPUT_LOW";
epwm1.hrpwm_HRLoadA = "HRPWM_LOAD_ON_CNTR_ZERO_PERIOD";
epwm1.epwmCounterCompare_shadowLoadModeCMPA = "EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD";
epwm1.epwmTimebase_emulationMode = "EPWM_EMULATION_FREE_RUN";
epwm1.epwmDeadband_enableRED = true;
epwm1.$name = "PWM";
epwm1.epwmDeadband_enableFED = true;
epwm1.epwmDeadband_delayRED = 10;
epwm1.epwmDeadband_delayFED = 10;
epwm1.hrpwm_enable = true;
epwm1.hrpwm_autoConv = true;
epwm1.useInterfacePins = ["EPWM#_A","EPWM#_B"];
epwm1.hrpwm_edgeModeA = "HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE";
epwm1.hrpwm_periodEnable = true;
epwm1.epwmTimebase_period = 23;
epwm1.hrpwm_tbprdHR = 205;
epwm1.epwmCounterCompare_cmpA = 11;
epwm1.hrpwm_cmpaHR = 230;
epwm1.epwm.$assign = "EPWM1";
/**
* Pinmux solution for unlocked pins/peripherals. This ensures that minor changes to the automatic solver in a future
* version of the tool will not impact the pinmux you originally saw. These lines can be completely deleted in order to
* re-solve from scratch.
*/
epwm1.epwm.epwm_aPin.$suggestSolution = "GPIO0";
epwm1.epwm.epwm_bPin.$suggestSolution = "GPIO1";

