Explanation and correction of MSP430 MCU __delay_cycles precise delay[Copy link]
Here, I want to discuss 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 this way of writing: #define CPU_CLOCK 8000000 This makes people easily 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 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, simply changing 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, 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, and the function does not support variable parameters, its parameters can only be constants.