在mcu晶元內部,往往硬體定時器的數量是非常有限的,而實際工程中卻需要大量的定時器來輔助完成具體的功能,如果乙個函式占用乙個定時器,那麼顯然不夠用,怎麼辦?
思路有2種:
1、直接將開源嵌入式作業系統的軟體定時器搬來使用
2、自己設計軟體定時器
這裡我只介紹第二種方法,我們知道,硬體定時器是通過對系統時鐘週期進行計數實現的,那麼軟體定時器也不例外,首先得要有時基,然後得計數以及清零或者重新裝載的動作。
那麼如何獲得時基呢?硬體定時器是直接有系統時鐘輸入給它們,但是軟體定時器則沒有,我們必須通過其他的方法獲得。有以下兩種方法獲得時基:
1、直接利用硬體定時器中斷作為時基,在硬體定時器中斷服務函式中完成對軟體定時器的計數。
2、在主函式迴圈中監視硬體定時器的數值,如果數值達到預定值之後軟體定時器就計數。
上面第一種是比較精確的,畢竟中斷服務函式總是如期到來,時基差不多是如下這種情況:
但是第二種方法就沒那麼好了,比如受到任務執行的阻塞,也許硬體定時器早已到達預設數值,軟體定時器還沒有檢測到,這種情況相當於輸入到軟體定時器的波形為占空比不斷變化的時鐘,而且硬體定時器的開關以及計數值裝載還要通過軟體去控制,顯然這種方法設計的軟體定時器只適合用在對精度要求非常低的情景下,比如按鍵掃瞄。
基於上面兩種獲取時基方式利弊的考慮,我們採用硬體定時器中斷的方式獲取軟體定時器的時基。於是基本思路就很清晰了,在中斷服務函式中不斷的對軟體定時器進行計數,函式再利用軟體定時器是否達到預設值來決定是執行還是阻塞。首先我們設計乙個結構體,這個結構體包含了四個成員:
typedef struct _softtimer
softtimer;
bisactivate,該成員用於描述該定時器是否被啟用,啟用就為ture,沒有啟用則為false。
uscount,該成員用於在定時器中斷服務函式中計數
timervalue,該成員用於表示軟體定時器的計數最大值
bistimeout,該成員用於表示軟體定時器是否到達預設計數值,以作為外部函式是否執行的依據
下面定義若干個軟體定時器:
#define softtimer_mxanum 5
volatile softtimer stsofttimergroup[softtimer_mxanum];
下面設計乙個函式用於對軟體定時器進行計數,該函式被定時器中斷服務函式執行。如下所示:
void softtimerrunning(void)}}
}
該函式很簡單,基本思路就是首先判斷某定時器是否被啟用,如果被啟用則對該定時器進行計數,計數值到預設值則清零並且設定時間到標誌。
而定時器的啟用則是由外部函式完成的,當外部定時器需要使用某軟體定時器的時候就將該軟體定時器啟用,並將預設計數值傳給它,啟用後軟體定時器就開始計數,之後就檢測該定時器是否到達預設值。**如下:
bool settimerout(uint8_t *funid,uint16_t prevalue)
{ uint8_t i;
for(i=0;i先判斷某定時器是否被占用(即是否已經啟用),如果被占用則查詢下乙個定時器,直到找到沒有被占用的定時器並將預設值傳給它,然後返回該定時器的id號,如果沒有找到可用定時器則返回false。
未完待續。。。
nrf 軟體定時器
52810的軟體定時器建立在乙個rtc的基礎上,使用乙個rtc計時。rtc作為乙個發動機一直在跑。rtc以tick為單位進行中斷觸發,每增加乙個tick就來一次中斷,中斷到來之後就和佇列預期的tick值比較,如果一樣就執行時鐘handler。所有的時鐘都是按照壓入乙個鐘佇列內進行處理。當create...
簡單軟體定時器
軟體定時器 在嵌入式開發中,定時器是及其常見的,但考慮到晶元外設資源有限,可以自己寫乙個軟體定時器,應用於對計時不是太嚴格的場合,比如led的閃爍,定時處理某一任務等等。該軟體定時器的原理是基於滴答系統時鐘中斷,在中斷中獲得時間基,該時間基可由使用者自由設定。另外有兩種方式可以實現軟體定時處理功能,...
軟體定時器3
硬體的資源總是緊張的,用這些有限的資源去做更多的事情,這大概就是每個硬體工程師一直在計較的事情了吧。定時器應該是很常用的乙個功能了,很多地方都需要。然而硬定時器就那麼幾個。所以面對一些對時間精度要求沒那麼高的地方,軟定時器就很有用了。簡單描述 所謂軟定時器,不過借助硬定時器產生乙個累積計數值。然後以...