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.
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"); }
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 );