Because of the holidays, TI E2E™ design support forum responses will be delayed from Dec. 25 through Jan. 2. Thank you for your patience.

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.

LAUNCHXL-F28027: C2000 Launchpad, F28027, HC-SR04 Ultrasonic Sensor problem

Part Number: LAUNCHXL-F28027
Other Parts Discussed in Thread: TMS320F28027

 Hello TI Community.

I recently started to work with C2000 Launchpad which have the uC TMS320F28027, in CCS v7.2.0, compiler: TI v6.4.12.

I'm trying to get a distance from an object in front of the sensor HC SR-04.

In my code i'm configuring GPIO34 as the TRIGGER for the sensor, GPIO7 as the external interrupt pin, and timer0 which i use as a counter in free run mode.

In my interrupt routine i'm trying to calculate the difference between when timer started and when timer stopped to get the distance in centimeters.

Also i'm trying to see if the distance is calculated correctly by lighting one of the four LEDs from the board, depending in which interval of values is measured distance.

For some reason, when i use the API functions to configure the timer0, the timer is running and nothing happens, that's why i changed to bits manipulation. 

Nonetheless, i keep getting odd values from the sensor. (something like 70K or 0, even if the interrupt routine is called correctly) 

I used a voltage divider from 5V ECHO pin to 3.3V GPIO7, because the sensor uses 5V.

Also i'm using the 5V pins and GND from the Launchpad board.

If someone could help me, that would be great.

Thank you for your time. 

Here is the code:


#include "DSP28x_Project.h" // Device Headerfile and Examples Include File

#include "f2802x_common/include/clk.h"
#include "f2802x_common/include/flash.h"
#include "f2802x_common/include/gpio.h"
#include "f2802x_common/include/pie.h"
#include "f2802x_common/include/pll.h"
#include "f2802x_common/include/pwr.h"
#include "f2802x_common/include/timer.h"
#include "f2802x_common/include/wdog.h"

// Prototype statements for functions found within this file.
interrupt void xint1_isr(void);


CLK_Handle myClk;
FLASH_Handle myFlash;
GPIO_Handle myGpio;
PIE_Handle myPie;
TIMER_Handle myTimer0;

// Global variables for this example
volatile uint32_t Xint1Count = 0;
volatile uint32_t distance = 0; //storing distance in cm
volatile uint32_t temp_var = 0; // storing the value from substraction
volatile int obstacol = 0;
volatile uint32_t start_val = 0; // storing start value of timer0
volatile uint32_t stop_val = 0; //storing stop value of timer0


#define DELAY (CPU_RATE/1000*6*510) //Qual period at 6 samples

#define US_LIMIT 1200000U //limit of about 24 ms for ultrasonic sensor

void main(void)
{
CPU_Handle myCpu;
PLL_Handle myPll;
PWR_Handle myPwr;
WDOG_Handle myWDog;

// Initialize all the handles needed for this application
myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj));
myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj));
myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj));
myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj));
myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj));
myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj));
myTimer0 = TIMER_init((void *)TIMER0_BASE_ADDR, sizeof(TIMER_Obj));
myPwr = PWR_init((void *)PWR_BASE_ADDR, sizeof(PWR_Obj));
myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj));

// Perform basic system initialization
WDOG_disable(myWDog);
CLK_enableAdcClock(myClk);
(*Device_cal)();

//Select the internal oscillator 1 as the clock source
CLK_setOscSrc(myClk, CLK_OscSrc_Internal);

// Setup the PLL for x10 /2 which will yield 60Mhz = 10Mhz * 10 / 2
PLL_setup(myPll, PLL_Multiplier_12, PLL_DivideSelect_ClkIn_by_2);

// Disable the PIE and all interrupts
PIE_disable(myPie);
PIE_disableAllInts(myPie);
CPU_disableGlobalInts(myCpu);
CPU_clearIntFlags(myCpu);

// If running from flash copy RAM only functions to RAM
#ifdef _FLASH
memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
#endif

// Setup a debug vector table and enable the PIE
PIE_setDebugIntVectorTable(myPie);
PIE_enable(myPie);

// Register interrupt handlers in the PIE vector table
PIE_registerPieIntHandler(myPie, PIE_GroupNumber_1, PIE_SubGroupNumber_4, (intVec_t)&xint1_isr);


// Clear the counters
Xint1Count = 0; // Count XINT1 interrupts

// Enable XINT1 and XINT2 in the PIE: Group 1 interrupt 4 & 5
// Enable INT1 which is connected to WAKEINT
PIE_enableInt(myPie, PIE_GroupNumber_1, PIE_InterruptSource_XINT_1);
CPU_enableInt(myCpu, CPU_IntNumber_1);

// Enable Global Interrupts
CPU_enableGlobalInts(myCpu);

// GPIO28 & GPIO29 are outputs, start GPIO28 high and GPIO29 low
//GPIO_setHigh(myGpio, GPIO_Number_28);
GPIO_setMode(myGpio, GPIO_Number_34, GPIO_28_Mode_GeneralPurpose);
GPIO_setDirection(myGpio, GPIO_Number_34, GPIO_Direction_Output);


// GPIO0 and GPIO1 are inputs
GPIO_setMode(myGpio, GPIO_Number_7, GPIO_0_Mode_GeneralPurpose);
GPIO_setDirection(myGpio, GPIO_Number_7, GPIO_Direction_Input);
GPIO_setQualification(myGpio, GPIO_Number_7, GPIO_Qual_Sync);

// Configure GPIO 0-3 as outputs
GPIO_setMode(myGpio, GPIO_Number_0, GPIO_0_Mode_GeneralPurpose);
GPIO_setMode(myGpio, GPIO_Number_1, GPIO_1_Mode_GeneralPurpose);
GPIO_setMode(myGpio, GPIO_Number_2, GPIO_2_Mode_GeneralPurpose);
GPIO_setMode(myGpio, GPIO_Number_3, GPIO_3_Mode_GeneralPurpose);

GPIO_setDirection(myGpio, GPIO_Number_0, GPIO_Direction_Output);
GPIO_setDirection(myGpio, GPIO_Number_1, GPIO_Direction_Output);
GPIO_setDirection(myGpio, GPIO_Number_2, GPIO_Direction_Output);
GPIO_setDirection(myGpio, GPIO_Number_3, GPIO_Direction_Output);

GPIO_setHigh(myGpio, GPIO_Number_0);
GPIO_setHigh(myGpio, GPIO_Number_1);
GPIO_setHigh(myGpio, GPIO_Number_2);
GPIO_setHigh(myGpio, GPIO_Number_3);


// GPIO0 is XINT1, GPIO1 is XINT2
GPIO_setExtInt(myGpio, GPIO_Number_7, CPU_ExtIntNumber_1);


// Configure XINT1
PIE_setExtIntPolarity(myPie, CPU_ExtIntNumber_1, PIE_ExtIntPolarity_FallingEdge);


// Enable XINT1 and XINT2
PIE_enableExtInt(myPie, CPU_ExtIntNumber_1);

// TIMER_stop(myTimer0);
//// Configure CPU-Timer 0, 1, and 2 to interrupt every second:
//// 50MHz CPU Freq, 1 second Period (in uSeconds)
//
// //ConfigCpuTimer(&CpuTimer0, 50, 1000000);
// TIMER_setPeriod(myTimer0, 0xFFFFFFFF);
// TIMER_setPreScaler(myTimer0, 1);
// TIMER_reload(myTimer0);
// TIMER_setEmulationMode(myTimer0, TIMER_EmulationMode_RunFree);
// TIMER_disableInt(myTimer0);

CpuTimer0Regs.TCR.bit.TSS = 1; // 1 = Stop timer, 0 = Start/Restart Timer

CpuTimer0Regs.PRD.all = 0xFFFFFFFF; // Initialize timer period to maximum

CpuTimer0Regs.TPR.all = 0x01;

CpuTimer0Regs.TCR.bit.TRB = 1; // 1 = reload timer now

CpuTimer0Regs.TCR.bit.FREE = 1;
CpuTimer0Regs.TCR.bit.SOFT = 0;


CpuTimer0Regs.TCR.bit.TIE = 0; // 0 = Disable/ 1 = Enable Timer Interrupt

//CpuTimer0Regs.TCR.all = 0; // TSS = 0 = Start/Restart Timer


for(;;) {

GPIO_setHigh(myGpio, GPIO_Number_34); //trigg
DELAY_US(10);
GPIO_setLow(myGpio, GPIO_Number_34);
//TIMER_start(myTimer0);
CpuTimer0Regs.TCR.bit.TRB = 1;

start_val = CpuTimer0Regs.TIM.all;
CpuTimer0Regs.TCR.bit.TSS = 0;
distance = 500;
DELAY_US(60000); // the time in which sensor has to give an echo back 

if(distance < 50)
{
GPIO_setLow(myGpio, GPIO_Number_0);
GPIO_setHigh(myGpio, GPIO_Number_1);
GPIO_setHigh(myGpio, GPIO_Number_2);
GPIO_setHigh(myGpio, GPIO_Number_3);
}
else if(distance < 100)
{
GPIO_setHigh(myGpio, GPIO_Number_0);
GPIO_setLow(myGpio, GPIO_Number_1);
GPIO_setHigh(myGpio, GPIO_Number_2);
GPIO_setHigh(myGpio, GPIO_Number_3);
}
else if(distance < 150 )
{
GPIO_setHigh(myGpio, GPIO_Number_0);
GPIO_setHigh(myGpio, GPIO_Number_1);
GPIO_setLow(myGpio, GPIO_Number_2);
GPIO_setHigh(myGpio, GPIO_Number_3);
}
else if(distance < 200)
{
GPIO_setHigh(myGpio, GPIO_Number_0);
GPIO_setHigh(myGpio, GPIO_Number_1);
GPIO_setHigh(myGpio, GPIO_Number_2);
GPIO_setLow(myGpio, GPIO_Number_3);
}
else
{
GPIO_setHigh(myGpio, GPIO_Number_0);
GPIO_setHigh(myGpio, GPIO_Number_1);
GPIO_setHigh(myGpio, GPIO_Number_2);
GPIO_setHigh(myGpio, GPIO_Number_3);
}
}
}


interrupt void xint1_isr(void)
{

//temp_var = TIMER_getCount(myTimer0);

stop_val = CpuTimer0Regs.TIM.all;

CpuTimer0Regs.TCR.bit.TSS = 1;
//TIMER_stop(myTimer0);


temp_var = start_val - stop_val;

distance = (temp_var / 5882 ); // (17 * 0.000001) //Converts Time to Distance

//TIMER_reload(myTimer0);
//CpuTimer0Regs.TCR.bit.TRB = 1;


// while(PIE_getIntFlags(myPie, PIE_GroupNumber_1) != 1); //Waiting for Echo
// TIMER_start(myTimer0);
// //Timer Starts
// while(PIE_getIntFlags(myPie, PIE_GroupNumber_1) == 1); //Waiting for Echo goes LOW
// //TIMER_stop(myTimer0); //Timer Stops

Xint1Count++;

// Acknowledge this interrupt to get more from group 1
PIE_clearInt(myPie, PIE_GroupNumber_1);
}

//===========================================================================
// No more.
//===========================================================================

 

  • So you've confirmed that you're getting into the ISR, correct? Have you looked at the sensor output on an oscilloscope to make sure it is as expected?

    Are you essentially trying to measure a pulse from the sensor? Have you considered using the ECAP instead of a timer+XINT?

    Whitney
  • Hello there, Whitney.
    Yes, i'm using the Xint1Count variable to see if it goes into ISR, i'm watching it in the watch window, debug mode.
    I want to mention that i tested the sensor with an Arduino code, on an Arduino board, and it worked well.
    Yes, i looked at the sensor ECHO pin on an oscilloscope, after i ran the code from CCS with launchpad.
    The thing is first time it seemed like it works well, the width of the ECHO pulse looked well, except from a strange little edge on the start of the pulse. I've come to conclusion that this edge of small width was from the fact that i didn't have a delay after the TRIGGER pulse.
    After i added the delay, the ECHO signal looked kinda proportionally with the distance, but after some time it gave a strange long pulse.
    I'm sorry for not taking some photos.

    Well, i'm not essentially trying just to measure a pulse from that sensor.
    My project is a bit bigger.
    I need to design and project a car that goes from point A to point B, using 2 ultrasonic sensors and a GPS module. Also i'm planing to control 2 motors with PWM, also on this board.
    First of all i need to solve this sensor issue, and after that to create another algorithm for this.
    I'm not sure if i can use eCAP to capture that pulse.
    I considered this variant, also checked the eCAP examples, but they are a bit vague for me, plus to that i'm kinda noobish (sorry for this slang word) in this field of programming microcontrollers with C, even if i'm a 4th year student, i had a small amout of experiences with microcontrollers and i did very simple stuff.

    I also suspect that i get these problems because of my breadboard or the sensor broke.
    I want to solder the voltage divider properly, to change the sensor and try again, even thought i think i did something wrong in my way to think that code.


    Thank you for your response.
  • I thought the eCAP might be helpful since it's intended to measure time between edges and generate an interrupt after it detects a certain number and pattern of edges. There's an eCAP reference guide here if you want to investigate it: www.ti.com/lit/ug/sprufz8a/sprufz8a.pdf

    Right now it looks like you're not detecting the the rising edge, correct? You're just starting the timer after your trigger pulse and then interrupting on the falling edge of the echo? How much time passes between the end of your trigger pulse and the start of your echo pulse? Is it negligible? Is it predictable and you're calculating it out?

    Whitney
  • Hey there.
    I'll look into the eCAP guide, thank you.

    Yes, i'm not detecting the rising edge, just the falling. I'm assuming, after the trigger and starting the timer, that the rising happens. After that, the falling edge of the ECHO activates the ISR.
    I think about some sort of hundreds of micro-seconds pass between the end of trigger and the start of the echo pulse. That's what i saw on the oscilloscope.
    For this test, it is negligible. I've considered to think about it in the future.
    I'm not sure about how to calculate that time, i'm assuming that the time that passes is equal to time of 8 pulses of 40KHz to pass, plus some sort of delay, because of the distance.
  • Hello again.
    I changed some things in my code for testing, just a little bit.
    Also i've soldered the voltage divider, changed the ultrasonic sensor, and i got my code to work.

    Except i don't really know how to calculate correctly the distance.
    My device is running at 60MHz and i have to do some calculation with what i get from the timer.

    Initially what I had to do was to get the time in microseconds and divide it by 58.82 to get the distance in centimeters.
    But i'm not sure i'm doing it right.
    I assume that my timer counts the cpu periods. One period is equal to 1 divided by 60MHz. Right?
    Well, from all of this i think it's right to say that the distance is equal to number of periods multiplied by time of one period and divided by 58.82. Right?

    When i go in the debug mode, i get my distance like this: 8.87583883e-05 

    Could someone pinpoint me to where i'm doing the mistakes? :D

    Thank you for your time and patience.

    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    #include "f2802x_common/include/clk.h"
    #include "f2802x_common/include/flash.h"
    #include "f2802x_common/include/gpio.h"
    #include "f2802x_common/include/pie.h"
    #include "f2802x_common/include/pll.h"
    #include "f2802x_common/include/pwr.h"
    #include "f2802x_common/include/timer.h"
    #include "f2802x_common/include/wdog.h"
    
    // Prototype statements for functions found within this file.
    interrupt void xint1_isr(void);
    
    
    CLK_Handle myClk;
    FLASH_Handle myFlash;
    GPIO_Handle myGpio;
    PIE_Handle myPie;
    TIMER_Handle myTimer0;
    
    
    #define FALSE 0
    #define TRUE 1
    
    // Global variables for this example
    volatile uint32_t Xint1Count = 0;
    volatile float distance = 0;  //storing distance in cm
    volatile uint32_t temp_var = 0;  // storing the value from substraction
    volatile bool obstacol = FALSE;
    volatile uint32_t start_val = 0;  // storing start value of timer0
    volatile uint32_t stop_val = 0; //storing stop value of timer0
    
    
    #define DELAY (CPU_RATE/1000*6*510)  //Qual period at 6 samples
    
    #define US_LIMIT 1200000U  //limit of  about 24 ms for ultrasonic sensor
    #define cpu_period (0.017 * 0.000001)
    void main(void)
    {
        CPU_Handle myCpu;
        PLL_Handle myPll;
        PWR_Handle myPwr;
        WDOG_Handle myWDog;
        
    
    
    
        // Initialize all the handles needed for this application 
        myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj)); 
        myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj));
        myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj));
        myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj));
        myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj));
        myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj));
        myTimer0 = TIMER_init((void *)TIMER0_BASE_ADDR, sizeof(TIMER_Obj));
        myPwr = PWR_init((void *)PWR_BASE_ADDR, sizeof(PWR_Obj));
        myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj));
    
        // Perform basic system initialization    
        WDOG_disable(myWDog);
        CLK_enableAdcClock(myClk);
        (*Device_cal)();
        
        //Select the internal oscillator 1 as the clock source
        CLK_setOscSrc(myClk, CLK_OscSrc_Internal);
        
        // Setup the PLL for x10 /2 which will yield 60Mhz = 10Mhz * 10 / 2
        PLL_setup(myPll, PLL_Multiplier_12, PLL_DivideSelect_ClkIn_by_2);
        
        // Disable the PIE and all interrupts
        PIE_disable(myPie);
        PIE_disableAllInts(myPie);
        CPU_disableGlobalInts(myCpu);
        CPU_clearIntFlags(myCpu);
        
        // If running from flash copy RAM only functions to RAM   
    #ifdef _FLASH
        memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
    #endif 
    
        // Setup a debug vector table and enable the PIE
        PIE_setDebugIntVectorTable(myPie);
        PIE_enable(myPie);
    
        // Register interrupt handlers in the PIE vector table
        PIE_registerPieIntHandler(myPie, PIE_GroupNumber_1, PIE_SubGroupNumber_4, (intVec_t)&xint1_isr);
    
    
        // Clear the counters
        Xint1Count = 0; // Count XINT1 interrupts
    
    
    
        // Enable XINT1 and XINT2 in the PIE: Group 1 interrupt 4 & 5
        // Enable INT1 which is connected to WAKEINT
        PIE_enableInt(myPie, PIE_GroupNumber_1, PIE_InterruptSource_XINT_1);
        CPU_enableInt(myCpu, CPU_IntNumber_1);
        
        // Enable Global Interrupts
        CPU_enableGlobalInts(myCpu);
    
        // GPIO28 & GPIO29 are outputs, start GPIO28 high and GPIO29 low
        //GPIO_setHigh(myGpio, GPIO_Number_28);
        GPIO_setMode(myGpio, GPIO_Number_34, GPIO_34_Mode_GeneralPurpose);
        GPIO_setDirection(myGpio, GPIO_Number_34, GPIO_Direction_Output);
        
    
    
        // GPIO0 and GPIO1 are inputs
        GPIO_setMode(myGpio, GPIO_Number_7, GPIO_7_Mode_GeneralPurpose);
        GPIO_setDirection(myGpio, GPIO_Number_7, GPIO_Direction_Input);
        //GPIO_setQualification(myGpio, GPIO_Number_7, GPIO_Qual_Sync);
        
    
        // Configure GPIO 0-3 as outputs
            GPIO_setMode(myGpio, GPIO_Number_0, GPIO_0_Mode_GeneralPurpose);
            GPIO_setMode(myGpio, GPIO_Number_1, GPIO_1_Mode_GeneralPurpose);
            GPIO_setMode(myGpio, GPIO_Number_2, GPIO_2_Mode_GeneralPurpose);
            GPIO_setMode(myGpio, GPIO_Number_3, GPIO_3_Mode_GeneralPurpose);
    
            GPIO_setDirection(myGpio, GPIO_Number_0, GPIO_Direction_Output);
            GPIO_setDirection(myGpio, GPIO_Number_1, GPIO_Direction_Output);
            GPIO_setDirection(myGpio, GPIO_Number_2, GPIO_Direction_Output);
            GPIO_setDirection(myGpio, GPIO_Number_3, GPIO_Direction_Output);
    
            GPIO_setHigh(myGpio, GPIO_Number_0);
            GPIO_setHigh(myGpio, GPIO_Number_1);
            GPIO_setHigh(myGpio, GPIO_Number_2);
            GPIO_setHigh(myGpio, GPIO_Number_3);
    
    
    
    
        // GPIO0 is XINT1, GPIO1 is XINT2
        GPIO_setExtInt(myGpio, GPIO_Number_7, CPU_ExtIntNumber_1);
    
    
        // Configure XINT1
        PIE_setExtIntPolarity(myPie, CPU_ExtIntNumber_1, PIE_ExtIntPolarity_FallingEdge);
    
    
        // Enable XINT1 and XINT2
        PIE_enableExtInt(myPie, CPU_ExtIntNumber_1);
    
    //        TIMER_stop(myTimer0);
    ////     Configure CPU-Timer 0, 1, and 2 to interrupt every second:
    ////     50MHz CPU Freq, 1 second Period (in uSeconds)
    //
    //        //ConfigCpuTimer(&CpuTimer0, 50, 1000000);
    //        TIMER_setPeriod(myTimer0, 0xFFFFFFFF);
    //        TIMER_setPreScaler(myTimer0, 1);
    //        TIMER_reload(myTimer0);
    //        TIMER_setEmulationMode(myTimer0, TIMER_EmulationMode_RunFree);
    //        TIMER_disableInt(myTimer0);
    
            CpuTimer0Regs.TCR.bit.TSS = 1;         // 1 = Stop timer, 0 = Start/Restart Timer
    
            CpuTimer0Regs.PRD.all =  0xFFFFFFFF;  // Initialize timer period to maximum
    
            CpuTimer0Regs.TPR.all = 0x01;
    
            CpuTimer0Regs.TCR.bit.TRB = 1;         // 1 = reload timer now
    
            CpuTimer0Regs.TCR.bit.FREE = 1;
            CpuTimer0Regs.TCR.bit.SOFT = 0;
    
    
            CpuTimer0Regs.TCR.bit.TIE = 0;         // 0 = Disable/ 1 = Enable Timer Interrupt
    
            //CpuTimer0Regs.TCR.all = 0;             // TSS = 0 = Start/Restart Timer
    
    
        for(;;) {
    
            GPIO_setHigh(myGpio, GPIO_Number_34); //triggering the pulses from sensor
            DELAY_US(10);
            GPIO_setLow(myGpio, GPIO_Number_34);
            //TIMER_start(myTimer0);
            //CpuTimer0Regs.TCR.bit.TRB = 1;
    
            start_val = CpuTimer0Regs.TIM.all;
            CpuTimer0Regs.TCR.bit.TSS = 0;
    
            //distance = 500;
            
            DELAY_US(30000); //waiting for echo
    
            if(distance < 50)
            {
                GPIO_setLow(myGpio, GPIO_Number_0);
                GPIO_setHigh(myGpio, GPIO_Number_1);
                GPIO_setHigh(myGpio, GPIO_Number_2);
                GPIO_setHigh(myGpio, GPIO_Number_3);
            }
            else if(distance < 100)
            {
                GPIO_setHigh(myGpio, GPIO_Number_0);
                GPIO_setLow(myGpio, GPIO_Number_1);
                GPIO_setHigh(myGpio, GPIO_Number_2);
                GPIO_setHigh(myGpio, GPIO_Number_3);
            }
            else if(distance < 150 )
            {
                GPIO_setHigh(myGpio, GPIO_Number_0);
                GPIO_setHigh(myGpio, GPIO_Number_1);
                GPIO_setLow(myGpio, GPIO_Number_2);
                GPIO_setHigh(myGpio, GPIO_Number_3);
            }
            else if(distance < 200)
            {
                GPIO_setHigh(myGpio, GPIO_Number_0);
                GPIO_setHigh(myGpio, GPIO_Number_1);
                GPIO_setHigh(myGpio, GPIO_Number_2);
                GPIO_setLow(myGpio, GPIO_Number_3);
            }
            else
            {
                GPIO_setHigh(myGpio, GPIO_Number_0);
                GPIO_setHigh(myGpio, GPIO_Number_1);
                GPIO_setHigh(myGpio, GPIO_Number_2);
                GPIO_setHigh(myGpio, GPIO_Number_3);
            }
        }
    }
    
    
    interrupt void xint1_isr(void)
    {
        //salveaza registru
    
        //temp_var = TIMER_getCount(myTimer0);
    
        stop_val = CpuTimer0Regs.TIM.all;
    
        CpuTimer0Regs.TCR.bit.TSS = 1;
        //TIMER_stop(myTimer0);
    
       // difference between start and stop value
          temp_var = start_val - stop_val;
    
          distance = ((temp_var * cpu_period) / 58.82 ); //  (17 * 0.000001)            //Converts Time to Distance
    
        //TIMER_reload(myTimer0);
        CpuTimer0Regs.TCR.bit.TRB = 1;
    
    
    //          while(PIE_getIntFlags(myPie, PIE_GroupNumber_1) != 1);              //Waiting for Echo
    //          TIMER_start(myTimer0);
    //          //Timer Starts
    //          while(PIE_getIntFlags(myPie, PIE_GroupNumber_1) == 1);               //Waiting for Echo goes LOW
    //          //TIMER_stop(myTimer0);               //Timer Stops
        
        Xint1Count++;
    
        // Acknowledge this interrupt to get more from group 1
        PIE_clearInt(myPie, PIE_GroupNumber_1);
    }
    
    //===========================================================================
    // No more.
    //===========================================================================
    

  • Have you made any progress on this? Should "cpu_period" be 0.017? If you put a breakpoint in your ISR and get the value of "temp_var" from the debugger and do the calculation yourself, do you get the same value that ends up in "distance"?

    Whitney
  • Hello there.

    You're right. The cpu_period should be 0.017 because i need the time to be in microseconds. In my version, it was in seconds. That was one of  my mistakes.

    Also, i don't think it's related but i commented the line "GPIO_setQualification(myGpio, GPIO_Number_7, GPIO_Qual_Sync);". I don't quite get what qualification of the GPIO does.

    And, in my for loop i changed the way i do things:


    GPIO_setHigh(myGpio, GPIO_Number_34); //triggering the pulses from sensor
    DELAY_US(10);
    GPIO_setLow(myGpio, GPIO_Number_34);
    DELAY_US(120); //delay between the trigger and echo
    CpuTimer0Regs.TCR.bit.TSS = 0; //start the timer
    start_val = CpuTimer0Regs.TIM.all; //store the value of timer
    DELAY_US(30000); //waiting for echo

    And the results are in centimeters, except there is an error somewhere between 3-5 centimeters.

    Also, i started to look into the eCAP module documentation.

    From what i've read i need to configure the eCAP in the following way:
    Knowing that the eCAP have 4 registers in which it stores the time of the occuring event, i've decided to use just 2 of the registers: CAP1 and CAP2.

    void InitECapture()
    {
    CLK_enableEcap1Clock(myClk);

    CAP_disableInt(myCap, CAP_Int_Type_All); // Disable all capture interrupts
    CAP_clearInt(myCap, CAP_Int_Type_All); // Clear all CAP interrupt flags
    CAP_disableCaptureLoad(myCap); // Disable CAP1-CAP4 register loads
    CAP_disableTimestampCounter(myCap); // Make sure the counter is stopped


    CAP_setCapContinuous(myCap);
    CAP_setStopWrap(myCap, CAP_Stop_Wrap_CEVT2);// Stop at 2 events
    CAP_setCapEvtPolarity(myCap, CAP_Event_1, CAP_Polarity_Rising); // Falling edge
    CAP_setCapEvtPolarity(myCap, CAP_Event_2, CAP_Polarity_Falling); // Rising edge

    CAP_setCapEvtReset(myCap, CAP_Event_1, CAP_Reset_Enable); // Difference operation
    CAP_setCapEvtReset(myCap, CAP_Event_2, CAP_Reset_Enable); // Difference operation

    CAP_enableSyncIn(myCap); // Enable sync in
    CAP_setSyncOut(myCap, CAP_SyncOut_SyncIn); // Pass through


    CAP_enableCaptureLoad(myCap);

    CAP_enableTimestampCounter(myCap); // Start Counter
    CAP_rearm(myCap); // arm one-shot
    CAP_enableCaptureLoad(myCap); // Enable CAP1-CAP4 register loads
    CAP_enableInt(myCap, CAP_Int_Type_CEVT2); // 2 events = interrupt CEVT2
    }

    __interrupt void ecap1_isr(void)
    {

    cap1 = CAP_getCap1(myCap);

    cap2 = CAP_getCap2(myCap);

    temp_var = cap2 - cap1;
    distance = ((temp_var * cpu_period) / 58.82) * 2;
    ECap1IntCount++;

    CAP_clearInt(myCap, CAP_Int_Type_CEVT2);
    CAP_clearInt(myCap, CAP_Int_Type_Global);
    CAP_rearm(myCap);

    // Acknowledge this interrupt to receive more interrupts from group 4
    PIE_clearInt(myPie, PIE_GroupNumber_4);
    }

    I looked into one of the examples with the eCAP and i modified it.

    At this point, i don't know if it'll work out or if i managed to think correctly the way i'm using the eCAP module.

    Thank you for your response. 

  • Hello,

    How's your project going? Did you get a chance to try out the eCAP or did you decide to stick with the CPU timer?

    Whitney
  • Hello,

    Somehow yes.

    From what I've read about eCAP module, I need to configure in in the continuous mode to capture the pulses from the sensor.

    I decided to use just two registers of the eCAP module, CAP1 and CAP2; CAP1 = when the rising edge occurred, and the CAP2 = when the falling edge occurred.
    Also I've set that when the event of falling edge is captured, it'll reset the CAP2 register. That's because i'm ussing only the CAP2 value to calculate the distance.

    Also, I configurated it in the way of getting an interrupt from the falling edge.

    Except, I didn't do configuration properly. This is coming from the fact that i get very imprecise distance calculations.

    And I'm not sure again if this is the problem or problems, cause i don't really understand the eCAP explanations or if I'm using the right algorithm.

    Here is my code for this experiment: 

    #include "DSP28x_Project.h"     // Device Headerfile and Examples Include File
    
    #include "f2802x_common/include/clk.h"
    #include "f2802x_common/include/flash.h"
    #include "f2802x_common/include/gpio.h"
    #include "f2802x_common/include/pie.h"
    #include "f2802x_common/include/pll.h"
    #include "f2802x_common/include/pwr.h"
    #include "f2802x_common/include/pwm.h"
    #include "f2802x_common/include/cap.h"
    #include "f2802x_common/include/wdog.h"
    
    // 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_t  ECap1IntCount;
    uint32_t  ECap1PassCount;
    uint32_t  EPwm3TimerDirection;
    volatile uint32_t cap1 = 0;
    volatile uint32_t cap2 = 0;
    volatile uint32_t cap3 = 0;
    volatile uint32_t cap4 = 0;
    volatile uint32_t distance = 0;  //storing distance in cm
    volatile uint32_t temp_val = 0;
    volatile uint32_t counter_ecap = 0;
    volatile uint32_t interupt_counter_ecap = 0;
    
    // To keep track of which way the timer value is moving
    #define EPwm_TIMER_UP   1
    #define EPwm_TIMER_DOWN 0
    
    #define cpu_period 0.017
    
    CAP_Handle myCap;
    CLK_Handle myClk;
    FLASH_Handle myFlash;
    GPIO_Handle myGpio;
    PIE_Handle myPie;
    PWM_Handle myPwm;
    
    void main(void)
    {
        CPU_Handle myCpu;
        PLL_Handle myPll;
        PWR_Handle myPwr;
        WDOG_Handle myWDog;
    
        // Initialize all the handles needed for this application
        myCap = CAP_init((void *)CAPA_BASE_ADDR, sizeof(CAP_Obj));
        myClk = CLK_init((void *)CLK_BASE_ADDR, sizeof(CLK_Obj));
        myCpu = CPU_init((void *)NULL, sizeof(CPU_Obj));
        myFlash = FLASH_init((void *)FLASH_BASE_ADDR, sizeof(FLASH_Obj));
        myGpio = GPIO_init((void *)GPIO_BASE_ADDR, sizeof(GPIO_Obj));
        myPie = PIE_init((void *)PIE_BASE_ADDR, sizeof(PIE_Obj));
        myPll = PLL_init((void *)PLL_BASE_ADDR, sizeof(PLL_Obj));
        myPwr = PWR_init((void *)PWR_BASE_ADDR, sizeof(PWR_Obj));
        myPwm = PWM_init((void *)PWM_ePWM3_BASE_ADDR, sizeof(PWM_Obj));
        myWDog = WDOG_init((void *)WDOG_BASE_ADDR, sizeof(WDOG_Obj));
    
        // Perform basic system initialization
        WDOG_disable(myWDog);
        CLK_enableAdcClock(myClk);
        (*Device_cal)();
        CLK_disableAdcClock(myClk);
    
        //Select the internal oscillator 1 as the clock source
        CLK_setOscSrc(myClk, CLK_OscSrc_Internal);
    
        // Setup the PLL for x12 /2 which will yield 60Mhz = 10Mhz * 12 / 2
        PLL_setup(myPll, PLL_Multiplier_12, PLL_DivideSelect_ClkIn_by_2);
    
        // Disable the PIE and all interrupts
        PIE_disable(myPie);
        PIE_disableAllInts(myPie);
        CPU_disableGlobalInts(myCpu);
        CPU_clearIntFlags(myCpu);
    
        // If running from flash copy RAM only functions to RAM
    #ifdef _FLASH
        memcpy(&RamfuncsRunStart, &RamfuncsLoadStart, (size_t)&RamfuncsLoadSize);
    #endif
    
        // Initialize GPIO
        GPIO_setPullUp(myGpio, GPIO_Number_4, GPIO_PullUp_Disable);
        GPIO_setMode(myGpio, GPIO_Number_4, GPIO_4_Mode_EPWM3A);
    
        GPIO_setPullUp(myGpio, GPIO_Number_5, GPIO_PullUp_Disable);
        //GPIO_setQualification(myGpio, GPIO_Number_5, GPIO_Qual_Sync);
        GPIO_setMode(myGpio, GPIO_Number_5, GPIO_5_Mode_ECAP1);
    
        // Setup a debug vector table and enable the PIE
        PIE_setDebugIntVectorTable(myPie);
        PIE_enable(myPie);
    
        // Register interrupt handlers in the PIE vector table
        PIE_registerPieIntHandler(myPie, PIE_GroupNumber_4, PIE_SubGroupNumber_1,
                                  (intVec_t)&ecap1_isr);
    
        // Setup peripherals used in this example
        InitEPwmTimer();
        InitECapture();
    
        // Initialize counters:
        ECap1IntCount = 0;
        ECap1PassCount = 0;
    
        // Enable CPU INT4 which is connected to ECAP1-4 INT:
        CPU_enableInt(myCpu, CPU_IntNumber_4);
    
        // Enable eCAP INTn in the PIE: Group 3 interrupt 1-6
        PIE_enableCaptureInt(myPie);
    
        // Enable global Interrupts and higher priority real-time debug events:
        CPU_enableGlobalInts(myCpu);
        CPU_enableDebugInt(myCpu);
    
        GPIO_setMode(myGpio, GPIO_Number_34, GPIO_34_Mode_GeneralPurpose);
        GPIO_setDirection(myGpio, GPIO_Number_34, GPIO_Direction_Output);
    
        for(;;)
        {
            //__asm("          NOP");
            GPIO_setHigh(myGpio, GPIO_Number_34);
            DELAY_US(10);
            GPIO_setLow(myGpio, GPIO_Number_34);
            DELAY_US(100);
            counter_ecap = ECap1Regs.TSCTR; //checking if TSCTR is modified
            CAP_enableTimestampCounter(myCap);          // Start Counter
    
    
        }
    }
    
    void InitEPwmTimer()
    {
        CLK_disableTbClockSync(myClk);
        CLK_enablePwmClock(myClk, PWM_Number_3);
    
        PWM_setCounterMode(myPwm, PWM_CounterMode_Up);
        PWM_setPeriod(myPwm, PWM3_TIMER_MIN);
        PWM_setPhase(myPwm, 0x00000000);
        PWM_setActionQual_Period_PwmA(myPwm, PWM_ActionQual_Toggle);
    
        // TBCLK = SYSCLKOUT
        PWM_setHighSpeedClkDiv(myPwm, PWM_HspClkDiv_by_2);
        PWM_setClkDiv(myPwm, PWM_ClkDiv_by_1);
    
        EPwm3TimerDirection = EPwm_TIMER_UP;
    
        CLK_enableTbClockSync(myClk);
    }
    
    void InitECapture()
    {
        CLK_enableEcap1Clock(myClk);
    
        CAP_disableInt(myCap, CAP_Int_Type_All);    // Disable all capture interrupts
        CAP_clearInt(myCap, CAP_Int_Type_All);      // Clear all CAP interrupt flags
        CAP_disableCaptureLoad(myCap);              // Disable CAP1-CAP4 register loads
        CAP_disableTimestampCounter(myCap);         // Make sure the counter is stopped
    
        // Configure peripheral registers
        //CAP_setCapOneShot(myCap);                   // One-shot
        CAP_setCapContinuous(myCap);
        CAP_setStopWrap(myCap, CAP_Stop_Wrap_CEVT2);// Stop at 2 events
        CAP_setCapEvtPolarity(myCap, CAP_Event_1, CAP_Polarity_Rising);    // Rising edge
        CAP_setCapEvtPolarity(myCap, CAP_Event_2, CAP_Polarity_Falling);     // Falling edge
       // CAP_setCapEvtPolarity(myCap, CAP_Event_3, CAP_Polarity_Rising);    // x edge
       // CAP_setCapEvtPolarity(myCap, CAP_Event_4, CAP_Polarity_Falling);     // x edge
    
        CAP_setCapEvtReset(myCap, CAP_Event_1, CAP_Reset_Disable);   // absolute
        CAP_setCapEvtReset(myCap, CAP_Event_2, CAP_Reset_Enable);   // Difference operation
       // CAP_setCapEvtReset(myCap, CAP_Event_3, CAP_Reset_Enable);   // Difference operation
       // CAP_setCapEvtReset(myCap, CAP_Event_4, CAP_Reset_Enable);   // Difference operation
    
        CAP_enableSyncIn(myCap);                    // Enable sync in
        CAP_setSyncOut(myCap, CAP_SyncOut_SyncIn);  // Pass through
    
    
        CAP_enableCaptureLoad(myCap);
    
        //CAP_enableTimestampCounter(myCap);          // Start Counter
        CAP_rearm(myCap);                           // arm one-shot
        CAP_enableCaptureLoad(myCap);               // Enable CAP1-CAP4 register loads
        CAP_enableInt(myCap, CAP_Int_Type_CEVT2);   // 4 events = interrupt CEVT2
    }
    
    __interrupt void ecap1_isr(void)
    {
        cap1 = CAP_getCap1(myCap);
        cap2 = CAP_getCap2(myCap);
        cap3 = CAP_getCap3(myCap);
        cap4 = CAP_getCap4(myCap);
    
        temp_val = (cap2);
        distance = ((temp_val * cpu_period) / 58.82) * 2;
        ECap1IntCount++;
    
        CAP_disableTimestampCounter(myCap);         // Make sure the counter is stopped
    
        interupt_counter_ecap = ECap1Regs.TSCTR; //checking if TSCTR is modified in ISR
    
        ECap1PassCount++;
    
        CAP_clearInt(myCap, CAP_Int_Type_CEVT2);
        CAP_clearInt(myCap, CAP_Int_Type_Global);
    
    
        CAP_rearm(myCap);
    
        // Acknowledge this interrupt to receive more interrupts from group 4
        PIE_clearInt(myPie, PIE_GroupNumber_4);
    }
    
    void Fail()
    {
        __asm("   ESTOP0");
    }
    
    //===========================================================================
    // No more.
    //===========================================================================
    

    Thank you for your time.