This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Timer, t1-t0, integral promotion

For ARM7, A hardware timer is 32-bits, and unsigned int is 32-bits too;
For a 16-bits MCU, A hardware timer is 16-bits, and unsigned int is 16-bits too;

So,

t0 = timer_val;
while ( ( timer_val - t0 ) < delay_val );

provide a simple and good delay;

Not so sure about, if a cast is needed.

t0 = timer_val;
while ( (unsigned int)( timer_val - t0 ) < delay_val );

Just noticed that, due to the integral promotion,

unsigned short t0, t1;
( t1 - t0 ) is a signed int.

It seems that,

unsigned int t0, t1;
( t1 - t0 ) is still an unsigned int.

I noticed this, because I use unsigned short to present a 16-bits timer_val on my X86-PC for testing/simulating purpose, and the result is not what I expected.

Parents
  • #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            uint32_t t0 = 4294967290, t1 = 19;    // t1 < t0
    
            printf("t0 u = %u\n", t0);
            printf("t1 u = %u\n", t1);
            printf("t0 d = %d\n", t0);
            printf("t1 d = %d\n", t1);
    
            printf("result u = %u\n", (t1 - t0));
            printf("result d = %d\n", (t1 - t0));
    
            if ( (t1 - t0) == 25 )
                    printf("OK\n");
            else
                    printf("NG\n");
    
            system("PAUSE");
    }
    


    t0 u = 4294967290
    t1 u = 19
    t0 d = -6
    t1 d = 19
    result u = 25
    result d = 25
    OK

    #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            int32_t t0 = 2147483640, t1 = -2147483631;    // t1 < t0
    
            printf("t0 u = %u\n", t0);
            printf("t1 u = %u\n", t1);
            printf("t0 d = %d\n", t0);
            printf("t1 d = %d\n", t1);
    
            printf("result u = %u\n", (t1 - t0));
            printf("result d = %d\n", (t1 - t0));
    
            if ( (t1 - t0) == 25 )
                    printf("OK\n");
            else
                    printf("NG\n");
    
            system("PAUSE");
    }
    


    t0 u = 2147483640
    t1 u = 2147483665
    t0 d = 2147483640
    t1 d = -2147483631
    result u = 25
    result d = 25
    OK

Reply
  • #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            uint32_t t0 = 4294967290, t1 = 19;    // t1 < t0
    
            printf("t0 u = %u\n", t0);
            printf("t1 u = %u\n", t1);
            printf("t0 d = %d\n", t0);
            printf("t1 d = %d\n", t1);
    
            printf("result u = %u\n", (t1 - t0));
            printf("result d = %d\n", (t1 - t0));
    
            if ( (t1 - t0) == 25 )
                    printf("OK\n");
            else
                    printf("NG\n");
    
            system("PAUSE");
    }
    


    t0 u = 4294967290
    t1 u = 19
    t0 d = -6
    t1 d = 19
    result u = 25
    result d = 25
    OK

    #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            int32_t t0 = 2147483640, t1 = -2147483631;    // t1 < t0
    
            printf("t0 u = %u\n", t0);
            printf("t1 u = %u\n", t1);
            printf("t0 d = %d\n", t0);
            printf("t1 d = %d\n", t1);
    
            printf("result u = %u\n", (t1 - t0));
            printf("result d = %d\n", (t1 - t0));
    
            if ( (t1 - t0) == 25 )
                    printf("OK\n");
            else
                    printf("NG\n");
    
            system("PAUSE");
    }
    


    t0 u = 2147483640
    t1 u = 2147483665
    t0 d = 2147483640
    t1 d = -2147483631
    result u = 25
    result d = 25
    OK

Children
  • For int32_t/uint32_t, the result is what I want.
    Due to the integral promotion, the result of int16_t/uint16_t is not I want.

  • My mistake:

    #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            int32_t t0 = 2147483640, t1 = 123;    // t1 < t0
    
            printf("t0 u = %u\n", t0);
            printf("t1 u = %u\n", t1);
            printf("t0 d = %d\n", t0);
            printf("t1 d = %d\n", t1);
    
            printf("result u = %u\n", (t1 - t0));
            printf("result d = %d\n", (t1 - t0));
    
            system("PAUSE");
    }
    


    t0 u = 2147483640
    t1 u = 123
    t0 d = 2147483640
    t1 d = 123
    result u = 2147483779
    result d = -2147483517

    #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            uint32_t t0 = 2147483640, t1 = 123;    // t1 < t0
    
            printf("t0 u = %u\n", t0);
            printf("t1 u = %u\n", t1);
            printf("t0 d = %d\n", t0);
            printf("t1 d = %d\n", t1);
    
            printf("result u = %u\n", (t1 - t0));
            printf("result d = %d\n", (t1 - t0));
    
            system("PAUSE");
    }
    


    t0 u = 2147483640
    t1 u = 123
    t0 d = 2147483640
    t1 d = 123
    result u = 2147483779
    result d = -2147483517

  • My mistake again:

    #include <stdio.h>
    #include <stdint.h>
    
    
    void main(void)
    {
            int32_t t0 = 2147483640, t1 = 123;    // t1 < t0
    
            printf("t0 u = %u\n", t0);
            printf("t1 u = %u\n", t1);
            printf("t0 d = %d\n", t0);
            printf("t1 d = %d\n", t1);
    
            printf("result u = %u\n", (t1 - t0));
            printf("result d = %d\n", (t1 - t0));
    
            if ( (t1 - t0) == 2147483779 )
                printf("OK\n");
            else
                printf("NG\n");
    
            system("PAUSE");
    }
    

    t0 u = 2147483640
    t1 u = 123
    t0 d = 2147483640
    t1 d = 123
    result u = 2147483779
    result d = -2147483517
    OK

    It is still OK!!!

  • I think this topic is too difficult to understand for me.

    Many thanks to everyone involved.

    My favorite:

    /* both t0 and timer_val are unsigned */
    t0 = timer_val;
    while ( (cast to timer-size unsigned)( timer_val - t0 ) < delay_val );