之前曾提過ROSA 的時間系統,今天解析時間如何精確計數,
// (C) 2015, Bridan Wang, CC BY-NC-SA 3.0 TW
// http://4rdp.blogspot.tw/search/label/ROSA%20(Arduino)
//
unsigned long now;
void SYS_TIMER() {
static byte tm_10ms = 0;
static byte tm_100ms = 0;
static byte tm_1sec = 0;
while (millis() - now >= 10) {
now += 10;
tm_10ms++;
tm_100ms++;
tm_1sec++;
}
if (tm_1sec >= 100) {
tm_1sec -= 100;
PROCESS_1sec();
}
if (tm_100ms >= 10) {
tm_100ms -= 10;
PROCESS_100ms();
}
if (tm_10ms != 0) {
tm_10ms -= 1;
PROCESS_10ms();
}
}
void PROCESS_1sec(){
static byte led = 0;
//Serial.println(now);
led = 1 - led;
digitalWrite(13, led);
}
void PROCESS_100ms(){
}
void PROCESS_10ms(){
}
void setup() {
// system timer0
now = millis();
}
void loop() {
SYS_TIMER(); // work on timer0
}
Arduino 有一個 millis() API 可以提供精準系統時間,時間的最小解析度為 1 ms,連續計時約 50 天會重置為零, 1000 ms X 60 sec X 60 min X 24 hr X 50 day ~ 2^32 ms,ROSA 目前設計到一天 24 小時,對普通玩具足已。
SYS_TIMER() 是自行設計的 API,主要計時產出三個關鍵時間:10 ms、100 ms、1 sec,因為單晶片內部程式執行非常快速,為了能在特定時間執行特定程式,因此用這方法區分,為什麼要這樣區分?像是按鍵之類的判別,每秒鐘能讀取 20 次以上就很夠,超音波或循跡每 100 ms 一次就 OK,鬧鐘定時每秒檢查一次即可。
在變數 tm_10ms、tm_100ms、tm_1sec 為了避免程式執行完,出去再回來後,原來數值會被清掉,所以加了 static 以保留數值,這相當於把變數用 global 方式宣告。
另外避免某些程式加入 delay(),使 SYS_TIMER() 失準,因此採計數方式,可以確保不會「落溝」。
在 PROCESS_1sec()例子中,pin 13 放置一個 LED 閃爍程式,亮一秒滅一秒。
在 PROCESS_1sec()例子中,pin 13 放置一個 LED 閃爍程式,亮一秒滅一秒。
沒有留言:
張貼留言