在ZSTACK中使用延时函数注意(附机器时钟指令周期)

关于Z-stack的延时,稍微总结几点使用中可能需要注意的地方:
  1同样的代码,裸机实验和在Z-stack中延时的时间可能是不一样的。
  因为在Z-stack中可能被中断打断,也可能Z-stack在某个地方对时钟的配置不一样,建议如果需要比较精确的延时,用示波器来看。可以用某个引脚电平拉高和拉低的语句夹住需要测试的部分,然后用示波器看电平翻转所用时间即可。
  附Z-STACK自带的延时函数

#define MicroWait(t) Onboard_wait(t)
void Onboard_wait( uint16 timeout )
{
  while (timeout--)
  {
    asm("NOP");
    asm("NOP");
    asm("NOP");
  }
}

  如果必要,注意屏蔽中断。
  2 如果一定要通过计算来得到精确延时的话,请注意CC2530是加强型的51单片机,一个机器周期不是等于12个时钟周期。(此文最后附时钟周期、机器周期与指令周期的区别)。
  以下是一个网友的计算,我搬运过来的
链接:计算延时

#define NOP()asm("NOP")

#define TIME_A OW_HW_WaitUs(3);//6uS
#define TIME_B OW_HW_WaitUs(47);//64uS
#define TIME_C OW_HW_WaitUs(44);//60uS
#define TIME_D OW_HW_WaitUs(6);//10uS
#define TIME_E OW_HW_WaitUs(5);//9uS
#define TIME_F OW_HW_WaitUs(40);//55uS
#define TIME_G {;}//0uS
#define TIME_H OW_HW_WaitUs(364);//480uS
#define TIME_I OW_HW_WaitUs(52);//70uS
#define TIME_J OW_HW_WaitUs(310);//410uS

void OW_HW_WaitUs(unsigned short microSecs)
{
    while(microSecs--)
    {
        NOP();
        NOP();
        NOP();
    }
}

  3 在Z-stack中不要滥用定时器
  定时器可以得到更为精确的延时,但是Z-stack中如果滥用定时器,可能会使某些更重要的中断得不到响应。一个比较典型的例子就是按键的消抖,如果在中断中使用一个20ms的延时来消抖,简直是可怕的。另外提一句,关于Z-STACK中的按键消抖,可以设置一个定时事件,如
osal_start_timerEx(SerialApp_TaskID, A_EVT, 5000);
也可以修改官方的按键处理函数。
  4 毫秒级的延时建议使用osal_start_timerEx这个定时器。不过需要设置某些事件。

 附
指令周期是取出并执行一条指令的时间,指令周期常常有若干个CPU周期(也叫机器周期),CPU周期一般由12个时钟周期组成(时钟周期通常由晶振决定)。
  也就是说指令周期的通常大于cpu周期,指令周期的长短与执行的指令有关,有的指令需要花费更多的CPU周期。
  1、时钟周期
  时钟周期也称为振荡周期,定义为时钟脉冲的倒数(可以这样来理解,时钟周期就是单片机外接晶振的倒数,例如12M的晶振,它的时间周期就是1/12 us),是计算机中最基本的、最小的时间单位。
  在一个时钟周期内,CPU仅完成一个最基本的动作。对于某种单片机,若采用了1MHZ的时钟频率,则时钟周期为1us;若采用4MHZ的时钟频率,则时钟周期为250us。由于时钟脉冲是计算机的基本工作脉冲,它控制着计算机的工作节奏(使计算机的每一步都统一到它的步调上来)
  在8051单片机中把一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示)。
  2、机器周期
  在计算机中,为了便于管理,常把一条指令的执行过程划分为若干个阶段,每一阶段完成一项工作。例如,取指令、存储器读、存储器写等,这每一项工作称为一个基本操作。完成一个基本操作所需要的时间称为机器周期。
  8051系列单片机的一个机器周期同6个S周期(状态周期)组成。前面已说过一个时钟周期定义为一个节拍(用P表示),二个节拍定义为一个状态周期(用S表示),8051单片机的机器周期由6个状态周期组成,也就是说一个机器周期=6个状态周期=12个时钟周期。
  3、指令周期
  指令周期是执行一条指令所需要的时间,一般由若干个机器周期组成。指令不同,所需的机器周期数也不同。对于一些简单的的单字节指令,在取指令周期中,指令取出到指令寄存器后,立即译码执行,不再需要其它的机器周期。
  对于一些比较复杂的指令,例如转移指令、乘法指令,则需要两个或者两个以上的机器周期。
  通常含一个机器周期的指令称为单周期指令,包含两个机器周期的指令称为双周期指令。
  CC2530的每个指令周期是一个时钟(我们一直说CC2530是个增强型的51单片机,从这里也可以看出来),而标准的8051 每个指令周期是12 个时钟。
结论,CC2530定时器执行一个+1操作的时间是晶振的倒数

你可能感兴趣的:(ZigBee)