Tool/software: Code Composer Studio
Here is my code:
//###########################################################################
// Description:
//! \addtogroup f2833x_example_list
//! <h1> eCap capture PWM (ecap_capture_pwm)</h1>
//!
//! This example configures ePWM3A for:
//! - Up count
//! - Period starts at 2 and goes up to 1000
//! - 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 GPIO24
//! - ePWM3A is on GPIO4
//! - Connect GPIO4 to GPIO24.
//!
//! \b Watch \b Variables \n
//! - ECap1IntCount - Successful captures
//! - ECap1PassCount - Interrupt counts
//
//###########################################################################
// $TI Release: F2833x/F2823x Header Files and Peripheral Examples V140 $
// $Release Date: March 4, 2015 $
// $Copyright: Copyright (C) 2007-2015 Texas Instruments Incorporated -
// http://www.ti.com/ ALL RIGHTS RESERVED $
//###########################################################################
#include "DSP28x_Project.h" // Device Headerfile and Examples Include File
#define POST_SHIFT 1 // Shift results after the entire sample table is full
#define INLINE_SHIFT 0 // Shift results as the data is taken from the results regsiter
#define NO_SHIFT 0 // Do not shift the results
// ADC start parameters
#if (CPU_FRQ_150MHZ) // Default - 150 MHz SYSCLKOUT
#define ADC_MODCLK 0x3 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 150/(2*3) = 25.0 MHz
#endif
#if (CPU_FRQ_100MHZ)
#define ADC_MODCLK 0x2 // HSPCLK = SYSCLKOUT/2*ADC_MODCLK2 = 100/(2*2) = 25.0 MHz
#endif
#define ADC_CKPS 0x0 // ADC module clock = HSPCLK/1 = 25.5MHz/(1) = 25.0 MHz
#define ADC_SHCLK 0x1 // S/H width in ADC module periods = 2 ADC cycle
#define AVG 1000 // Average sample limit
#define ZOFFSET 0x00 // Average Zero offset
#define BUF_SIZE 1024 // Sample buffer size
#define NR(x) (sizeof(x)/sizeof(x[0]))
#pragma DATA_SECTION()
// Global variable for this example
Uint16 SampleTable[BUF_SIZE];
Uint16 DataTable[BUF_SIZE];
Uint16 j;
__interrupt void ecap1_isr(void);
void InitECapture(void);
void Fail(void);
// Global variables used in this example
Uint32 ECap1IntCount;
Uint32 ECap1PassCount;
Uint16 array_index = 0;
// To keep track of which way the timer value is moving
void main(void)
{
static Uint16 i;
static Uint16 j;
InitSysCtrl();
EALLOW;
SysCtrlRegs.HISPCP.all = ADC_MODCLK;
EDIS;
EALLOW;
GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0; // GPIO
GpioCtrlRegs.GPBDIR.bit.GPIO34 = 1; // Output
EDIS;
InitECap1Gpio();
// Step 3. Clear all interrupts and initialize PIE vector table:
// Disable CPU interrupts
DINT;
// Initialize the PIE control registers to their default state.
// The default state is all PIE interrupts disabled and flags
// are cleared.
// This function is found in the DSP2833x_PieCtrl.c file.
InitPieCtrl();
// Disable CPU interrupts and clear all CPU interrupt flags:
IER = 0x0000;
IFR = 0x0000;
// Initialize the PIE vector table with pointers to the shell Interrupt
// Service Routines (ISR).
// This will populate the entire table, even if the interrupt
// is not used in this example. This is useful for debug purposes.
// The shell ISR routines are found in DSP2833x_DefaultIsr.c.
// This function is found in DSP2833x_PieVect.c.
InitPieVectTable();
InitAdc();
// Interrupts that are used in this example are re-mapped to
// ISR functions found within this file.
EALLOW; // This is needed to write to EALLOW protected registers
PieVectTable.ECAP1_INT = &ecap1_isr;
EDIS; // This is needed to disable write to EALLOW protected registers
// Step 4. Initialize all the Device Peripherals:
// This function is found in DSP2833x_InitPeripherals.c
// InitPeripherals(); // Not required for this example
//initialize GPIO I don't understand why this can enable interrupt.
EALLOW;
GpioCtrlRegs.GPBMUX2.bit.GPIO60 = 0;
GpioCtrlRegs.GPBDIR.bit.GPIO60 = 0;
EDIS;
InitECapture();
// Step 5. User specific code, enable interrupts:
// Specific ADC setup for this example:
AdcRegs.ADCTRL1.bit.ACQ_PS = ADC_SHCLK;
/* Sequential mode:Sample rate = 1/[(2+ACQ_PS)*ADC clock in ns]
= 1/(3*40ns) = 8.3MHz (for 150MHz SYSCLKOUT)
= 1/(3*80ns) = 4.17MHz(for 100MHz SYSCLKOUT)
If Simultaneous mode enabled: Sample rate = 1/[(3+ACQ_PS)*ADC clock in ns] */
AdcRegs.ADCTRL3.bit.ADCCLKPS = ADC_CKPS;
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 1 Cascaded mode
AdcRegs.ADCCHSELSEQ1.bit.CONV00 = 0x0;
AdcRegs.ADCTRL1.bit.CONT_RUN = 0; // Start-Stop mode
AdcRegs.ADCTRL1.bit.SEQ_OVRD = 1;
AdcRegs.ADCCHSELSEQ1.all = 0x0001; // Initialize all ADC channel selects to A0
AdcRegs.ADCCHSELSEQ2.all = 0x0;
AdcRegs.ADCCHSELSEQ3.all = 0x0;
AdcRegs.ADCCHSELSEQ4.all = 0x0;
AdcRegs.ADCMAXCONV.bit.MAX_CONV1 = 0x1;
AdcRegs.ADCTRL2.all = 0x2000;
for(i=0; i<BUF_SIZE; i++)
{
SampleTable[i] = 0;
}
// Initialize counters:
ECap1IntCount = 0;
ECap1PassCount = 0;
// Enable CPU INT4 which is connected to ECAP1-4 INT:
IER |= M_INT4;
// Enable eCAP INTn in the PIE: Group 3 interrupt 1-6
PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
// Enable global Interrupts and higher priority real-time debug events:
EINT; // Enable Global interrupt INTM
ERTM; // Enable Global realtime interrupt DBGM
// Step 6. IDLE loop. Just sit and loop forever (optional):
for(;;)
{
while(j<BUF_SIZE){
j = BUF_SIZE-1;
DataTable[j] = (SampleTable[0]);
j--;
}
}
}
void InitECapture()
{
ECap1Regs.ECEINT.all = 0x0000; // Disable all capture interrupts
ECap1Regs.ECCLR.all = 0xFFFF; // Clear all CAP interrupt flags
ECap1Regs.ECCTL1.bit.CAPLDEN = 0; // Disable CAP1-CAP4 register loads
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0; // Make sure the counter is stopped
// Configure peripheral registers
ECap1Regs.ECCTL2.bit.CONT_ONESHT = 0; // Continuous
ECap1Regs.ECCTL2.bit.STOP_WRAP = 3; // Stop at 4 events
ECap1Regs.ECCTL1.bit.CAP1POL = 1; // Falling edge
ECap1Regs.ECCTL1.bit.CAP2POL = 0; // Rising edge
ECap1Regs.ECCTL1.bit.CAP3POL = 1; // Falling edge
ECap1Regs.ECCTL1.bit.CAP4POL = 0; // Rising edge
ECap1Regs.ECCTL1.bit.CTRRST1 = 0; // stm operation
ECap1Regs.ECCTL1.bit.CTRRST2 = 0; // stm operation
ECap1Regs.ECCTL1.bit.CTRRST3 = 0; // stm operation
ECap1Regs.ECCTL1.bit.CTRRST4 = 0; // stm operation
ECap1Regs.ECCTL2.bit.SYNCI_EN = 1; // Enable sync in
ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0; // Pass through
ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable capture units
ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1; // Start Counter
ECap1Regs.ECCTL2.bit.REARM = 0; // arm one-shot
ECap1Regs.ECCTL1.bit.CAPLDEN = 1; // Enable CAP1-CAP4 register loads
ECap1Regs.ECEINT.bit.CEVT4 = 1; // 4 events = interrupt
}
__interrupt void ecap1_isr(void)
{
volatile Uint16 array_index;
volatile Uint16 i;
//Variable to monitor whether the rotation signal is triggering interrupt.
ECap1IntCount++;
ECap1PassCount++;
array_index = 0;
// Wait for int1
AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;
GpioDataRegs.GPBSET.bit.GPIO34 = 1;
AdcRegs.ADCTRL2.bit.SOC_SEQ1 = 1;
#if INLINE_SHIFT
SampleTable[array_index++]= ( (AdcRegs.ADCRESULT0)>>4);
#endif
#if NO_SHIFT || POST_SHIFT
SampleTable[array_index++] = ( (AdcRegs.ADCRESULT0));
#endif //-- NO_SHIFT || POST_SHIFT
#if POST_SHIFT
//For post shifting, shift the ADC results
//in the SampleTable buffer after the buffer is full.
for (i=0; i<BUF_SIZE; i++)
{
SampleTable[i] = ((SampleTable[i]) >>4);
}
#endif // -- POST_SHIFT
GpioDataRegs.GPBCLEAR.bit.GPIO34 = 0; // Clear GPIO34 for monitoring -optional
// AdcRegs.ADCTRL2.bit.RST_SEQ1 = 1;
ECap1Regs.ECCLR.bit.CEVT4 = 1;
ECap1Regs.ECCLR.bit.INT = 1;
ECap1Regs.ECCTL2.bit.REARM = 0;
// Acknowledge this interrupt to receive more interrupts from group 4
PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
}
void Fail()
{
__asm(" ESTOP0");
}
//===========================================================================
// No more.
//===========================================================================
This variable 'array_index' should add one, but it maintains 0, why?