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.
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.
//===========================================================================
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. //===========================================================================
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,
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.