我按照ecap_ex2_capture_pwm例程进行ecap方波捕获实验,当我捕获例程中产生的epwm波时,捕获值都是正确的。但当我用信号发生器输入同频率、同幅度的方波时,捕获值变得不正确。我尝试增加gpio口的采样时间来进行改善,但是没有任何效果。
以下是我的代码:
//#############################################################################
//
// 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:
// Copyright (C) 2013-2025 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"
//
// 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;
volatile uint32_t cap2Count;
volatile uint32_t cap3Count;
volatile uint32_t cap4Count;
volatile uint16_t epwm3PeriodCount;
//
// Function Prototypes
//
void initECAP(void);
void initEPWM(void);
__interrupt void ecap1ISR(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_EPWM3A);
GPIO_setPadConfig(5, GPIO_PIN_TYPE_STD);
GPIO_setPinConfig(GPIO_5_EPWM3B);
//
// Configure GPIO 16 as eCAP input
//
XBAR_setInputPin(XBAR_INPUT7, 16);
GPIO_setPinConfig(GPIO_16_GPIO16);
GPIO_setDirectionMode(16, GPIO_DIR_MODE_IN);
GPIO_setQualificationPeriod(16, 20);
//
// Interrupts that are used in this example are re-mapped to ISR functions
// found within this file.
//
Interrupt_register(INT_ECAP1, &ecap1ISR);
//
// Configure ePWM and eCAP
//
initEPWM();
initECAP();
//
// Initialize counters:
//
cap2Count = 0U;
cap3Count = 0U;
cap4Count = 0U;
ecap1IntCount = 0U;
ecap1PassCount = 0U;
epwm3PeriodCount = 0U;
//
// Enable interrupts required for this example
//
Interrupt_enable(INT_ECAP1);
//
// Enable Global Interrupt (INTM) and Real time interrupt (DBGM)
//
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, 50000);
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);
//
// Enable sync and clock to PWM
//
SysCtl_enablePeripheral(SYSCTL_PERIPH_CLK_TBCLKSYNC);
}
//
// initECAP - Configure eCAP
//
void initECAP()
{
ECAP_disableInterrupt(ECAP1_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_clearInterrupt(ECAP1_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));
//
// Disable CAP1-CAP4 register loads
//
ECAP_disableTimeStampCapture(ECAP1_BASE);
//
// Configure eCAP
// Enable capture mode.
// One shot mode, stop capture at event 4.
// Set polarity of the events to rising, falling, rising, falling edge.
// Set capture in time difference mode.
// Select input from XBAR7.
// Enable eCAP module.
// Enable interrupt.
//
ECAP_stopCounter(ECAP1_BASE);
ECAP_enableCaptureMode(ECAP1_BASE);
ECAP_setCaptureMode(ECAP1_BASE, ECAP_ONE_SHOT_CAPTURE_MODE, ECAP_EVENT_4);
ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_1, ECAP_EVNT_FALLING_EDGE);
ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_2, ECAP_EVNT_FALLING_EDGE);
ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_3, ECAP_EVNT_FALLING_EDGE);
ECAP_setEventPolarity(ECAP1_BASE, ECAP_EVENT_4, ECAP_EVNT_FALLING_EDGE);
ECAP_enableCounterResetOnEvent(ECAP1_BASE, ECAP_EVENT_1);
ECAP_enableCounterResetOnEvent(ECAP1_BASE, ECAP_EVENT_2);
ECAP_enableCounterResetOnEvent(ECAP1_BASE, ECAP_EVENT_3);
ECAP_enableCounterResetOnEvent(ECAP1_BASE, ECAP_EVENT_4);
XBAR_setInputPin(XBAR_INPUT7, 16);
ECAP_enableLoadCounter(ECAP1_BASE);
ECAP_setSyncOutMode(ECAP1_BASE, ECAP_SYNC_OUT_SYNCI);
ECAP_startCounter(ECAP1_BASE);
ECAP_enableTimeStampCapture(ECAP1_BASE);
//ECAP_reArm(ECAP1_BASE);
ECAP_reArm(ECAP1_BASE);
ECAP_enableInterrupt(ECAP1_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
}
//
// eCAP 1 ISR
//
__interrupt void ecap1ISR(void)
{
//
// Get the capture counts. Each capture should be 4x the ePWM count
// because of the ePWM clock dividers.
//
cap2Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_2);
cap3Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_3);
cap4Count = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_4);
//
// Clear interrupt flags for more interrupts.
//
ECAP_clearInterrupt(ECAP1_BASE,ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
ECAP_clearGlobalInterrupt(ECAP1_BASE);
//
// Start eCAP
//
ECAP_reArm(ECAP1_BASE);
//
// Acknowledge the group interrupt for more interrupts.
//
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
}
附上一些图片:

这张是采集自身epwm波时正确的捕获值;

这张是外部输入方波时错误的捕获值。
恳求大佬的帮助!
不胜感激!
