Explanation and correction of MSP430 MCU __delay_cycles precise delay[Copy link]
This post was last edited by fish001 on 2018-7-7 21:26 Here, I will discuss the issue of using __delay_cycles delay for 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 writing like this: #define CPU_CLOCK 8000000 This makes people think that they can modify its value to achieve the unification of system parameters with different main frequencies, but in fact this is incorrect! For example, modify it to #define CPU_CLOCK 32768 to achieve the delay of 32KHz main frequency... Let's calculate it: 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 In other words, 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 It is conceivable that the shortest instruction execution cycle of the CPU is 30.5us. At this time, is it possible to delay for 1us? Therefore, it is absolutely wrong to simply change the above definition to #define CPU_CLOCK 32768. Similarly, some friends have achieved a delay of 0.5us, which is also unrealistic when f = 1MHz = 1000000Hz, and the machine cycle Tm = 1us. When f = 8Mhz, 4 machine cycles are 0.5us. Therefore, in order to avoid incorrect use or incorrect understanding, it is best 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 In addition: __delay_cycles is not a real function, it just provides compiler inline expansion, the function does not support variable parameters, its parameters can only be constants.