主题中讨论的其他器件:C2000WARE
大家好!
是否可以同时启用 TBPRDHR 和 CMPAHR?
TBPRDHR 和 CMPAHR 与 TRM "15.14.1.3 HRPWM 设置"中所述、
然而、在"边沿模式"中似乎只能选择 TBPRDHR 和 CMPAHR。
因此、就 TRM 而言、不可能同时支持两者。
此致、
伊藤
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.
大家好!
是否可以同时启用 TBPRDHR 和 CMPAHR?
TBPRDHR 和 CMPAHR 与 TRM "15.14.1.3 HRPWM 设置"中所述、
然而、在"边沿模式"中似乎只能选择 TBPRDHR 和 CMPAHR。
因此、就 TRM 而言、不可能同时支持两者。
此致、
伊藤
尊敬的 Ito:
我刚才整理了一些代码、使用我们现有的示例以高度简化的方式实现占空比控制和周期控制。 只使用 EPWM1模块(通道 A 和 B)、CMPxHR 值保持不变(可由用户更改)、TBPRDHR 递增时非常缓慢。
我建议您将一个现有示例(例如 {C2000Ware}\driverlib\f2837xd\examples\cpu\HRPWM\HRPWM_ex4_DUTY_updown_SFO)导入到 CCS 中、然后将 HRPWM_ex4_DUTY_updown_SFO.c 文件内容替换为下面的内容。 希望这有助于显示您应该实施哪些设置!
//#############################################################################
//
// FILE: hrpwm_simple_duty_and_period_control_updown_sfo.c
//
// TITLE: HRPWM DUTY and PERIOD CONTROL (simplified).
//
//#############################################################################
//
// This is a simplified HRPWM example where HRPWM duty control and
// HRPWM period control capability are both already set up for you on only
// one PWM module (EPWM1). This example uses CMPAHR, CMPBHR, and TBPRDHR to show the
// implementation of HR duty and period modulation together. The user can alter
// CMPAHR and CMPBHR values during run time in the register viewing window of CCS.
// the example slowly increments the TBPRDHR value to increase the TBPRDHR value.
// You can see the outputs of channels EPWM1A and EPWM1B change on an oscilloscope.
// Increasing CMPxHR values will decrease the duty cycle of channel 'x'.
// The incrementing of TBPRDHR will lower the frequency by lengthening the period of both channels.
//
// Period is incremented by default. To adjust the duty cycle while running the code:
// 1. Open the Registers window in CCS.
// 2. Turn on Continuous Refresh using the yellow arrows button.
// 3. Scroll to EPWM1 registers and expand them.
// 4. Find the CMPA and CMPB registers. Click the arrow to expand them so you see the HR elements.
// 5. Right-click on CMPAHR and CMPBHR and change the number formats to Hex for readability.
// 6. Double-click on the CMPAHR or CMPBHR register and change the value from 0x0100 to 0xFF00.
// This changes the CMPxHR value from 1 to the max (255). Maxing out CMPxHR to 255 should result
// in a 1-clock-cycle change.
//
// From here, you can continue to alter the HR numbers as needed for HR duty and period control.
//
//
//#############################################################################
//
// Included Files
//
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "SFO_V8.h"
//
// Defines
//
#define EPWM_TIMER_TBPRD 100UL // TBPRD value for this example is set to 100
#define LAST_EPWM_INDEX_FOR_EXAMPLE 2 // Used for the EPWM initialization function
//
// Globals
//
float32_t periodFine = 0.20; //HRPWM period percentage
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.
//
// Store the EPWM1 'base' name here (can append other EPWM modules as needed)
//
volatile uint32_t ePWM[] = {0, myEPWM1_BASE};
//
// Function Prototypes
//
void initHRPWM(uint32_t period);
void error(void);
__interrupt void epwm1ISR(void);
//
// 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();
//
// Assign the interrupt service routines to ePWM interrupts
//
Interrupt_register(INT_EPWM1, &epwm1ISR);
//
// Initialize the EPWM GPIOs and change XBAR inputs from using GPIO0
// This will implement any SysConfig configurations. Note that any configurations
// that occur after this will overwrite your SysConfig configurations.
//
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);
//
// Initialize the EPWM1 module in code with PRD set to EPWM_TIMER_TBPRD (in this example, 100)
//
initHRPWM(EPWM_TIMER_TBPRD);
//
// Enable sync and clock to PWM
//
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
// Enable ePWM interrupts
//
Interrupt_enable(INT_EPWM1);
//
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
//
EINT;
ERTM;
for(;;)
{
//
// Apply HRPWM Period Control (slowly increments 0.2 to 0.9 in 0.1 steps, then starts over)
//
for(periodFine = 0.2; periodFine < 0.9; periodFine += 0.1)
{
DEVICE_DELAY_US(1000000);
uint16_t i = 0;
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.
}
}
}
//
// Define the EPWM1 ISR
//
__interrupt void epwm1ISR(void)
{
//
// This is left empty for the user to fill as needed
//
EPWM_clearEventTriggerInterruptFlag(EPWM1_BASE); // Clear the interrupt flag from the PWM module
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP3); // Acknowledge the EPWM interrupt group in the PIE to reset the ACK bit
}
//
// Initialize your EPWM1 module as with HR configurations (PRD is function input)
//
void initHRPWM(uint32_t period)
{
uint16_t j;
// Parse through all EPWM modules you want this to apply to. In this case, only EPWM1 will be initalized.
for (j=1;j<LAST_EPWM_INDEX_FOR_EXAMPLE;j++)
{
//
// Set PWM mode to free run so that debugger does not stop it
//
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 up base duty to be 50% (CMPx = 50, TBPRD = 100)
// Initialize CMPxHR values to be 1 (these are within the CMPA and CMPB registers, but must be written to in a particular way as shown below.
//
HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_A, (period/2 << 8) + 1);
HRPWM_setCounterCompareValue(ePWM[j], HRPWM_COUNTER_COMPARE_B, (period/2 << 8) + 1);
//
// Set up counter mode to be up-down counter mode
//
EPWM_setTimeBaseCounterMode(ePWM[j], EPWM_COUNTER_MODE_UP_DOWN);
//
// Disable phase shifting
//
EPWM_disablePhaseShiftLoad(ePWM[j]);
//
// Set up both EPWM1 clock dividers and disable sync out pulses
//
EPWM_setClockPrescaler(ePWM[j],
EPWM_CLOCK_DIVIDER_1,
EPWM_HSCLOCK_DIVIDER_1);
EPWM_setSyncOutPulseMode(ePWM[j], EPWM_SYNC_OUT_PULSE_DISABLED);
//
// Set up shadowing
// MUST BE CTR=(ZER & PRD)
//
EPWM_setCounterCompareShadowLoadMode(ePWM[j],
EPWM_COUNTER_COMPARE_A,
EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);
EPWM_setCounterCompareShadowLoadMode(ePWM[j],
EPWM_COUNTER_COMPARE_B,
EPWM_COMP_LOAD_ON_CNTR_ZERO_PERIOD);
//
// Set up Action Qualifiers for Channels A and B
// (set high on CMPxU, set low on CMPxD for both channels)
//
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_A,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_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_B,
EPWM_AQ_OUTPUT_LOW,
EPWM_AQ_OUTPUT_ON_TIMEBASE_DOWN_CMPB);
//
// Select Channel A and B control mode to utilize CMPxHR or TBPRDHR
//
HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_DUTY_PERIOD_CTRL);
HRPWM_setMEPControlMode(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_DUTY_PERIOD_CTRL);
//
// Select Channel A and B edge mode to control both edges
//
HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_A, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);
HRPWM_setMEPEdgeSelect(ePWM[j], HRPWM_CHANNEL_B, HRPWM_MEP_CTRL_RISING_AND_FALLING_EDGE);
//
// Set up shadow loading for CMPAHR (this MUST be set to shadow load on CTR=(ZER & PRD))
//
HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_A, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);
HRPWM_setCounterCompareShadowLoadEvent(ePWM[j], HRPWM_CHANNEL_B, HRPWM_LOAD_ON_CNTR_ZERO_PERIOD);
//
// Turn on auto-conversion
//
HRPWM_enableAutoConversion(ePWM[j]);
//
// Turn on high-resolution period control in order to let HR duty control occur on BOTH EDGEs.
//
HRPWM_enablePeriodControl(ePWM[j]);
HRPWM_disablePhaseShiftLoad(ePWM[j]);
//
// Set up an empty interrupt where user can fill with whatever is desired
// Select INT on Time base counter zero event,
// Enable INT, generate INT on 1st event
//
EPWM_setInterruptSource(ePWM[j], EPWM_INT_TBCTR_ZERO);
EPWM_enableInterrupt(ePWM[j]);
EPWM_setInterruptEventCount(ePWM[j], 1U);
//
// 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
}
此致、
艾里森