ESP系列跟Arduino UNO(AVR系列)在TIMER(計時器)上有一個很大的差別在於它有兩個獨立的計時器,最多可以同時四個

可以不用像在UNO上用類似於分割的方式來做計時的功用,

下面是一個簡單的範例我建立了兩個TIMER,週期分別為0.5s跟1s的計時器來做定時中斷

裡面的變數為A及B,另外再用一個變數C一樣是做+1的動作,只是用最一般的方式做,然後delay500

所以我們可以堆測A跟C的累加速度一樣,B的累加速度是他們的一半

推測會看到的結果會像下面這樣

A: 6

B: 3

C: 6

 

 

程式碼:

portMUX_TYPE mux0 = portMUX_INITIALIZER_UNLOCKED;
portMUX_TYPE mux1 = portMUX_INITIALIZER_UNLOCKED;
volatile bool state = LOW;
hw_timer_t * timer0;   // 宣告硬體計時器物件指標
hw_timer_t * timer1;   // 宣告硬體計時器物件指標

int A = 0;
int B = 0;
int C = 0;

void IRAM_ATTR onTimer0()
{  // 計時器0中斷服務常式 不能SERIAL
  portENTER_CRITICAL(&mux0); //要鎖住記憶體區塊,不然跑一跑就爆掉了
 
    A = A + 1;
 
  portEXIT_CRITICAL(&mux0); //要鎖住記憶體區塊,不然跑一跑就爆掉了
}
void IRAM_ATTR onTimer1()
{  // 計時器1中斷服務常式 不能SERIAL
  portENTER_CRITICAL(&mux1);  //要鎖住記憶體區塊,不然跑一跑就爆掉了
 
  
    B = B + 1;
  
  portEXIT_CRITICAL(&mux1);  //要鎖住記憶體區塊,不然跑一跑就爆掉了
}

void setup() {  
  // 使用硬體計時器0建立0.5秒週期的計時器。
  timer0 = timerBegin(0, 80, true);
  timerAttachInterrupt(timer0, &onTimer0, true);
  timerAlarmWrite(timer0, 1000000/2, true);//0.5S
  timerAlarmEnable(timer0);
  // 使用硬體計時器1建立1秒週期的計時器。
  timer1 = timerBegin(1, 80, true);
  timerAttachInterrupt(timer1, &onTimer1, true);
  timerAlarmWrite(timer1, 1000000, true);//1S
  timerAlarmEnable(timer1);

  Serial.begin(115200);
}

void loop() 

  
  Serial.print("A:");
  Serial.println(A);
  Serial.print("B:");
  Serial.println(B);
  Serial.print("C:");
  Serial.println(C);
  C = C+1 ;
  delay(500);
}

  

下圖為實際執行所看到的結果,證明前面的推論是正確的

image

arrow
arrow
    創作者介紹
    創作者 凶王 的頭像
    凶王

    凶王的部落

    凶王 發表在 痞客邦 留言(1) 人氣()