Go Down

Topic: Timing - Increment every .5us (Read 743 times) previous topic - next topic

acetech09

Hey everyone. I'm upgrading a project from an Uno to a Zero and it went smoothly. However, there's a part in the code that references 328P timer registers:

Code: [Select]

TCCR1A = 0;  //reset timer1
TCCR1B = 0;
TCCR1B |= (1 << CS11);  //set timer1 to increment every 0,5 us


I'm not much of a programmer and have mostly stumbled through the code in this project, but this part I think I understand. I just can't find an analogue to this for the new core.

Regardless of the background, I'm simply trying to find a way of either incrementing a register or variable every .5us.

Thanks

AloyseTech

#1
Jul 07, 2016, 08:55 am Last Edit: Jul 07, 2016, 01:07 pm by AloyseTech
Hi,

You can try this code that use Timer Counter 5 to generate interrupt every 5┬Ás :

Code: [Select]
void configureTimer5()
{
// clock the timer with the core cpu clock (48MHz)
GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)) ;
while(GCLK->STATUS.bit.SYNCBUSY);

// Reset the TC
TC5->COUNT16.CTRLA.reg = TC_CTRLA_SWRST;
while(TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY);
while(TC5->COUNT16.CTRLA.bit.SWRST);

// Set Timer counter Mode to 16 bits
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_MODE_COUNT16;

// Set TC5 mode as match frequency
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_WAVEGEN_MFRQ;

TC5->COUNT16.CTRLA.reg |= TC_CTRLA_PRESCALER_DIV1 | TC_CTRLA_ENABLE;

TC5->COUNT16.CC[0].reg = (uint16_t) 239; //0.5us = 240 clock cycle at 48MHz (core clock)
while(TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY);

// Configure interrupt request
NVIC_DisableIRQ(TC5_IRQn);
NVIC_ClearPendingIRQ(TC5_IRQn);
NVIC_SetPriority(TC5_IRQn, 0); //you can change priority between 0 (Highest priority) and 2 (lowest)
NVIC_EnableIRQ(TC5_IRQn);

// Enable the TC5 interrupt request
TC5->COUNT16.INTENSET.bit.MC0 = 1;
while(TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY);

//enable the counter (from now your getting interrupt)
TC5->COUNT16.CTRLA.reg |= TC_CTRLA_ENABLE;
while(TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY);

//use this to disable the counter :
//TC5->COUNT16.CTRLA.reg &= ~TC_CTRLA_ENABLE;
//while(TC5->COUNT16.STATUS.reg & TC_STATUS_SYNCBUSY);
}

volatile uint32_t myCounter = 0;
void TC5_Handler (void)
{
//do your stuff here
myCounter++;


    // Clear the interrupt
    TC5->COUNT16.INTFLAG.bit.MC0 = 1;
}


if you only need the counter value and nothing else, I think you can do something like this :
TC5->COUNT16.COUNT.reg
...and deactivate the interrupt.

Go Up