我打算用ecap模块来捕获方波的频率,并按照ecap_ex2_capture_pwm例程来修改了代码。在调试过程中我发现如果将断点打在某些位置会导致捕获到的数据出错,类似以下位置:

但如果将断点打在延时函数后,就不会产生错误。
这种情况不是第一次出现了,我之前在调试串口通信时发现如果断点打在串口发送函数之后,会导致发送的数据丢失最后两个比特。我很疑惑为什么会产生这种情况,对于串口,我认为是在中断时串口的发送缓冲区里的数据并未发出,所以会导致比特丢失。但对于ecap模块的这个情况,我理解不了错误产生的原因。
我的代码如下:
#include "F28x_Project.h"
#include "driverlib.h"
#include "device.h"
#include "uart.h"
#include "user_ecap.h"
volatile uint32_t cap1Count2;
volatile uint32_t cap1Count3;
volatile uint32_t cap1Count4;
volatile uint32_t cap2Count2;
volatile uint32_t cap2Count3;
volatile uint32_t cap2Count4;
volatile uint16_t cap1_flag;
volatile uint16_t cap2_flag;
volatile uint16_t f1_flag;
volatile uint16_t f2_flag;
volatile float pulse_f1;
volatile float pulse_f2;
volatile uint32_t time = 0;
void initEcapGpio(XBAR_InputNum input, uint16_t pin, uint32_t pinConfig);
void initECAP(uint32_t base, XBAR_InputNum input, uint16_t pin);
void CapPulse(uint32_t base);
void EnableEcapInterrupt(uint32_t interruptNumber, void (*handler)(void));
__interrupt void ecap1ISR(void);
__interrupt void ecap2ISR(void);
void main(void)
{
// Initialize device clock and peripherals
Device_init();
// Initialize GPIO and configure the GPIO pin as a push-pull output
Device_initGPIO();
#ifdef _STANDALONE
#ifdef _FLASH
// Send boot command to allow the CPU2 application to begin execution
Device_bootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_FLASH);
#else
// Send boot command to allow the CPU2 application to begin execution
Device_bootCPU2(C1C2_BROM_BOOTMODE_BOOT_FROM_RAM);
#endif // _FLASH
#endif // _STANDALONE
// 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();
EnableEcapInterrupt(INT_ECAP1, &ecap1ISR);
EnableEcapInterrupt(INT_ECAP2, &ecap2ISR);
// Enable Global Interrupt (INTM) and realtime interrupt (DBGM)
EINT;
ERTM;
GPIO_setPadConfig(92, GPIO_PIN_TYPE_PULLUP); // Enable pullup on GPIO92
GPIO_writePin(92, 1); // Load output latch
GPIO_setPinConfig(GPIO_92_GPIO92); // GPIO92 = GPIO92
GPIO_setDirectionMode(92, GPIO_DIR_MODE_OUT); // GPIO92 = output
//initIPC(IPC_CPU1_L_CPU2_R, IPC_FLAG31);
initEcapGpio(XBAR_INPUT7, 32, GPIO_32_GPIO32);
initEcapGpio(XBAR_INPUT8, 34, GPIO_34_GPIO34);
initECAP(ECAP1_BASE, XBAR_INPUT7, 32);
initECAP(ECAP2_BASE, XBAR_INPUT8, 34);
f1_flag = 0;
f2_flag = 0;
cap1_flag = 0;
cap2_flag = 0;
for (;;)
{
if (!cap1_flag)
{
CapPulse(ECAP1_BASE);
DEVICE_DELAY_US(1000);
cap1_flag = 1;
}
if (!cap2_flag)
{
CapPulse(ECAP2_BASE);
DEVICE_DELAY_US(1000);
cap2_flag = 1;
}
if (f1_flag)
{
uint32_t temp = 0;
cap1Count2 = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_2);
cap1Count3 = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_3);
cap1Count4 = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_4);
temp = cap1Count2 + cap1Count3 + cap1Count4;
temp /= 3;
pulse_f1 = 200000000.0 / (float)temp;
f1_flag = 0;
cap1_flag = 0;
}
if (f2_flag)
{
uint32_t temp = 0;
cap2Count2 = ECAP_getEventTimeStamp(ECAP2_BASE, ECAP_EVENT_2);
cap2Count3 = ECAP_getEventTimeStamp(ECAP2_BASE, ECAP_EVENT_3);
cap2Count4 = ECAP_getEventTimeStamp(ECAP2_BASE, ECAP_EVENT_4);
temp = cap2Count2 + cap2Count3 + cap2Count4;
temp /= 3;
pulse_f2 = 200000000.0 / (float)temp;
f2_flag = 0;
cap2_flag = 0;
}
//如果中断打在这里会导致捕获数据出错
DEVICE_DELAY_US(500000);
//如果中断打在延时函数后数据就是正确的
time++;
if (time > 2097152)
{
GPIO_togglePin(92);
time = 0;
}
// Software breakpoint.
// Hit run again to get updated conversions.
//ESTOP0;
}
}
void initEcapGpio(XBAR_InputNum input, uint16_t pin, uint32_t pinConfig)
{
XBAR_setInputPin(input, pin);
GPIO_setPinConfig(pinConfig);
GPIO_setPadConfig(pin, GPIO_PIN_TYPE_PULLUP);
GPIO_setDirectionMode(pin, GPIO_DIR_MODE_IN);
GPIO_setQualificationMode(pin, GPIO_QUAL_ASYNC);
}
void initECAP(uint32_t base, XBAR_InputNum input, uint16_t pin)
{
// Disable ,clear all capture flags and interrupts
ECAP_disableInterrupt(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(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(base);
//
// Configure eCAP
// Enable capture mode.
// One shot mode, stop capture at event 4.
// Set polarity of the events to rising, rising, rising, rising edge.
// Set capture in time difference mode.
// Select input from XBAR7.
// Enable eCAP module.
// Enable interrupt.
//
ECAP_stopCounter(base);
ECAP_enableCaptureMode(base);
ECAP_setCaptureMode(base, ECAP_ONE_SHOT_CAPTURE_MODE, ECAP_EVENT_4);
ECAP_setEventPolarity(base, ECAP_EVENT_1, ECAP_EVNT_RISING_EDGE);
ECAP_setEventPolarity(base, ECAP_EVENT_2, ECAP_EVNT_RISING_EDGE);
ECAP_setEventPolarity(base, ECAP_EVENT_3, ECAP_EVNT_RISING_EDGE);
ECAP_setEventPolarity(base, ECAP_EVENT_4, ECAP_EVNT_RISING_EDGE);
ECAP_enableCounterResetOnEvent(base, ECAP_EVENT_1);
ECAP_enableCounterResetOnEvent(base, ECAP_EVENT_2);
ECAP_enableCounterResetOnEvent(base, ECAP_EVENT_3);
ECAP_enableCounterResetOnEvent(base, ECAP_EVENT_4);
XBAR_setInputPin(input, pin);
ECAP_enableLoadCounter(base);
ECAP_setSyncOutMode(base, ECAP_SYNC_OUT_SYNCI);
ECAP_startCounter(base);
ECAP_enableTimeStampCapture(base);
ECAP_reArm(base);
ECAP_enableInterrupt(base, ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
}
void EnableEcapInterrupt(uint32_t interruptNumber, void (*handler)(void))
{
Interrupt_register(interruptNumber, handler);
Interrupt_enable(interruptNumber);
}
void CapPulse(uint32_t base)
{
// Start eCAP
ECAP_reArm(base);
}
// eCAP 1 ISR
#pragma CODE_SECTION(ecap1ISR, ".TI.ramfunc");
__interrupt void ecap1ISR(void)
{
f1_flag = 1;
// Get the capture counts.
//cap1Count2 = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_2);
//cap1Count3 = ECAP_getEventTimeStamp(ECAP1_BASE, ECAP_EVENT_3);
//cap1Count4 = 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);
// Acknowledge the group interrupt for more interrupts.
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
}
// eCAP 2 ISR
#pragma CODE_SECTION(ecap2ISR, ".TI.ramfunc");
__interrupt void ecap2ISR(void)
{
f2_flag = 1;
//uint32_t temp=0;
// Get the capture counts.
//cap2Count2 = ECAP_getEventTimeStamp(ECAP2_BASE, ECAP_EVENT_2);
//cap2Count3 = ECAP_getEventTimeStamp(ECAP2_BASE, ECAP_EVENT_3);
//cap2Count4 = ECAP_getEventTimeStamp(ECAP2_BASE, ECAP_EVENT_4);
// Clear interrupt flags for more interrupts.
ECAP_clearInterrupt(ECAP2_BASE, ECAP_ISR_SOURCE_CAPTURE_EVENT_4);
ECAP_clearGlobalInterrupt(ECAP2_BASE);
// Acknowledge the group interrupt for more interrupts.
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP4);
}
希望能有大佬帮忙分析以下。
不胜感激!
