175192387 发表于 2011-4-18 09:57:26

关于延时函数的问题

这是设置时钟的程序,这样的话,一个指令周期应该是1us
    SCFQCTL=31;                     //MCLK=320*ACLK=10240KHz,DCO+=0
    SCFI0=0;
    FLL_CTL0 |= XCAP18PF;
我写了这个函数,我想一个_NOP();应该是一个指令周期,是不是说delay_Nus(1)就是延时1US???
void delay_Nus(uint8 n)
{
        uchar i;
        for(i = n;i > 0;i--)
      _NOP();
}

liuzq1981 发表于 2011-4-18 10:49:29

要想精确延时的话用定时器TIMER

/*延时微秒函数*/
void delay_us(unsigned int us)
{
TACTL= TASSEL1;                  // 设置 TA 时钟源为 系统时钟MCLK
TACCR0 = us*CPU_F;                   // 载入 CCR0 延时值(us 延时值)

TACCTL0 &= ~CCIFG;                  // 清除中断标志
TACTL |= TACLR+MC_1;                // 清除 TA 和启动 TA 定时器 Up模式
while ((TACCTL0 & CCIFG)==0);       // 等待定时器完成 定时时间
TACTL &= ~MC_1;                     // 停止 TA 定时器结束
}

dr2001 发表于 2011-4-18 11:12:00

回复【楼主位】175192387
-----------------------------------------------------------------------

否。

for循环的i --以及i > 0判断都可能产生额外的指令,从而消耗执行时间。而且该消耗是每个周期都存在的。
这种类型的延时方法,必须看编译后的汇编或者使用汇编语言写函数;然后查对应的CPU手册计算指令周期数,从而得到较为准确的结果。

而且,该类延时受到中断等的影响。

wangshaosh 发表于 2011-4-25 09:36:17

延时函数我用示波器仔细观察过
_NOP();对应的是一个时钟周期(假如是8M的晶振,这样就是0.125us)非常精确
所以1us就是_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();_NOP();
加入写成for(i=0;i<8;i++)
         _NOP();
这样就远大于1us了   主要是因为每条C语言语句可能占用好几个时钟周期
在上面的for循环中每个循环都需要对i进行处理 所以就耽误时间了

所以短时间的延时就直接使用_NOP();不要进行循环来省事

如果进行毫秒级的延时
void XT2delayms(unsigned int time_)// XT2的延时ms
{
        unsigned int _i;
        while(time_--)
        for (_i = 0; _i < 1594; _i++);
}

这样对每个循环判断的时间相对较小,所以使用此函数可以延时的线性度就比较好

scty 发表于 2011-4-27 00:07:05

为什么不用IAR自带的延时呢?

#defineCPU_F         ((double)1000000)   //MCLK主频
#definedelay_us(x)   __delay_cycles((long)(CPU_F*(double)x/1000000.0))
#definedelay_ms(x)   __delay_cycles((long)(CPU_F*(double)x/1000.0))

pentong 发表于 2011-4-27 00:20:23

建议用自带的延时函数来做;
定时器里面的TACCR0值,通过自带延时函数观察计数器来设置,这样才准确。

guisi 发表于 2011-5-20 10:40:45

LZ的问题,看来楼主也是使用C语言了。
页: [1]
查看完整版本: 关于延时函数的问题