帖子來自芯片之家公眾號。
作為一個搞電子嵌入式的你來說,定時器相信絕對不會陌生,去翻看STM32的官方數據手冊,可能有四分之一的篇幅都在講定時器,可見定時器的重要性,定時器定時器嘛,最重要的功能還是定時。之前經常有師弟跟我抱怨,哎呀,這個單片機怎么只有2個定時器,我都不夠用了,怎么辦呀,然后一頭霧水,其實,只要有一個硬件定時器,在實際不是要求特別特別精準的場合,我們可以模擬很多個軟件定時器出來,今天,群主給大家分享一個完全由C語言編寫,高度可移植,超級牛逼的軟件定時器!
MultiTimer 是一個軟件定時器擴展模塊,可無限擴展你所需的定時器任務,取代傳統的標志位判斷方式, 更優雅更便捷地管理程序的時間觸發時序。一共有3個文件: multi_timer.c--定時器c源文件;
multi_timer.h--定時器h頭文件;
main--用戶代碼文件。
我們直接上代碼:
- /*
- * main.c
- *
- * Created on: 20161229
- * @Author : 曉宇
- * @version :V1.0.0
- *
- * ,%%%%%%%%,
- * ,%%/\%%%%/\%%
- * ,%%%\c''''J/%%%
- * %. %%%%/ o o \%%%
- * `%%. %%%% |%%%
- * `%% `%%%%(__Y__)%%'
- * // ;%%%%`\-/%%%'
- * (( / `%%%%%%%'
- * \\ .' |
- * \\ / \ | |
- * \\/ ) | |
- * \ /_ | |__
- * (____________))))))) 攻城獅
- *
- */
- #include "multi_timer.h"
- struct Timer timer1;
- struct Timer timer2;
- void timer1_callback()
- {
- printf("timer1 timeout!\r\n");
- }
- void timer2_callback()
- {
- printf("timer2 timeout!\r\n");
- }
- int main()
- {
- timer_init(&timer1, timer1_callback, 1000, 1000); //1s loop
- timer_start(&timer1);
- timer_init(&timer2, timer2_callback, 50, 0); //50ms delay
- timer_start(&timer2);
- while(1) {
-
- timer_loop();
- }
- }
- void HAL_SYSTICK_Callback(void)
- {
- timer_ticks(); //1ms ticks
- }
復制代碼
1、先申請一個定時器管理handle
2、初始化定時器對象,注冊定時器回調處理函數,設置定時時間(ms),循環定時觸發時間
- timer_init(struct Timer* handle, void(*timeout_cb)(), uint32_t timeout, uint32_t repeat);
復制代碼
3.啟動定時器
4.設置1ms的硬件定時器循環調用 *timer_ticks()* 以提供時間基準
- void HAL_SYSTICK_Callback(void)
- {
- timer_ticks();
- }
復制代碼
5.在主循環調用定時器后臺處理函數
- int main()
- { ...
- while(1) {
- ...
- timer_loop();
- }
- }
復制代碼
上面,我們定義了兩個定時器,第一個以每1秒一次進行循環執行,第二個定時器50ms之后只執行一次,執行之后,可以通過相應的回調函數打印出來,里面就可以添加我們的定時任務了。怎么樣,是不是很簡單,只需要設置好定時基準,申請好定時器,初始化完畢,你想要的效果,是定時一次還是進行循環,都沒問題,多個定時器之間使用鏈表來實現,可以啟動暫停每個定時器,用起來之后,是不是很爽?具體的代碼,需要大家仔細去推敲其中的原理,當然直接用也是可以的。
部分源代碼展示: - /*
- * multi_timer.h
- *
- * Created on: 20161229
- * @Author : 曉宇
- * @version :V1.0.0
- */
- #ifndef _MULTI_TIMER_H_
- #define _MULTI_TIMER_H_
- #include "stdint.h"
- typedef struct Timer {
- uint32_t timeout;
- uint32_t repeat;
- void (*timeout_cb)(void);
- struct Timer* next;
- }Timer;
- #ifdef __cplusplus
- extern "C" {
- #endif
- void timer_init(struct Timer* handle, void(*timeout_cb)(), uint32_t timeout, uint32_t repeat);
- int timer_start(struct Timer* handle);
- void timer_stop(struct Timer* handle);
- void timer_ticks(void);
- void timer_loop(void);
- // void timer_again(struct Timer* handle);
- // void timer_set_repeat(struct Timer* handle, uint32_t repeat);
- #ifdef __cplusplus
- }
- #endif
- #endif/*
- * multi_timer.c
- *
- * Created on: 20161229
- * @Author : 曉宇
- * @version :V1.0.0
- */
- #include "multi_timer.h"
- //timer handle list head.
- static struct Timer* head_handle = NULL;
- //Timer ticks
- static uint32_t _timer_ticks = 0;
- /**
- * @brief Initializes the timer struct handle.
- * @param handle: the timer handle strcut.
- * @param timeout_cb: timeout callback.
- * @param repeat: repeat interval time.
- * @retval None
- */
- void timer_init(struct Timer* handle, void(*timeout_cb)(), uint32_t timeout, uint32_t repeat)
- {
- // memset(handle, sizeof(struct Timer), 0);
- handle->timeout_cb = timeout_cb;
- handle->timeout = _timer_ticks + timeout;
- handle->repeat = repeat;
- }
- /**
- * @brief Start the timer work, add the handle into work list.
- * @param btn: target handle strcut.
- * @retval 0: succeed. -1: already exist.
- */
- int timer_start(struct Timer* handle)
- {
- struct Timer* target = head_handle;
- while(target) {
- if(target == handle) return -1; //already exist.
- target = target->next;
- }
- handle->next = head_handle;
- head_handle = handle;
- return 0;
- }
- /**
- * @brief Stop the timer work, remove the handle off work list.
- * @param handle: target handle strcut.
- * @retval None
- */
- void timer_stop(struct Timer* handle)
- {
- struct Timer** curr;
- for(curr = &head_handle; *curr; ) {
- struct Timer* entry = *curr;
- if (entry == handle) {
- *curr = entry->next;
- // free(entry);
- } else
- curr = &entry->next;
- }
- }
- /**
- * @brief main loop.
- * @param None.
- * @retval None
- */
- void timer_loop()
- {
- struct Timer* target;
- for(target=head_handle; target; target=target->next) {
- if(_timer_ticks >= target->timeout) {
- if(target->repeat == 0) {
- timer_stop(target);
- } else {
- target->timeout = _timer_ticks + target->repeat;
- }
- target->timeout_cb();
- }
- }
- }
- /**
- * @brief background ticks, timer repeat invoking interval 1ms.
- * @param None.
- * @retval None.
- */
- void timer_ticks()
- {
- _timer_ticks++;
- }
復制代碼
全部資料51hei下載地址:
MultiTimer.zip
(2.26 KB, 下載次數: 47)
2019-9-14 20:02 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|