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