工具与软件:
您好!
我将尝试从数据表中执行以下示例:

我完成了所有配置的不同之处在于我做了:
下降沿上的 CAP1
上升沿上的 CAP2
下降沿上的 CAP3
上升沿上的 CAP4
此外、我将中断设置为仅在 CAP4就绪时才触发。
然后在中断中、CAP2、CAP3、CAP4的值与预期一致、但 CAP1在第一个中断中的值并不完全相同、它离开了1000个计数、并且对于每个中断、它都在预期值附近保持去抖、所有其他 CAPS 始终是正确的。
下面是我所做配置的 sudo 代码:
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.
工具与软件:
您好!
我将尝试从数据表中执行以下示例:

我完成了所有配置的不同之处在于我做了:
下降沿上的 CAP1
上升沿上的 CAP2
下降沿上的 CAP3
上升沿上的 CAP4
此外、我将中断设置为仅在 CAP4就绪时才触发。
然后在中断中、CAP2、CAP3、CAP4的值与预期一致、但 CAP1在第一个中断中的值并不完全相同、它离开了1000个计数、并且对于每个中断、它都在预期值附近保持去抖、所有其他 CAPS 始终是正确的。
下面是我所做配置的 sudo 代码:
尊敬的 Esmail:
在执行单次触发模式时、请参阅有关 CAP1测量的此主题:
我希望这能解答您的问题。
此致、
Ryan Ma
尊敬的 Esmail:
即使在单次触发模式下、TSCTR 也会持续运行。 在每个事件上、TSCTR 将继续复位。 处于单次触发模式并达到 STOP_Wrap 值时、CAP1-4寄存器在下一次 RE ARM 之前不会再加载。
由于您在捕获事件4之后重新布防、因此 TSCTR 已经在连续计数、即使您将其复位、该值也将继续运行。 然后、如果您恰好在下降沿发生后对其进行 ARM、则会错过该事件、直到下一个下降沿将偏离 CAP1计数。
我建议使用 CAP2-4作为正确的值、就像在我们的软件示例中我们仅使用 CAP2-4作为有效测量一样。

此致!
Ryan Ma
您好、Ryan、
那么、如果我要执行以下操作:
1-配置。
2启动
3-获得 ISR (此处的 CAP1值将会出错、但没关系)
4 -在 ISR 结束时、我做了:
4.1-通过置位 ECCTL2 寄存器的 CTRFILTRESET 位进行计数器复位。
4.2-请重新布防。
然后、在下一个 ISR 中、该值应该是正确的。
此外、是否有任何可以完成的配置可以让我看到 CAP1正确值?
尊敬的 Esmail:
即使采用上述配置、在复位计数器时、计数器仍将连续运行。
尝试以下操作:
1-配置。
2启动
3-获得 ISR (此处的 CAP1值将会出错、但没关系)
4 -在 ISR 结束时、我做了:
设置 TSCTRSTOP = 0
4.1-通过置位 ECCTL2 寄存器的 CTRFILTRESET 位进行计数器复位。
4.2-请重新布防。
设置 TSCTRSTOP = 1
另一个选项是将 eCAP 配置为连续运行。 这将具有正确的 CAP1值、因为 CAP 寄存器将根据事件连续加载。
此致!
Ryan Ma
Ryan、您好!
感谢您的答复。 您在此提出的建议、因为我知道在捕获了每个 CAP (CAP2、CAP3和 CAP4)后、我需要重新布防/重置所有 CAPS?
-如果是这样,那么这不满足我正在尝试实施的测试案例,这是执行上述序列。
此外、我不关注脉冲宽度、而是将所有电容器设置为相同值。
此处的问题是、CAP1不会像其余电容那样冻结值、这个问题只会出现在 EPWM15中、但对于 EPWM10和 EPWM9、我们不会看到这个问题、那么您对此有何看法?
总之、最好能为我提供一个执行上述序列的测试用例、以便为 EPWM15和 CAP1值冻结。
如果我们实际上不能冻结 CAP1值、那么我想数据表或勘误表中应该会提供清晰的说明。
非常感谢。
Esmail
尊敬的 Esmail:

CAP1取决于从 CAP4到生成中断、然后到重新启用的时间、然后将记录下一个下降沿。 由于您是以单次触发模式运行、因此我要重申一点、每次捕获之间的时间取决于此时序、因此始终会发生这种情况。 当重新布防时、TSCTR 不会进行复位。
我希望这可以澄清您看到的问题。
我想问一下、让所有 CAP 寄存器保持相同值的预期用例是什么? 我无法肯定为什么 EPWM10/9您没有看到该问题、因为这应该无关紧要。
此致!
Ryan Ma
尊敬的 Esmail:
您可以尝试的另一个实验是在启用捕获事件4的中断之前、您可以确保在捕获事件2发生后重新激活。
下面是一个我编辑过的示例、为 CAP1捕获正确的值。
//#############################################################################
//
// FILE: ecap_capture_pwm.c
//
// TITLE: Capture ePWM3.
//
//! \addtogroup driver_example_list
//! <h1>eCAP Capture PWM Example</h1>
//!
//! This example configures ePWM3A for:
//! - Up count mode
//! - Period starts at 500 and goes up to 8000
//! - Toggle output on PRD
//!
//! eCAP1 is configured to capture the time between rising
//! and falling edge of the ePWM3A output.
//!
//! \b External \b Connections \n
//! - eCAP1 is on GPIO16
//! - ePWM3A is on GPIO4
//! - Connect GPIO4 to GPIO16.
//!
//! \b Watch \b Variables \n
//! - \b ecap1PassCount - Successful captures.
//! - \b ecap1IntCount - Interrupt counts.
//
//#############################################################################
//
//
// $Copyright: $
//#############################################################################
//
// Included Files
//
#include "driverlib.h"
#include "device.h"
#include "board.h"
//
// Defines
//
#define PWM3_TIMER_MIN 500U
#define PWM3_TIMER_MAX 8000U
#define EPWM_TIMER_UP 1U
#define EPWM_TIMER_DOWN 0U
//
// Globals
//
uint32_t ecap1IntCount;
uint32_t ecap1PassCount;
uint32_t epwm3TimerDirection;
volatile uint32_t cap1Count;
volatile uint32_t cap2Count;
volatile uint32_t cap3Count;
volatile uint32_t cap4Count;
volatile uint16_t epwm3PeriodCount;
//
// Function Prototypes
//
void error(void);
void initECAP(void);
void initEPWM(void);
//
// Main
//
void main(void)
{
//
// Initialize device clock and peripherals
//
Device_init();
//
// Disable pin locks and enable internal pullups.
//
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();
//
// Configure GPIO4/5 as ePWM3A/3B
//
GPIO_setPadConfig(4,GPIO_PIN_TYPE_STD);
GPIO_setPinConfig(GPIO_4_EPWM3_A);
GPIO_setPadConfig(5,GPIO_PIN_TYPE_STD);
GPIO_setPinConfig(GPIO_5_EPWM3_B);
//
// Board initialization
// Configure GPIO 16 as eCAP input
// Enable interrupts required for this example
//
Board_init();
//
// Configure ePWM
//
initEPWM();
//
// Initialize counters:
//
cap2Count = 0U;
cap3Count = 0U;
cap4Count = 0U;
ecap1IntCount = 0U;
ecap1PassCount = 0U;
epwm3PeriodCount = 0U;
//
// Enable Global Interrupt (INTM) and Real time interrupt (DBGM)
//
ECAP_clearInterrupt(myECAP0_BASE,
(ECAP_ISR_SOURCE_CAPTURE_EVENT_1 |
ECAP_ISR_SOURCE_CAPTURE_EVENT_2 |
ECAP_ISR_SOURCE_CAPTURE_EVENT_3 |
ECAP_ISR_SOURCE_CAPTURE_EVENT_4 |
ECAP_ISR_SOURCE_COUNTER_OVERFLOW |
ECAP_ISR_SOURCE_COUNTER_PERIOD |
ECAP_ISR_SOURCE_COUNTER_COMPARE));
ECAP_resetCounters(myECAP0_BASE);
ECAP_reArm(myECAP0_BASE);
while(!(ECAP_getInterruptSource(myECAP0_BASE) & ECAP_ISR_SOURCE_CAPTURE_EVENT_2))
{
}
ECAP_clearInterrupt(myECAP0_BASE,
(ECAP_ISR_SOURCE_CAPTURE_EVENT_1 |
ECAP_ISR_SOURCE_CAPTURE_EVENT_2 |
ECAP_ISR_SOURCE_CAPTURE_EVENT_3 |
ECAP_ISR_SOURCE_CAPTURE_EVENT_4 |
ECAP_ISR_SOURCE_COUNTER_OVERFLOW |
ECAP_ISR_SOURCE_COUNTER_PERIOD |
ECAP_ISR_SOURCE_COUNTER_COMPARE));
ECAP_resetCounters(myECAP0_BASE);
ECAP_reArm(myECAP0_BASE);
ECAP_enableInterrupt(myECAP0_BASE,(ECAP_ISR_SOURCE_CAPTURE_EVENT_4));
EINT;
ERTM;
//
// Loop forever. Suspend or place breakpoints to observe the buffers.
//
for(;;)
{
NOP;
}
}
//
// initEPWM - Configure ePWM
//
void initEPWM()
{
//
// Disable sync(Freeze clock to PWM as well)
//
SysCtl_disablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
//
// Configure ePWM
// Counter runs in up-count mode.
// Action qualifier will toggle output on period match
//
EPWM_setTimeBaseCounterMode(EPWM3_BASE, EPWM_COUNTER_MODE_UP);
EPWM_setTimeBasePeriod(EPWM3_BASE, PWM3_TIMER_MIN);
EPWM_setPhaseShift(EPWM3_BASE, 0U);
EPWM_setActionQualifierAction(EPWM3_BASE,
EPWM_AQ_OUTPUT_A,
EPWM_AQ_OUTPUT_TOGGLE,
EPWM_AQ_OUTPUT_ON_TIMEBASE_PERIOD);
EPWM_setClockPrescaler(EPWM3_BASE,
EPWM_CLOCK_DIVIDER_1,
EPWM_HSCLOCK_DIVIDER_2);
epwm3TimerDirection = EPWM_TIMER_UP;
//
// Enable sync and clock to PWM
//
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
}
//
// myECAP0 ISR
//
__interrupt void INT_myECAP0_ISR(void)
{
//
// Get the capture counts. Each capture should be 4x the ePWM count
// because of the ePWM clock divider.
//
cap1Count = ECAP_getEventTimeStamp(myECAP0_BASE, ECAP_EVENT_1);
cap2Count = ECAP_getEventTimeStamp(myECAP0_BASE, ECAP_EVENT_2);
cap3Count = ECAP_getEventTimeStamp(myECAP0_BASE, ECAP_EVENT_3);
cap4Count = ECAP_getEventTimeStamp(myECAP0_BASE, ECAP_EVENT_4);
//
// Compare the period value with the captured count
//
epwm3PeriodCount = EPWM_getTimeBasePeriod(EPWM3_BASE);
// if(cap2Count > ((epwm3PeriodCount *4) + 4) ||
// cap2Count < ((epwm3PeriodCount *4) - 4))
// {
// error();
// }
//
// if(cap3Count > ((epwm3PeriodCount *4) + 4) ||
// cap3Count < ((epwm3PeriodCount *4) - 4))
// {
// error();
// }
//
// if(cap4Count > ((epwm3PeriodCount *4) + 4) ||
// cap4Count < ((epwm3PeriodCount *4) - 4))
// {
// error();
// }
ecap1IntCount++;
//
// Keep track of the ePWM direction and adjust period accordingly to
// generate a variable frequency PWM.
//
if(epwm3TimerDirection == EPWM_TIMER_UP)
{
if(epwm3PeriodCount < PWM3_TIMER_MAX)
{
EPWM_setTimeBasePeriod(EPWM3_BASE, ++epwm3PeriodCount);
}
else
{
epwm3TimerDirection = EPWM_TIMER_DOWN;
EPWM_setTimeBasePeriod(EPWM3_BASE, ++epwm3PeriodCount);
}
}
else
{
if(epwm3PeriodCount > PWM3_TIMER_MIN)
{
EPWM_setTimeBasePeriod(EPWM3_BASE, --epwm3PeriodCount);
}
else
{
epwm3TimerDirection = EPWM_TIMER_UP;
EPWM_setTimeBasePeriod(EPWM3_BASE, ++epwm3PeriodCount);
}
}
//
// Count correct captures
//
ecap1PassCount++;
//
// Clear interrupt flags for more interrupts.
//
ECAP_clearInterrupt(myECAP0_BASE,ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
ECAP_clearGlobalInterrupt(myECAP0_BASE);
//
// Start eCAP
//
ECAP_reArm(myECAP0_BASE);
//
// Acknowledge the group interrupt for more interrupts.
//
Interrupt_clearACKGroup(INT_myECAP0_INTERRUPT_ACK_GROUP);
}
//
// error - Error function
//
void error()
{
ESTOP0;
}
const ecap = scripting.addModule("/driverlib/ecap.js", {}, false);
const ecap1 = ecap.addInstance();
const gpio = scripting.addModule("/driverlib/gpio.js", {}, false);
const gpio1 = gpio.addInstance();
const inputxbar = scripting.addModule("/driverlib/inputxbar.js", {}, false);
const inputxbar1 = inputxbar.addInstance();
const inputxbar_input = scripting.addModule("/driverlib/inputxbar_input.js");
const inputxbar_input1 = inputxbar_input.addInstance();
/**
* Write custom configuration values to the imported modules.
*/
ecap1.$name = "myECAP0";
ecap1.captureMode = "ECAP_ONE_SHOT_CAPTURE_MODE";
ecap1.eventStop = "ECAP_EVENT_4";
ecap1.eventOnePolarity = "ECAP_EVNT_FALLING_EDGE";
ecap1.eventThreePolarity = "ECAP_EVNT_FALLING_EDGE";
ecap1.interruptSourceCapture = ["ECAP_ISR_SOURCE_CAPTURE_EVENT_4"];
ecap1.counterResetOnEvent = ["ECAP_EVENT_1","ECAP_EVENT_2","ECAP_EVENT_3","ECAP_EVENT_4"];
ecap1.enableLoadCounter = true;
ecap1.ecapInput = "ECAP_INPUT_INPUTXBAR7";
ecap1.registerInterrupts = true;
ecap1.reArm = false;
ecap1.ecapInt.enableInterrupt = true;
gpio1.$name = "myGPIO0";
gpio1.qualMode = "GPIO_QUAL_ASYNC";
gpio1.gpioPin.$assign = "GPIO16";
inputxbar1.$name = "myINPUTXBAR0";
inputxbar_input1.$name = "myINPUTXBARINPUT0";
inputxbar_input1.inputxbarInput = "XBAR_INPUT7";
inputxbar_input1.inputxbarGpio = "GPIO16";
此致!
Ryan Ma
这是正确的行为。 我要归档 JIRA、以确保我们在 TRM 中更清楚地表明重新定位后 TSCTR 不会复位。
此致!
Ryan Ma