很多时候我们偷懒采用CPU在那里空跑的方式来获得延时,下面看看有哪些延时语句
__no_operation();
_NOP();
复制代码
这是空操作语句,其实我认为少量的这样的语句是可以接受的
volatile int i = MAX_VALUE;
while (i-- > 0);
复制代码
这种是最常见的延时操作了
__delay_cycles(NUMBER_OF_CYCLES);
复制代码
相似的还有这个。
在ULP中出现上面的三种语句都会提示报警,其实我认为有时候为了调试或者一两个clk的等待使用NOP这样的语句(第一种)其实可以接受的,很少时间的CLK延时也去使用定时器,引入太多的中断源也不利于稳定。
当然,第二和第三中才是“罪大恶极”的延时语句,长时间让CPU处于一种无意义的运行状态是很耗费能量的。相比较而言定时器就要节能很多,所以建议采用定时器定时唤醒的方式。
COPY个例子过来:
//******************************************************************************
// MSP430G2xx3 Demo - Timer_A, Toggle P1.0, CCR0 Cont. Mode ISR, DCO SMCLK
//
// Description: Toggle P1.0 using software and TA_0 ISR. Toggles every
// 50000 SMCLK cycles. SMCLK provides clock source for TACLK.
// During the TA_0 ISR, P1.0 is toggled and 50000 clock cycles are added to
// CCR0. TA_0 ISR is triggered every 50000 cycles. CPU is normally off and
// used only during TA_ISR.
// ACLK = n/a, MCLK = SMCLK = TACLK = default DCO
//
// MSP430G2xx3
// ---------------
// /|\| XIN|-
// | | |
// --|RST XOUT|-
// | |
// | P1.0|-->LED
//
// D. Dang
// Texas Instruments Inc.
// December 2010
// Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10
//******************************************************************************
#include
void main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop WDT
P1DIR |= 0x01; // P1.0 output
CCTL0 = CCIE; // CCR0 interrupt enabled
CCR0 = 50000;
TACTL = TASSEL_2 + MC_2; // SMCLK, contmode
_BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt
}
// Timer A0 interrupt service routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer_A (void)
{
P1OUT ^= 0x01; // Toggle P1.0
CCR0 += 50000; // Add Offset to CCR0
}
复制代码 |