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.

CCS/MSP432P401R: Clock() function not calculating the correct time elapsed.

Part Number: MSP432P401R

Tool/software: Code Composer Studio

I have some code that is supposed to determine the amount of time elapsed and in this simple example that I have, it outputs the wrong time elapsed.

#include <sys/time.h>

int main(){
      clock_t t;
      t = clock();
      delay(5000);
      t = clock() - t;
      printf ((float)t)/CLOCKS_PER_SEC);
      }

OUTPUT:

0.00

  • I didn't find a document that described what clock() is expected to do in the msp432P library. The comments in the source suggest that it asks the host PC (which wasn't quite what I expected) via the debugger semi-hosting, and if the host isn't there it returns 0. This is from:

    ccsv8\tools\compiler\ti-cgt-arm_18.1.5.LTS\lib\src\clock.c

    ccsv8\tools\compiler\ti-cgt-arm_18.1.5.LTS\lib\src\hostclock.c

    I suggest you run/sample a timer, maybe SysTick. Are you trying to measure CPU or elapsed time? (The Unix clock(3) measures CPU time.)

  • I want to measure the time elapsed, so in this particular example I posted it should be around 5 seconds because of the delay.

  • I suggest using one of the Timer32-s. [Ref TRM (SLAU356H) Chap 18] -- It's very simple to set up and 32 bits gives a fairly wide range (90 seconds at 48MHz). If you want more range (with reduced precision) there are pre-scalers of /16 and /256.

    I suggest Free-Run mode with no interrupts. (Pinky-promise to measure only periods shorter than the range.)  Your clock() replacement then just reads the VALUE register. The Timer32 counts down, so you have to subtract two samples backwards. Unsigned-underflow gives you the correct answer even if the counter wraps.

    There's an Example (it's One-Shot mode, not Free-Run, but you can interpolate) in:

    http://dev.ti.com/tirex/explore/node?node=AMIPGPOyb9htr.YBcwVItA__z-lQYNj__LATEST

    The Interrupt Enable (IE) is =1 at reset so be sure to set CONTROL with =, not |=.

  • When I print the value of the timer it stays a constant number and does not count down. It keeps printing "1073790976". I don't understand why.

  • It sounds like you're doing something similar to printf("%d", TIMER32_1), aka 0x4000C000. You want TIMER32_1->VALUE.

    Have you set TIMER32_1->CONTROL?

  • Thank you for that, the number is decreasing. But now I'm trying to make sense of the number... how would I convert, "16744247" into seconds? What is the representation of "16744247"?

  • The Tiimer32 runs from MCLK, i.e. each tick is the same as a CPU tick. If you haven't changed it (your original code didn't) MCLK is running at 3MHz. I typically find myself defining a preprocessor symbol for the clock speed, e.g.

    > #define HZ 3000000UL   // 3MHz

    so that value in seconds is 16744247/HZ. As a singleton, such a value doesn't have much meaning (it's (unsigned)(-1) - when_you_started_the_timer). The utility is in the difference between two readings.

  • Okay, I'm not understanding this code. I was under the assumption that you plug in an initial value and once it started the timer would start counting down every second. When I'm running the code it seems as if the values that I'm printing are arbitrary. For example here is some output: 342779 ... 347717 ... 382323 ... 387227 ...

    It appears to be counting down and the counting up. I don't really understand what is happening. I just need something that starts at an initial value and then counts down to a value of 0 and stops at 0.

  • This is somewhat different from what you originally requested. One-shot mode does what you describe now. Load the LOAD register with how long (ticks=seconds*HZ) you want to count.

    Which code are you referring to?

  •     int main(){
        WDT_A->CTL = WDT_A_CTL_PW |             // Stop WDT
                WDT_A_CTL_HOLD;
    
        // Timer32 set up in one-shot, free run, 32-bit, no pre-scale
        TIMER32_1->CONTROL = TIMER32_CONTROL_SIZE |
                TIMER32_CONTROL_ONESHOT;
    
        // Load Timer32 Counter with initial value
        TIMER32_1->LOAD= 0x50226;
    
        // Start Timer32 and enable interrupt
        TIMER32_1->CONTROL = TIMER32_CONTROL_ENABLE;
        int value = TIMER32_1->VALUE;
        Serial.println(value);
        delay(4000);
        value = TIMER32_1->VALUE;
        Serial.println(value);}

    OUTPUT: 330418 351919

    This is the code that I am running and the output that I am getting. I really don't understand what is happening. What do I need to change?

  • > TIMER32_1->CONTROL = TIMER32_CONTROL_ENABLE;

    This sets it (back) into 16-bit/periodic mode. Try:

    > TIMER32_1->CONTROL |= TIMER32_CONTROL_ENABLE;

    A curiosity of this timer is that setting it into 16-bit mode (per se) doesn't clear the high bits.

    ----------------

    int value = TIMER32_1->VALUE;

    VALUE is 32-bit unsigned. (This doesn't matter with a small LOAD value, but it does in 32-bit periodic mode.) This should be:

    > unsigned int value = TIMER32_1->VALUE;

  • Now I'm getting all 0 for the output of this code:

     int main(){
        WDT_A->CTL = WDT_A_CTL_PW |             // Stop WDT
                WDT_A_CTL_HOLD;
    
        // Timer32 set up in one-shot, free run, 32-bit, no pre-scale
        TIMER32_1->CONTROL = TIMER32_CONTROL_SIZE |
                TIMER32_CONTROL_ONESHOT;
    
        // Load Timer32 Counter with initial value
        TIMER32_1->LOAD= 0x50226;
    
        // Start Timer32 and enable interrupt
        TIMER32_1->CONTROL |= TIMER32_CONTROL_ENABLE;
        unsigned int value = TIMER32_1->VALUE;
        Serial.println(value);
        delay(4000);
        value = TIMER32_1->VALUE;
        Serial.println(value);
        
    }

  • I'm not surprised that the second value is 0, since my calculator says 0x50226/3000000 = ~0.1 seconds, i.e. much less than 4 seconds.

    I don't know about the first. When I do this sequence, monitoring with an LED, I get a "blip" that is roughly 0.1 seconds long.

    Are you using any breakpoints? Observed behavior is that Timer32 keeps counting while at a breakpoint.

  • No, I don't believe so. I really don't understand this. Do you think you could write something very simple that does what I need?

  • I think this code is about as simple as it gets.

    Maybe Serial or delay() is getting in your way? They look Arduino-ish but I don't know where you're getting them from.

  • Are you using Energia?

**Attention** This is a public forum