毫秒,微妙級別軟體定時器

2021-10-02 06:05:34 字數 2562 閱讀 4165

微控制器開發中,軟體定時器是常用的工具。定時執行特定任務和延時功能,都可以用軟體定時器實現。

常見的延時函式的實現做法有:

1. 使用空指令進行延時,通過控制空指令的執行次數,進行延時。優點:不需要占用系統外設。缺點:系統執行指定個空指令的時間不穩定,中途出現的中斷處理會嚴重影響計時的精確性。

2.使用微控制器的定時器外設,設定特定的時間產生中斷,進行計時。優點:計時準確,不受其他中斷影響計時。缺點:浪費微控制器外設資源,並且延時處理不能巢狀呼叫,靈活性不夠。

這裡要介紹的是利用微控制器內部的systicket 定時器實現的軟體定時器。systicket timer每毫秒產生一次中斷,微控制器內有乙個無符號型別的32位全域性變數msticket對中斷次數進行計數,我們可以認為msticket

為當前「系統時間」。

先介紹相對簡單的ms定時器,ms定時器的結構定義如下:

typedef struct

mssofttimer;

start欄位用來表示定時器的開關狀態,考慮到位元組對齊的問題,用了十六位的型別。如果微控制器儲存資源緊張,可以不用這個字段。value欄位用來儲存開始計時時刻系統的時間,也就是msticket的值。

ms定時器的介面函式如下:

1

#define def_ms_tm(tm) mssofttimer tm;

2#define declare_ms_tm(tm) extern mssofttimer tm;

3#define get_ms_tm_val(tm) _get_ms_tm_val(tm.value)45

#define start_ms_tm(tm) do \

6while(0)10

11#define init_ms_tm(tm) do \

12while(0)16

17#define is_ms_tm_on(tm) ( tm.start)

18#define stop_ms_tm(tm) tm.start = 0

定義定時器,本質是就是定義乙個定時器型別的變數。可以巢狀呼叫,如果要在中斷處理函式中使用軟體定時器,要先將msticket 中斷的優先順序設定為最高端別的,並且可以搶占。獲取當前的計時時間,就是將當前的「系統時間」,減去定時器開始計時時刻的時間。具體實現如下:

1

uint32_t _get_ms_tm_val(uint32_t pre_timer_val)210

else

1114

15return

ret_timer_val;

16 }

第12行**中,對msticket 變數溢位做了判斷和處理。

利於ms軟體定時器實現的ms延時函式如下:

void

delay_ms(uint32_t ms)

us 定時器實現原理跟ms定時器類似,但會稍微複雜一些。us定時利用系統systicket 定時器內部的計數值(systick current value)進行計時。如果系統時鐘為20m,每隔1us,systick current value減少20。

如果系統時鐘為48m,每隔1us,systick current value 減少48。系統systicket 定時器結構如下:

1 typedef struct

2 systick_type;

us 定時器的結構體如下:

1 typedef struct

2ussofttimer;

init_ticket_val 記錄的是開始計時時刻systick current value的值。init_ms_val 記錄的是開始計時時刻msticket 的值。

us 定時器介面函式實現如下:

1

void _start_us_sw(ussofttimer*ptm)27

8#pragma o0

9 uint32_t _get_us_tm_val(ussofttimer*ptm)

1037

38return

us_interval;39}

4041

#define def_us_tm(tm) ussofttimer tm

42#define declare_us_tm(tm) extern ussofttimer tm

43#define get_us_tm_val(tm) _get_us_tm_val(&tm)

44#define is_us_tm_on(tm) (1== tm.start)

45#define stop_us_tm(tm) tm.start = 0

46#define start_us_tm(tm) _start_us_sw(&tm)

us延時函式的實現如下:

1

void

delay_us(uint32_t us)

2

STM8L1xx利用定時器實現毫秒和微妙延時

採用微控制器的定時計數器進行毫秒和微妙級延時,精度較準。檢測溢位時產生的標誌位來判斷延時到達。下面以stm8l101晶元為例及配合 說明。一 實現原理 1 初始化timer2時鐘源 附上相應 void tim2init void 開啟外設時鐘源 選擇向上計數模式和開啟自動重載入功能 填裝計數器的初始...

swoole學習之毫秒定時器

常規定時器 首先想到的就是linux自帶的crontab 不過這個定時器是分鐘級別的.swoole定時器 swoole timer after after time,callback 設定乙個延時器 swoole timer clear timer id 清除指定的定時器 server on ope...

c實現毫秒 微秒級定時器

秒級定時器,都知道可以用sleep實現,但如果要實現毫秒級呢?usleep?使用select實現 select函式原型 int select int nfds,fd set readfds,fd set writefds,fd set exceptfds,struct timeval timeout...