軟體定時器
在嵌入式開發中,定時器是及其常見的,但考慮到晶元外設資源有限,可以自己寫乙個軟體定時器,應用於對計時不是太嚴格的場合,比如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
硬體的資源總是緊張的,用這些有限的資源去做更多的事情,這大概就是每個硬體工程師一直在計較的事情了吧。定時器應該是很常用的乙個功能了,很多地方都需要。然而硬定時器就那麼幾個。所以面對一些對時間精度要求沒那麼高的地方,軟定時器就很有用了。簡單描述 所謂軟定時器,不過借助硬定時器產生乙個累積計數值。然後以...