关于延时函数的问题
这是设置时钟的程序,这样的话,一个指令周期应该是1usSCFQCTL=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();
} 要想精确延时的话用定时器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 定时器结束
} 回复【楼主位】175192387
-----------------------------------------------------------------------
否。
for循环的i --以及i > 0判断都可能产生额外的指令,从而消耗执行时间。而且该消耗是每个周期都存在的。
这种类型的延时方法,必须看编译后的汇编或者使用汇编语言写函数;然后查对应的CPU手册计算指令周期数,从而得到较为准确的结果。
而且,该类延时受到中断等的影响。 延时函数我用示波器仔细观察过
_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++);
}
这样对每个循环判断的时间相对较小,所以使用此函数可以延时的线性度就比较好 为什么不用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)) 建议用自带的延时函数来做;
定时器里面的TACCR0值,通过自带延时函数观察计数器来设置,这样才准确。 LZ的问题,看来楼主也是使用C语言了。
页:
[1]