01
掃描周期與時鐘節(jié)拍
一般小型系統(tǒng)由Background和Foreground構(gòu)成。Background稱為任務(wù)區(qū),F(xiàn)oreground稱為中斷區(qū)。對實時性要求很高的操作要由中斷區(qū)的中斷服務(wù)程序來完成。位于Background區(qū)域的任務(wù)響應時間取決于超級循環(huán)(Super-Loops)執(zhí)行一次的時間,也稱之為掃描周期ScanCycleTime。掃描周期并不固定,任務(wù)執(zhí)行過程中掃描周期的最大值意味著任務(wù)最壞的響應時間。
microLite裸機系統(tǒng)最小的時間單位是時鐘節(jié)拍(Tick),時鐘節(jié)拍是特定的周期性中斷,這個中斷可以看做是系統(tǒng)心跳,時鐘節(jié)拍由硬件定時器產(chǎn)生,當中斷到來時,將調(diào)用一次ml_tick_increase()。不同硬件定時器的中斷實現(xiàn)不同,下面的中斷函數(shù)以 STM32 定時器作為示例:
void SysTick_Handler(void)
{
ml_tick_increase();
}
在中斷函數(shù)中調(diào)用 ml_tick_increase()對全局變量 ml_tick 進行自加,代碼如下:
void ml_tick_increase(void)
{
ml_tick++;
}
通過調(diào)用 ml_tick_get會返回當前 ml_tick 的值,即可以獲取到當前的時鐘節(jié)拍值。此接口可用于獲取系統(tǒng)的最大掃描周期,或者測量某任務(wù)運行的時間。接口函數(shù)如下:
ml_tick_t ml_tick_get(void)
{
ml_tick_t t = 0;
t = ml_tick;
while (t != ml_tick) {
t = ml_tick;
}
return t;
}
02
microLite_timer介紹
軟件定時器microLite_timer提供兩類定時器機制:
- 第一類是周期觸發(fā)定時器(MLPeriod),這類定時器會周期性的觸發(fā)定時器,并且“一旦啟動,永不停止”。
- 第二類是單次觸發(fā)定時器(MLShot),這類定時器在啟動后只會觸發(fā)一次定時器事件,然后定時器自動停止。
03
應用場景
周期觸發(fā)定時器(MLPeriod),適用于對首次觸發(fā)時間要求不嚴格的場合。比如,讓LED以280ms周期性亮滅。這種情況下我們并不關(guān)心LED首次由滅到亮用了多長時間,我們只要求LED在以后的時間以準確的280ms周期性亮滅。
單次觸發(fā)定時器(MLShot),適用于對首次觸發(fā)時間要求嚴格的場合。另外MLshot定時器自動停止后,調(diào)用啟動函數(shù)MLShot.start,亦可實現(xiàn)周期觸發(fā)。
04
API接口
microLite_timer支持的MLPeriod接口主要包括:
- MLPeriod.Init,初始化定時器;
- MLPeriod.run;
- MLPeriod.check,檢查定時器是否超時。
microLite_timer支持的MLShot接口主要包括:
- MLShot.start,啟動定時器;
- MLShot.stop,停止定時器;
- MLShot.check,檢查定時器是否超時。
05.1
MLPeriod編程范例
需求:讓4個任務(wù)分別以1000ms、500ms、500ms、800ms周期性執(zhí)行。
代碼實現(xiàn):
#include "microLite_timer.h"
#include "stdio.h"
void test1(void)
{
MLPeriod.init();
printf("microLite - Bare metal system, 2021 Copyright by stevenLyanrnrn");
printf("microLite timer sample, current tick is %d rn", ml_tick_get());
while (1) {
MLPeriod.run();
if (MLPeriod.check(1000)) {
printf("task1, current tick is %drn", ml_tick_get());
}
if (MLPeriod.check(500)) {
printf("task2, current tick is %drn", ml_tick_get());
}
if (MLPeriod.check(500)) {
printf("task3, current tick is %drn", ml_tick_get());
}
if (MLPeriod.check(800)) {
printf("task4, current tick is %drn", ml_tick_get());
}
}
}
運行效果:
microLite - Bare metal system, 2021 Copyright by stevenLyan
microLite timer sample, current tick is 9
task2, current tick is 513
task3, current tick is 515
task4, current tick is 813
task1, current tick is 1013
task2, current tick is 1015
task3, current tick is 1018
task2, current tick is 1513
task3, current tick is 1515
task4, current tick is 1613
task1, current tick is 2013
task2, current tick is 2015
task3, current tick is 2018
task4, current tick is 2413
05.2
MLShot編程范例
需求:見下面“代碼實現(xiàn)”的注釋。
代碼實現(xiàn):
#include "microLite_timer.h"
#include "stdio.h"
static ml_shotTimer_TypeDef test2_timer1 = {0};
static ml_shotTimer_TypeDef test2_timer2 = {0};
static ml_shotTimer_TypeDef test2_timer3 = {0};
void test2(void)
{
printf("microLite - Bare metal system, 2021 Copyright by stevenLyanrnrn");
printf("microLite timer sample, current tick is %d rn", ml_tick_get());
MLShot.start(&test2_timer1, 800);
MLShot.start(&test2_timer2, 500);
while (1) {
/*----------------------------------------------------------------------------*/
/* Schedules the specified task for execution after the specified delay.
[the specified delay]: [timer1]800 ticks */
if (MLShot.check(&test2_timer1)) {
printf("timer1 stop(auto), current tick is %d!!!rn", ml_tick_get());
}
/*----------------------------------------------------------------------------*/
/* Schedules the specified task for repeated fixed-delay execution, beginning
after the specified delay.
[the specified delay]: [timer2]500 ticks
[repeated fixed-delay]: [timer3]1000 ticks
*/
if (MLShot.check(&test2_timer2)) {
MLShot.start(&test2_timer3, 1000);
printf("timer2 stop(auto) and timer3 start, current tick is %d!!!rn", ml_tick_get());
}
if (MLShot.check(&test2_timer3)) {
MLShot.start(&test2_timer3, 1000);
printf("timer3 timeout, current tick is %drn", ml_tick_get());
}
}
}
運行效果:
microLite - Bare metal system, 2021 Copyright by stevenLyan
microLite - Bare metal system, 2021 Copyright by stevenLyan
microLite timer sample, current tick is 9
timer2 stop(auto) and timer3 start, current tick is 513!!!
timer1 stop(auto), current tick is 813!!!
timer3 timeout, current tick is 1514
timer3 timeout, current tick is 2515
timer3 timeout, current tick is 3516
timer3 timeout, current tick is 4517
06
注意事項
- MLPeriod.run在一個掃描周期內(nèi),應被調(diào)用一次且僅一次;
- 不建議將MLPeriod.check的參數(shù)設(shè)置為不固定值;
- 不建議嵌套使用MLPeriod.check;
- MLPeriod支持定時周期不同的定時器的個數(shù)為ML_PERIODTIMER_MAX;
- MLShot觸發(fā)后,定時器自動停止;
- microLite_timer的定時精度由系統(tǒng)Tick時鐘的周期以及掃描周期決定。
-
led燈
+關(guān)注
關(guān)注
22文章
1593瀏覽量
109313 -
軟件定時器
+關(guān)注
關(guān)注
0文章
18瀏覽量
6896 -
觸發(fā)器
+關(guān)注
關(guān)注
14文章
2031瀏覽量
61845 -
stm32定時器
+關(guān)注
關(guān)注
0文章
13瀏覽量
2394
發(fā)布評論請先 登錄
GD32對Timer定時器原理的詳細講解

為什么選擇esp_timer定時器作為esp32首選軟件定時器呢
通用定時器(Timer)
通用定時器(Timer)總體特性的功能概述和詳細的程序概述

ESP32 之 ESP-IDF 教學(三)——通用硬件定時器(Timer)

msp432快速入門第十節(jié)之timer32定時器

評論