//타이머인터럽트를 이용하면 주기적인 연산(일정한 sampling time이 필요할 때)을 처리할 때 편하다.
//이 스케치에서는 dt주기로 타이머 인터럽트를 설정하고 그때마다 led를 on off제어 한다.
//출력은 PB27번, DUE보드의 13번 핀이다.
float dt =0.2; //sampling time. 이것이 인터럽트 발생의 주기가 됨.
//함수 프로토타입 선언
void confugure_pio();
void configure_timer_counter();
void confugure_pio()//pio의 환경설정
{
pmc_enable_periph_clk(ID_PIOB);//PIOB를 사용하려면 PIOB로 가는 CLOCK을 활성화해야함.
PIOB->PIO_PER = PIO_PB27;//PB27의 PIO기능을 ENABLE함
PIOB->PIO_IDR = PIO_PB27;//PB27의 INTERRUPT DISABLE
PIOB->PIO_OER = PIO_PB27;//PB27을 I/O라인의 OUTPUT으로 설정함.
}
//TC0을 사용하자. 타이머카운터 0번의 0번 채널
//타이머 인터럽트를 사용하도록 설정하자.
//타이머 인터럽트의 주기는 dt에 정의하면 매 dt의 시간마다 led를 on off하게 한다.
//dt가 0.1이므로 인터럽트의 주기가 0.1초이며 10hz이다.
void configure_timer_counter()타이머 카운터의 환경설정
{
pmc_set_writeprotect(false);//write protection기능을 꺼둠
pmc_enable_periph_clk(ID_TC3);//peripheral clock을 enable시킴.
//TC_CMR를 환경설정하자.
//wavemode, upmode with automatic trigger on RC compare, TIMER CLOCK 1(MCK/2)로 환경설정됨.
TC1->TC_CHANNEL[0].TC_CMR=(TC_CMR_WAVE) | (TC_CMR_WAVSEL_UP_RC) | (TC_CMR_TCCLKS_TIMER_CLOCK1);
//CMR : Channel Mode Register // 15th bit | 14th bit | 0th bit
//14번 비트는 CPCTRG로, 1로 SET될 경우, RC compare resets the counter and starts the counter clock
//Register C(RC) is set to the maximum count specified by the clock frequency divided by the desired frequency.
//RC contains the Register C value in real time.
uint32_t rc = (uint32_t)((VARIANT_MCK/2)*dt);
TC1->TC_CHANNEL[0].TC_RC = rc-1; // TOP값=registor RC설정(그냥 TC_RC=rc라고 해줘도 된다)
TC1->TC_CHANNEL[0].TC_RA = rc/2; // Middle값=registor RA설정
TC1->TC_CHANNEL[0].TC_IER = TC_IER_CPCS; //RC compare interrupter을 활성화시킴
//TC1->TC_CHANNEL[0].TC_IER = TC_IER_CPAS;
TC1->TC_CHANNEL[0].TC_IDR = ~TC_IER_CPCS; //RC compare interrupter을 제외한 interrupter을 disable시킨다. 근데 도대체 위에서 RA설정해 놓고 왜 다시 DISABLE시키는거지?
//TC1->TC_CHANNEL[0].TC_IDR = ~(TC_IER_CPCS | TC_IER_CPAS);
//And tell the Nested vector Interrupt Controller to enable our IRQ(interrupt requenst).//
//NVIC는 간단히 설명하면 INTERRUPT가 발생하여 MCU로 알려주면 CORE에서 INTERRUPT HANDLER를
//호출할지 , 무시할지, 혹은 어떤 순서로 호출할지 등을 결정하는 역할을 한다.
//흔히 우선순위가 높은 인터럽트를 호출하는 역할을 함.
NVIC_EnableIRQ(TC3_IRQn);
//counter을 reset하고(SWRG), Counter clock을 enable함(CLKEN)
TC1->TC_CHANNEL[0].TC_CCR=TC_CCR_CLKEN | TC_CCR_SWTRG; //counter 을 리셋 한 후 counter clock을 enable한다
}
void setup()
{
Serial.begin(115200);
void confugure_pio(); //PIO confuguration
configure_timer_counter(); //tiemr/counter confuguration
}
void loop()
{
}// do nothing
void TC3_Handler()//timer counter 의 service routine. TC1의 CHANNEL 0에 해당하는 TIEMR COUNTER INTERRUPT
{
static int flag=0;
unsigned int status;
status =TC1->TC_CHANNEL[0].TC_SR;// status 정보를 읽어 TC_SR을 0으로 CLEAR함.
if(flag==0)
{
PIOB->PIO_SODR=PIO_PB27;// LED ON
flag=1;
}
else
{
PIOB->PIO_CODR=PIO_PB27;//LED OFF
flag=0;
}
}
'Programming > Embedded' 카테고리의 다른 글
[Arduino Due]-basic ADC code (0) | 2022.02.19 |
---|---|
[Arduino Due]-basic PWM control code (0) | 2022.02.18 |
[Arduino Due]-basic pin change interrupt code (0) | 2022.02.18 |
[Arduino Due]-basic PIO control code (0) | 2022.02.18 |
간단한 센서값 필터링(filtering) 예제코드 (0) | 2022.02.18 |