Offline
Newbie
Karma: 0
Posts: 29
|
 |
« Reply #90 on: April 20, 2013, 03:08:15 pm » |
Using this code, you can set a timer for any of the ISRs TC0_Handler through TC8_Handler, see table of parameters below. It is possible to use the timers without a physically mapped pin, such as TC1 channel 0 (TC3_Handler) shown here: volatile boolean l;
//TC1 ch 0 void TC3_Handler() { TC_GetStatus(TC1, 0); digitalWrite(13, l = !l); }
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) { pmc_set_writeprotect(false); pmc_enable_periph_clk((uint32_t)irq); TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4); uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above TC_SetRA(tc, channel, rc/2); //50% high, 50% low TC_SetRC(tc, channel, rc); TC_Start(tc, channel); tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS; tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS; NVIC_EnableIRQ(irq); }
void setup(){ pinMode(13,OUTPUT); startTimer(TC1, 0, TC3_IRQn, 4); //TC1 channel 0, the IRQ for that channel and the desired frequency }
void loop(){ }
Here is the table of parameters: | ISR/IRQ | TC | Channel | Due pins | | TC0 | TC0 | 0 | 2, 13 | | TC1 | TC0 | 1 | 60, 61 | | TC2 | TC0 | 2 | 58 | | TC3 | TC1 | 0 | none <- this line in the example above | | TC4 | TC1 | 1 | none | | TC5 | TC1 | 2 | none | | TC6 | TC2 | 0 | 4, 5 | | TC7 | TC2 | 1 | 3, 10 | | TC8 | TC2 | 2 | 11, 12 |
Noob question here, could someone please explain the inputs to the startTimer function? What is channel, and how do we use the frequency input? Also, what are the pins in the table for? Can anyone kindly answer to the following question please? How can we disable the Timer by turning off the PWM? (Outside of Timer Function)
|
|
|
|
|
Logged
|
|
|
|
|
Brasil
Offline
Jr. Member
Karma: 3
Posts: 78
|
 |
« Reply #91 on: April 20, 2013, 03:12:08 pm » |
Using this code, you can set a timer for any of the ISRs TC0_Handler through TC8_Handler, see table of parameters below. It is possible to use the timers without a physically mapped pin, such as TC1 channel 0 (TC3_Handler) shown here: volatile boolean l;
//TC1 ch 0 void TC3_Handler() { TC_GetStatus(TC1, 0); digitalWrite(13, l = !l); }
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) { pmc_set_writeprotect(false); pmc_enable_periph_clk((uint32_t)irq); TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4); uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above TC_SetRA(tc, channel, rc/2); //50% high, 50% low TC_SetRC(tc, channel, rc); TC_Start(tc, channel); tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS; tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS; NVIC_EnableIRQ(irq); }
void setup(){ pinMode(13,OUTPUT); startTimer(TC1, 0, TC3_IRQn, 4); //TC1 channel 0, the IRQ for that channel and the desired frequency }
void loop(){ }
Here is the table of parameters: | ISR/IRQ | TC | Channel | Due pins | | TC0 | TC0 | 0 | 2, 13 | | TC1 | TC0 | 1 | 60, 61 | | TC2 | TC0 | 2 | 58 | | TC3 | TC1 | 0 | none <- this line in the example above | | TC4 | TC1 | 1 | none | | TC5 | TC1 | 2 | none | | TC6 | TC2 | 0 | 4, 5 | | TC7 | TC2 | 1 | 3, 10 | | TC8 | TC2 | 2 | 11, 12 |
Noob question here, could someone please explain the inputs to the startTimer function? What is channel, and how do we use the frequency input? Also, what are the pins in the table for? Can anyone kindly answer to the following question please? How can we disable the Timer by turning off the PWM? (Outside of Timer Function) Hi, If it's really needed to understand the code, i suggest you looking at the Datasheet, that is the best place to get those explanations since every uController is different. But, if you just want to use timers on arduino Due, install the DueTimer library: github.com/ivanseidel/DueTimer Regards, Ivan
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 2
|
 |
« Reply #92 on: April 20, 2013, 03:29:31 pm » |
Using this code, you can set a timer for any of the ISRs TC0_Handler through TC8_Handler, see table of parameters below. It is possible to use the timers without a physically mapped pin, such as TC1 channel 0 (TC3_Handler) shown here: volatile boolean l;
//TC1 ch 0 void TC3_Handler() { TC_GetStatus(TC1, 0); digitalWrite(13, l = !l); }
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) { pmc_set_writeprotect(false); pmc_enable_periph_clk((uint32_t)irq); TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4); uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above TC_SetRA(tc, channel, rc/2); //50% high, 50% low TC_SetRC(tc, channel, rc); TC_Start(tc, channel); tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS; tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS; NVIC_EnableIRQ(irq); }
void setup(){ pinMode(13,OUTPUT); startTimer(TC1, 0, TC3_IRQn, 4); //TC1 channel 0, the IRQ for that channel and the desired frequency }
void loop(){ }
Here is the table of parameters: | ISR/IRQ | TC | Channel | Due pins | | TC0 | TC0 | 0 | 2, 13 | | TC1 | TC0 | 1 | 60, 61 | | TC2 | TC0 | 2 | 58 | | TC3 | TC1 | 0 | none <- this line in the example above | | TC4 | TC1 | 1 | none | | TC5 | TC1 | 2 | none | | TC6 | TC2 | 0 | 4, 5 | | TC7 | TC2 | 1 | 3, 10 | | TC8 | TC2 | 2 | 11, 12 |
I'm a bit confused about the code for the startTimer function. -What is the purpose of TC3_Handler() and how does it interact with startTimer()? -Once startTimer() is called, how do I stop the timer(how do I disable PWM)? -There's a few lines that I don't understand in startTimer(): TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4); <--- How does TC_Configure() work? Where can I find reference about this? uint32_t rc = VARIANT_MCK/128/frequency; <---------- is VARIANT_MCK the frequency of arduino DUE(84MHz)? What does rc do? TC_SetRA(tc, channel, rc/2); //50% high, 50% low<----sets the duty cycle? TC_SetRC(tc, channel, rc);<---------- what is this line for? TC_Start(tc, channel);<---------------enables PWM? How does it work? tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;<----------What does this line do? tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;<--------What does this line do? NVIC_EnableIRQ(irq); <-----enables interrupt?
|
|
|
|
|
Logged
|
|
|
|
|
0
Offline
Full Member
Karma: 2
Posts: 109
ArduiYES!
|
 |
« Reply #93 on: April 21, 2013, 04:14:26 pm » |
StartTimer starts the timer. this function needs to be called once. after Starttimer is finished, the (hardware) timer keeps running on it's own, without any need for code. the timer counts up to a certain value, then generates an interrupt, starts with 0 and continues counting.
TC3_handler is called each time the interrupt of Timer/Counter TC3 (=timer 1 channel 0) is generated by the timer. "TC3_handler" is a pre-determined functionname just like "setup" and "loop" because TC3_handler is called for each interrupt, it is called as often as the timer hits that "certain value". The lower that value the more often the TC3_handler is executed.
TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4); Read the datasheet paragraph 37.7.11, fields WAVE, WAVSEL, TCCLKS. TC_configure just sets bits in the TC_CMR register that belongs to TC3 (= Timer 1 channel 0 ) uint32_t rc = VARIANT_MCK/128/frequency; <---------- is VARIANT_MCK the frequency of arduino DUE(84MHz)? What does rc do? Serial.Println(VARIANT_MCK,DEC) will enlighten. spoiler : yes rc is the value the timer counts towards. it is that "certain value" I mentioned above.
TC_SetRA(tc, channel, rc/2); //50% high, 50% low<----sets the duty cycle? yes, see datasheet 37.6.11.1, for instance. TC_SetRC(tc, channel, rc);<---------- what is this line for? it sets the value the timer counts towards. so it defines the frequency of the interrupts generated by the timer
TC_Start(tc, channel);<---------------enables PWM? How does it work? no, it starts the timer. the timer begins incrementing now.
tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;<----------What does this line do? I'm not sure but I think it sets the flag that specifies an interrupt is desired when timer = rc. IER = interrupt Enable Register
tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;<--------What does this line do? IDR = interrupt disable register, all other interrupt-types supported by TC3 are disabled and will not occur.
NVIC_EnableIRQ(irq); <-----enables interrupt? yes. it is the overall enabler, allowing interrupts to be generated by TC3.
|
|
|
|
« Last Edit: April 22, 2013, 04:04:51 pm by raalst »
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 29
|
 |
« Reply #94 on: April 24, 2013, 03:26:26 pm » |
Using this code, you can set a timer for any of the ISRs TC0_Handler through TC8_Handler, see table of parameters below. It is possible to use the timers without a physically mapped pin, such as TC1 channel 0 (TC3_Handler) shown here: volatile boolean l;
//TC1 ch 0 void TC3_Handler() { TC_GetStatus(TC1, 0); digitalWrite(13, l = !l); }
void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) { pmc_set_writeprotect(false); pmc_enable_periph_clk((uint32_t)irq); TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4); uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above TC_SetRA(tc, channel, rc/2); //50% high, 50% low TC_SetRC(tc, channel, rc); TC_Start(tc, channel); tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS; tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS; NVIC_EnableIRQ(irq); }
void setup(){ pinMode(13,OUTPUT); startTimer(TC1, 0, TC3_IRQn, 4); //TC1 channel 0, the IRQ for that channel and the desired frequency }
void loop(){ }
Here is the table of parameters: | ISR/IRQ | TC | Channel | Due pins | | TC0 | TC0 | 0 | 2, 13 | | TC1 | TC0 | 1 | 60, 61 | | TC2 | TC0 | 2 | 58 | | TC3 | TC1 | 0 | none <- this line in the example above | | TC4 | TC1 | 1 | none | | TC5 | TC1 | 2 | none | | TC6 | TC2 | 0 | 4, 5 | | TC7 | TC2 | 1 | 3, 10 | | TC8 | TC2 | 2 | 11, 12 |
Noob question here, could someone please explain the inputs to the startTimer function? What is channel, and how do we use the frequency input? Also, what are the pins in the table for? Guys! can anyone kindly explain me why this code does not work for the frequencies upper than 3 KHZ? I have tested 1Hz to 3000Hz for the frequency but seems further frequencies it has problem. What's the acceptable range of frequency? We did a loop as follows. void loop() { startTimer(TC1, 0, TC3_IRQn, 1); Serial.println("1Hz"); delay(5000); startTimer(TC1, 0, TC3_IRQn, 4000); // LIne 6 Serial.println("4KHz"); delay(3000); } This frequency is used to control the speed of motor. When we set the second frequency (Line 6 ) to 4000HZ it won't return to the 1HZ as it is supposed to. We tried 1 to 3KHZ and it works but more than 4KHZ it goes weird! Any solution please?
|
|
|
|
« Last Edit: April 24, 2013, 03:35:50 pm by henrimontreal »
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 2
|
 |
« Reply #95 on: May 06, 2013, 02:17:03 pm » |
I got frequency between 1-21KHz to work, but I found another problem. I can't get 2 timers to run simultaneously. I ran the startTimer function twice with different handlers, but they refuse to work. Anyone know how to fix this problem?
|
|
|
|
|
Logged
|
|
|
|
|
Brasil
Offline
Jr. Member
Karma: 3
Posts: 78
|
 |
« Reply #96 on: May 07, 2013, 01:28:34 pm » |
Try using my Library: https://github.com/ivanseidel/DueTimerIt has everything implemented, revised, and checked... (It's not PERFECT, but if you find any bugs, fell free to notify me!)
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 37
|
 |
« Reply #97 on: May 15, 2013, 07:04:50 am » |
Hi, I tried to use your librairie and it works until 4 us. Under it don't works. On scope I have 2.6us for 2 asked. For 4us I have 4us so it's ok. It's not possible to put 2 ? Thanks
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Newbie
Karma: 0
Posts: 37
|
 |
« Reply #98 on: May 15, 2013, 07:42:43 am » |
Sorry, I use digitalwrite for my tests instead use port directly and digitalwrite take time  So it works thanks.
|
|
|
|
|
Logged
|
|
|
|
|
|