이때 주의할 사항은 PWM과 사용하는 타이머가 겹칠수 있으므로 반드시 실험해서 잘 작동하나 확인해야 함.

 

좋은 설명 : https://youtu.be/LONGI_JcwEQ

샘플 코드. 출처 : techtutorialsx.com/2017/10/07/esp32-arduino-timer-interrupts/

volatile int interruptCounter;
int totalInterruptCounter;
 
hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;
 
void IRAM_ATTR onTimer() {
  portENTER_CRITICAL_ISR(&timerMux);
  interruptCounter++;
  portEXIT_CRITICAL_ISR(&timerMux);
 
}
 
void setup() {
 
  Serial.begin(115200);
 
  timer = timerBegin(0, 80, true);
  timerAttachInterrupt(timer, &onTimer, true);
  timerAlarmWrite(timer, 1000000, true);
  timerAlarmEnable(timer);
 
}
 
void loop() {
 
  if (interruptCounter > 0) {
 
    portENTER_CRITICAL(&timerMux);
    interruptCounter--;
    portEXIT_CRITICAL(&timerMux);
 
    totalInterruptCounter++;
 
    Serial.print("An interrupt as occurred. Total number: ");
    Serial.println(totalInterruptCounter);
 
  }
}

============================================================================

ESP32 하드웨어 타이머 관련 기본 지식 :

  2 그룹의 2개씩의 64비트 하드웨어 타이머 (총 4개, 0 ~ 3)

   16 bit prescaler (2 ~ 2^16 사이의 값)

 

   ESP32는 80 Mhz짜리 수정(Crystal)을 사용하므로 (80,000,000 / prescaler) tics / sec 의 속도임.

   만약 80으로 나눠주면 80,000,000 / 80 = 1,000,000 tics / sec 이 됨.

 

   아두이노 코드에서 타이머를 사용하려면 다음과 같이 포인터를 만들어 주면 됨.

      hw_timer_t * timer = NULL;   // 포인터 설정.

 

   그 다음에는 타이머를 지정할 때 3개의 값을 주는데,

         1: 타이머 ID (0~3),

         2: 나눌 Prescaler 값,

         3: true (Rising Edge), false (Falling Edge) 

      timer = timerBegin(0, 80, true);  // 이건 타이머 0를 사용하고, 틱 80,000,000을 80으로 나누고, Rising Edge 사용.

 

  타이머를 Real Time용으로 만들기 위해서 아두이노 IDE에서는 다음과 같은 portMUX_TYPE 오브젝트를 사용함.

    portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

  

   타이머 함수를 만들어 줄 것. 

 

      (*) 타이머 함수를 만들때 주의사항.

        1. 코드가 아주 빨리 실행되는 일만 시킬 것.  (시리얼 통신같은 무거운 일 시키면 안됨)

        2. 각 코드는 고유의 타이머를 연결시킬 것.

        3. 타이머 함수에서 함수 외부 코드와 공유할 수 있는 변수는 반드시 (volatile)로 지정할 것.

           예 :  volatile  int  t0count;

        4. PWM 코드와 사용하는 타이머가 겹치는 지 반드시 확인할 것.

 

     코드 예 :

      void  IRAM_ATTR  onTimer() {

           portENTER_CRITICAL_ISR(&timerMux);

           t0count++;  // ... critical code executed in the RAM of the ESP32 

           portEXIT_CRITICAL_ISR(&timerMux);

      }

 

   타이머를 활성화(Enable) 시키기 전에 반드시 타이머 함수를 지정하고 연결시킬 것.

      timerAttachInterrupt(timer, &onTimer, true);

 

   그 다음에 알람용 (실제 시간마다 실행될 시간)을 지정함.

      timerAlarmWrite(timer, 1000000, true);    // 이전에 80으로 나눠서 1초에 백만 tic이 돌게 세팅된 상태에 

                                                                       // 백만 tic마다 실행하게 함.  그러므로 이 코드는 1초에 1번 작동함. 

 

   마지막에 타이머를 활성화(Enable) 시킴.

      timerAlarmEnable(timer);

 

 

 

 

+ Recent posts