簡單軟體定時器

2021-09-25 10:17:18 字數 1403 閱讀 7168

軟體定時器

在嵌入式開發中,定時器是及其常見的,但考慮到晶元外設資源有限,可以自己寫乙個軟體定時器,應用於對計時不是太嚴格的場合,比如led的閃爍,定時處理某一任務等等。該軟體定時器的原理是基於滴答系統時鐘中斷,在中斷中獲得時間基,該時間基可由使用者自由設定。另外有兩種方式可以實現軟體定時處理功能,後面會講到。

軟體定時器結構體元素

首先說明一下該軟體定時器的結構體元素:

#define stimer_empty  0    

#define stimer_valid  1

#define stimer_basetime 10   /* ms */

typedef int (*stimerproc_t)(int arg);

typedef struct stimer_t;

stimer_t結構體中有乙個指標函式proc,這是使用者定時處理的任務,並且看到該指標函式有乙個傳入引數,這由使用者新增定時器時傳入。其中迴圈週期,視具體任務情況而定。

在列舉中定義需要使用到的定時器序號,本文使用的是指定物件定時器的方式,另外的一種方式為定義乙個大的定時器緩衝區,在新增定時器時檢測到空的定時器即可新增,這兩種方式各有取捨,看具體應用場景修改。

typedef enum stimer_index_t;

static stimer_t g_stimer_buf[max_timer]; /* 定時器緩衝區 */

定時器核心**

在了解軟體定時器結構體元素之後,再來詳細看一下軟體定時器核心**:

int add_stimer(uint8_t id, stimerproc_t proc, uint32_t inv, uint32_t arg, int cycle)

return -1;

}void stop_stimer(uint8_t id)

}void stimer_proc(void)}}

}void stimer_task(void)}} 

}__weak void system_tick_callback(void)

}/* 滴答中斷1ms一次 */

void systick_handler(void)

void main(void)

}利用滴答系統時鐘產生的中斷計時獲得時間,這裡的滴答時鐘配置為1ms一次中斷,當中斷10次時即為乙個軟體定時器的時間基。

當需要新增乙個定時任務時,比如讓led燈500ms反轉一次狀態:

int led_task_proc(int arg)

/* 新增軟體定時器 */

void main(void)

}以上這種方式為在滴答中斷中計時,在main函式中執行,另外還有一種方式針對無阻塞並對時間有要求的任務,即是把stimer_proc()與stimer_task()結合在一起實現,任務在滴答中斷中執行,切記定時任務不能阻塞滴答中斷。

nrf 軟體定時器

52810的軟體定時器建立在乙個rtc的基礎上,使用乙個rtc計時。rtc作為乙個發動機一直在跑。rtc以tick為單位進行中斷觸發,每增加乙個tick就來一次中斷,中斷到來之後就和佇列預期的tick值比較,如果一樣就執行時鐘handler。所有的時鐘都是按照壓入乙個鐘佇列內進行處理。當create...

設計軟體定時器

在mcu晶元內部,往往硬體定時器的數量是非常有限的,而實際工程中卻需要大量的定時器來輔助完成具體的功能,如果乙個函式占用乙個定時器,那麼顯然不夠用,怎麼辦?思路有2種 1 直接將開源嵌入式作業系統的軟體定時器搬來使用 2 自己設計軟體定時器 這裡我只介紹第二種方法,我們知道,硬體定時器是通過對系統時...

軟體定時器3

硬體的資源總是緊張的,用這些有限的資源去做更多的事情,這大概就是每個硬體工程師一直在計較的事情了吧。定時器應該是很常用的乙個功能了,很多地方都需要。然而硬定時器就那麼幾個。所以面對一些對時間精度要求沒那麼高的地方,軟定時器就很有用了。簡單描述 所謂軟定時器,不過借助硬定時器產生乙個累積計數值。然後以...