About MSP430 Miscellaneous Talks --Precise Delay of delay_cycles
[Copy link]
Regarding the issue of using __delay_cycles delay in MSP430 microcontroller.
IAR for MSP430 compiler provides a compiler inline precise delay function (not a real function) to provide users with precise delay use. The function prototype is:
_intrinsic void __delay_cycles(unsigned long __cycles);
This internal function implements a delay of __cycles CPU cycles, but for the setting of this parameter, I want to state:
__cycles requires us to pass the number of CPU cycles.
The common usage on the Internet is:
#define CPU_CLOCK 8000000
#define delay_us(us) __delay_cycles(CPU_CLOCK/1000000*(us))
#define delay_ms(ms) __delay_cycles(CPU_CLOCK/1000*(ms))
When the CPU main clock frequency is 8MHz, this is indeed no problem, but the following writing:
#define CPU_CLOCK 8000000
This makes people think that they can unify the parameters of different main frequency systems by modifying its value. In fact,
this is incorrect! For example, modify it to #define CPU_CLOCK 32768 to achieve the delay of 32KHz main frequency...
Let's do some calculations:
When the system main clock frequency CPU_CLOCK is 8MHz:
frequency f = 8MHz = 8,000,000Hz
machine cycle Tm = 1/f = 1/8MHz = 1/8us
That is, the duration of a machine cycle (nop) is 1/8us, so the delay of 1us is 8*Tm, the same as above:
#define delay_us(us) __delay_cycles(8*(us))
#define delay_ms(ms) __delay_cycles(8000*(ms))
According to the above macro definition method, we define CPU_CLOCK as 32768, then:
frequency f = 32KHz = 32,768Hz
machine cycle Tm = 1/f = 1/32768Hz ~= 30.5us
As you can imagine, the shortest CPU instruction execution cycle is 30.5us. At this time, is it possible to delay for 1us? So, simply change the above definition to
#define CPU_CLOCK 32768
is absolutely wrong.
Similarly, some friends have achieved a delay of 0.5us, which is also unrealistic when f = 1MHz = 1000000Hz
, when the machine cycle Tm = 1us. When f = 8Mhz, 4 machine cycles are 0.5us, which is acceptable.
Therefore, to avoid incorrect usage or incorrect understanding, it is better to define the macro as follows:
#if CPU_CLOCK == 8000000
#define delay_us(us) __delay_cycles(8*(us))
#define delay_ms(ms) __delay_cycles(8000*(ms))
#else
#pragma error "CPU_CLOCK is defined implicitly!"
#endif
另外:
__delay_cycles is not a real function, it is just provided for compiler inline expansion.
Variable parameters are not supported, only constant parameters can be used.
|