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.

Program for a Counter

Other Parts Discussed in Thread: CONTROLSUITE, TMS320F28335

Can i write a simple program for a counter which can count pulses. Please give me a program for reference.

Thank you

  • Hi Arun,

    Which controller are you using?

    Regards,

    Gautam

  • BTW you can use external interrupts and eCAP module for this purpose. For reference examples you can check controlSuite and respective user guides.

    Regards,

    Gautam

  • Sir, 

    I am using TMS320F28335. 

    For both the it is not counting the pulses properly. Please give me the program for counting the pulses properly.

    Thank You

  • Arun, you can modify this project: "ecap_capture_pwm" (found in controlSuite) according to your requirement.

    Here's the code:

    //###########################################################################
    //
    // FILE:    Example_2833xECap_Capture_Pwm.c
    //
    // TITLE:   Capture EPWM3.
    //
    // ASSUMPTIONS:
    //
    //    This program requires the DSP2833x header files.  
    //
    //    Make the following external connection:
    //    EPWM3 on GPIO4 should be connected to ECAP1 on GPIO24.
    //
    //    As supplied, this project is configured for "boot to SARAM" 
    //    operation.  The 2833x Boot Mode table is shown below.  
    //    For information on configuring the boot mode of an eZdsp, 
    //    please refer to the documentation included with the eZdsp,  
    //
    //       $Boot_Table:
    //
    //         GPIO87   GPIO86     GPIO85   GPIO84
    //          XA15     XA14       XA13     XA12
    //           PU       PU         PU       PU
    //        ==========================================
    //            1        1          1        1    Jump to Flash
    //            1        1          1        0    SCI-A boot
    //            1        1          0        1    SPI-A boot
    //            1        1          0        0    I2C-A boot
    //            1        0          1        1    eCAN-A boot
    //            1        0          1        0    McBSP-A boot
    //            1        0          0        1    Jump to XINTF x16
    //            1        0          0        0    Jump to XINTF x32
    //            0        1          1        1    Jump to OTP
    //            0        1          1        0    Parallel GPIO I/O boot
    //            0        1          0        1    Parallel XINTF boot
    //            0        1          0        0    Jump to SARAM	    <- "boot to SARAM"
    //            0        0          1        1    Branch to check boot mode
    //            0        0          1        0    Boot to flash, bypass ADC cal
    //            0        0          0        1    Boot to SARAM, bypass ADC cal
    //            0        0          0        0    Boot to SCI-A, bypass ADC cal
    //                                              Boot_Table_End$
    //
    // DESCRIPTION:
    //
    //    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 PWM3A output.
    //
    //###########################################################################
    // $TI Release: 2833x/2823x Header Files and Peripheral Examples V133 $
    // $Release Date: June 8, 2012 $
    //###########################################################################
    
    
    
    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    
    // Configure the start/end period for the timer
    #define PWM3_TIMER_MIN     10                    
    #define PWM3_TIMER_MAX     8000
    
    // Prototype statements for functions found within this file.
    interrupt void ecap1_isr(void);
    void InitECapture(void);
    void InitEPwmTimer(void);
    void Fail(void);
    
    // Global variables used in this example
    Uint32  ECap1IntCount;
    Uint32  ECap1PassCount;
    Uint32  EPwm3TimerDirection;
    
    // To keep track of which way the timer value is moving
    #define EPWM_TIMER_UP   1
    #define EPWM_TIMER_DOWN 0
    
    void main(void)
    {
    
    // Step 1. Initialize System Control:
    // PLL, WatchDog, enable Peripheral Clocks
    // This example function is found in the DSP2833x_SysCtrl.c file.
       InitSysCtrl();
    
    // Step 2. Initalize GPIO: 
    // This example function is found in the DSP2833x_Gpio.c file and
    // illustrates how to set the GPIO to it's default state.
    // InitGpio();  // Skipped for this example  
       
       InitEPwm3Gpio();
       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();
    
    // 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
       InitEPwmTimer();    // For this example, only initialize the ePWM Timers
       InitECapture();
    
    
    // Step 5. User specific code, enable interrupts:
    
    // Initalize 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(;;)
       {
           asm("          NOP");
       }
    
    } 
    
    
    void InitEPwmTimer()
    {
    
       EALLOW;
       SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;
       EDIS;
    
       EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
       EPwm3Regs.TBPRD = PWM3_TIMER_MIN;
       EPwm3Regs.TBPHS.all = 0x00000000;
       EPwm3Regs.AQCTLA.bit.PRD = AQ_TOGGLE;      // Toggle on PRD
       
       // TBCLK = SYSCLKOUT
       EPwm3Regs.TBCTL.bit.HSPCLKDIV = 1;
       EPwm3Regs.TBCTL.bit.CLKDIV = 0;
    
    
       EPwm3TimerDirection = EPWM_TIMER_UP; 
       
       EALLOW;
       SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
       EDIS;
    
    }
    
    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 = 1;      // One-shot
       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 = 1;          // Difference operation         
       ECap1Regs.ECCTL1.bit.CTRRST2 = 1;          // Difference operation         
       ECap1Regs.ECCTL1.bit.CTRRST3 = 1;          // Difference operation         
       ECap1Regs.ECCTL1.bit.CTRRST4 = 1;          // Difference 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 = 1;            // 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)
    {
    
       // Cap input is syc'ed to SYSCLKOUT so there may be
       // a +/- 1 cycle variation
        
       if(ECap1Regs.CAP2 > EPwm3Regs.TBPRD*2+1 || ECap1Regs.CAP2 < EPwm3Regs.TBPRD*2-1) 
       {
           Fail();
       }
    
       if(ECap1Regs.CAP3 > EPwm3Regs.TBPRD*2+1 || ECap1Regs.CAP3 < EPwm3Regs.TBPRD*2-1) 
       {
           Fail();
       }
       
       if(ECap1Regs.CAP4 > EPwm3Regs.TBPRD*2+1 || ECap1Regs.CAP4 < EPwm3Regs.TBPRD*2-1) 
       {
           Fail();
       }   
    
    
       ECap1IntCount++;
    
       if(EPwm3TimerDirection == EPWM_TIMER_UP)
       {
            if(EPwm3Regs.TBPRD < PWM3_TIMER_MAX) 
            {
               EPwm3Regs.TBPRD++;
            }
            else
            {
               EPwm3TimerDirection = EPWM_TIMER_DOWN;
               EPwm3Regs.TBPRD--;
            }
       }
       else
       {
            if(EPwm3Regs.TBPRD > PWM3_TIMER_MIN) 
            {
               EPwm3Regs.TBPRD--;
            }
            else
            {
               EPwm3TimerDirection = EPWM_TIMER_UP;
               EPwm3Regs.TBPRD++;
            }
       }   
    
       ECap1PassCount++;
    
       ECap1Regs.ECCLR.bit.CEVT4 = 1;
       ECap1Regs.ECCLR.bit.INT = 1;
       ECap1Regs.ECCTL2.bit.REARM = 1;
    
       // Acknowledge this interrupt to receive more interrupts from group 4
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
    }
    
    
    void Fail()
    {
        asm("   ESTOP0");
    }
    
    
    
    
    
    //===========================================================================
    // No more.
    //===========================================================================
    

    Regards,

    Gautam