1. 程式人生 > >在ZSTACK中使用延時函式注意(附機器時鐘指令週期)

在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操作的時間是晶振的倒數