1. 程式人生 > >TICK延時的有效方法

TICK延時的有效方法

以往,如果要在程式裡非堵塞式地延時一段時間,比如說我發了一包資料,然後要等待一段時間,如果時間到了還沒收到回覆,則認為超時,如果在等待時間內沒有收到資料,我也不能停下來空等,而應該去做別的事。一般情況下,我們會設定一個定時器,讓他週期中斷,然後定一個全域性變數,這個全域性變數在這個定時器的中斷裡累加,程式中凡是需要延時的地方,可以通過讀取這個全域性變數,來知道時間流逝,這個全域性變數一般取名叫tick。在需要延時的時間,把當前的tick儲存下來,然後每次程式執行到需要延時的地方,就拿當前的tick減去儲存的tick,檢視一下過去了多長時間,以此來判斷超時時間是否一到。

這裡這個tick的減的操作,大部分情況下都是沒問題的。因為一般情況下,tick的累加間隔一般設定1ms,而tick的大小一般也定為32位,要讓這個tick累加到溢位變成0,要經過49天。討論這個tick溢位問題,是因為這個減的操作,只有在tick沒溢位的時候是沒問題的。試想一下,如果在等待的期間tick溢位了,那麼儲存的值就會比當前的tick的值要大了,無符號數,用小的減去大的會怎麼樣?

可能你會想,考慮到這個情況,那每次減之前,判斷一下當前tick與儲存的tick的大小,保證用大的減去小的,一樣能準確獲得延時時間。這樣做也確實能夠避免溢位的問題,可是程式裡就會很繁瑣很囉嗦。

可以有另外一種更有效的計算延時的方法。

在需要延時的時候,讀取當前tick,然後把當前tick的值加上你要延時的時間,儲存下來。像這樣end_tick = OS_GetTick() + delay_ms然後在判斷延時的時候,是判斷當前tick跟儲存下來的這個值是否相同。if(end_tick == OS_GetTick()),如果相同了,則說明延時時間已到。這個方法的巧妙利用了溢位。試想一下,tick溢位的情況,你把tick加上delay_ms,已經超過32位的表示範圍,例如0xffff fff0 + 0x20,那麼結果會是0x10。儲存的值就是0x10,而tick從當前的0xffff fff0累加到溢位也沒關係,溢位後tick從0又開始計數,計到0x10,就剛好到了我們想要的時間。這種方法,永遠也不用考慮溢位的情況