개발자/Arduino

nano 33 iot 1초 타이머 작동 - delay 사용 금지

지구빵집 2023. 10. 13. 11:37
반응형

 

 

타이머를 작동하여 1초 마다 작동하는 코드

빠진 건 없겠지

 

간단하게 설명하면 

 

1. 맨 위 변수 sampling rate를 준다. 단위는 milisecond, 이 시간으로 인터럽트를 발생한다. 여기서는 1000ms, 즉 1초마다 인터럽트가 발생하도록 설정하였다.

 

2. 타이머 인터럽트에서 사용할 변수를 선언한다. 여기서는 1초마다 증가하는 타임 틱 변수와 300초(5분)를 확인할 수 있는 변수를 주었다. 이 변수는 타이머 인터럽트 함수에서 함께 증가시켜준다.

 

3. delay 쓰지 않고 메인에서 시간 체크만 하면서 정해진 시간마다 일정한 동작을 실행한다.

 

4. TC5_Handler 이하 타이머 관련 함수들이다. 설명은 시간상 생략한다. 그대로 가져다 쓰면 잘 동작한다.

 

 

#include <SPI.h>

//define timer sampling rate 1000=1sec
uint32_t sampleRate = 1000; //sample rate in milliseconds, determines how often TC5_Handler is called

//time variable
uint32_t time_tick_onesecond=0;
uint32_t flag_300seconds = 0;


void setup() {

//setup Timer
    tcConfigure(sampleRate); //configure the timer to run at <sampleRate>Hertz
    tcStartCounter(); //starts the timer
}

void loop() {       

    if(flag_300seconds > 300) //every 5minute send
    {
        //execute - call function
        flag_300seconds = 0;     
    }

}


//Here Start Timer function
//this function gets called by the interrupt at <sampleRate>Hertz

void TC5_Handler (void) {
  //YOUR CODE HERE  
  time_tick_onesecond++;
  flag_300seconds++;

  Serial.println(time_tick_onesecond);
  
  // END OF YOUR CODE
  TC5->COUNT16.INTFLAG.bit.MC0 = 1; //Writing a 1 to INTFLAG.bit.MC0 clears the interrupt so that it will run again
}


/* 
 *  TIMER SPECIFIC FUNCTIONS FOLLOW
 *  you shouldn't change these unless you know what you're doing
 */

//Configures the TC to generate output events at the sample frequency.
//Configures the TC in Frequency Generation mode, with an event output once
//each time the audio sample frequency period expires.
 void tcConfigure(int sampleRate)
{
 // select the generic clock generator used as source to the generic clock multiplexer
 GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)) ;
 while (GCLK->STATUS.bit.SYNCBUSY);

 tcReset(); //reset TC5

 // Set Timer counter 5 Mode to 16 bits, it will become a 16bit counter ('mode1' in the datasheet)
 TC5->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;
 // Set TC5 waveform generation mode to 'match frequency'
 TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;
 //set prescaler
 //the clock normally counts at the GCLK_TC frequency, but we can set it to divide that frequency to slow it down
 //you can use different prescaler divisons here like TC_CTRLA_PRESCALER_DIV1 to get a different range
 TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1024 | TC_CTRLA_ENABLE; //it will divide GCLK_TC frequency by 1024
 //set the compare-capture register. 
 //The counter will count up to this value (it's a 16bit counter so we use uint16_t)
 //this is how we fine-tune the frequency, make it count to a lower or higher value
 //system clock should be 1MHz (8MHz/8) at Reset by default
 TC5->COUNT16.CC[0].reg = (uint16_t) (SystemCoreClock / sampleRate);
 while (tcIsSyncing());
 
 // Configure interrupt request
 NVIC_DisableIRQ(TC5_IRQn);
 NVIC_ClearPendingIRQ(TC5_IRQn);
 NVIC_SetPriority(TC5_IRQn, 0);
 NVIC_EnableIRQ(TC5_IRQn);

 // Enable the TC5 interrupt request
 TC5->COUNT16.INTENSET.bit.MC0 = 1;
 while (tcIsSyncing()); //wait until TC5 is done syncing 
} 

//Function that is used to check if TC5 is done syncing
//returns true when it is done syncing
bool tcIsSyncing()
{
  return TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY;
}

//This function enables TC5 and waits for it to be ready
void tcStartCounter()
{
  TC5->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE; //set the CTRLA register
  while (tcIsSyncing()); //wait until snyc'd
}

//Reset TC5 
void tcReset()
{
  TC5->COUNT16.CTRLA.reg = TC_CTRLA_SWRST;
  while (tcIsSyncing());
  while (TC5->COUNT16.CTRLA.bit.SWRST);
}

//disable TC5
void tcDisable()
{
  TC5->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
  while (tcIsSyncing());
}
// end of code.

 

 

반응형