Go Down

Topic: Due timer getting TC7 to toggle its associated Pin (3) (Read 107 times) previous topic - next topic


Using Due timers, how do you get the timer to toggle its associated pin High / Low rather than me doing it in code with DigitalWrite? That is TC7 toggles Pin 3. The attached code is my working square wave timer (65.624KHz), but it uses digital write rather than leaving it to the timer.
I am using TC7 so somehow I should be able to get the timer to toggle Pin3. I have got thus far by searching this forum (thanks) and in examples I see comments like (//50% high, 50% low) when setting up the timer. This implies to me the timers are meant to direct drive the pin. The step that seems to be missing is actually enabling the signal to be on pin 3. Hence I put digitalwrite in my timer. I would like to do this without the digitalwrite, because directly producing a square wave by the timers, is what I think the chip's timers been designed to do. I just cannot do that last bit of doing away with the digitalwrite and getting the timer setup to do the squarewave itself. Hope you can assist.


Timer Counter naming rules are somehow confusing.  "TC7" is Timer Counter 2 channel 1 but TC7 must be used for the corresponding interrupt handler. Pin 3 is PC28 has you can read in Graynomad pinout diagram.

You can either have direct register programing (in such case Sam3x datasheet is your best friend) or use tc_lib from antodom.

An example sketch with TC8 (Timer Counter 2 channel 2) to blink an LED with 1 MHz frequency:

Code: [Select]

/*       Timer Counter 2 Channel 2, namely TC8, 1 MHz frequency   */

void setup() {



void loop() {


void tc_setup() {

  PMC->PMC_PCER1 |= PMC_PCER1_PID35;                      // TC8 power ON : Timer Counter 2 channel 2 IS TC8 - see page 38

  PIOD->PIO_PDR |= PIO_PDR_P7;                            // Set the pin to the peripheral
  PIOD->PIO_ABSR |= PIO_PD7B_TIOA8;                       // Peripheral type B

  TC2->TC_CHANNEL[2].TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1  // MCK/2 = 42 M Hz, clk on rising edge
                              | TC_CMR_WAVE               // Waveform mode
                              | TC_CMR_WAVSEL_UP_RC       // UP mode with automatic trigger on RC Compare
                              | TC_CMR_ACPA_CLEAR         // Clear TIOA2 on RA compare match
                              | TC_CMR_ACPC_SET;          // Set TIOA2 on RC compare match

  TC2->TC_CHANNEL[2].TC_RC = 42;  //<*********************  Frequency = (Mck/2)/TC_RC  Hz
  TC2->TC_CHANNEL[2].TC_RA = 21;  //<********************   Any Duty cycle in between 1 and TC_RC

  TC2->TC_CHANNEL[2].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Software trigger TC2 counter and enable

void TC8_Handler() {

  static uint32_t Count;

  TC2->TC_CHANNEL[2].TC_SR;                               // Read and clear status register
  if (Count++ == 1000000) {
    Count = 0;
    PIOB->PIO_ODSR ^= PIO_ODSR_P27;                       // Toggle LED every 1 Hz


Sep 15, 2020, 07:36 pm Last Edit: Sep 15, 2020, 07:58 pm by Stephan_uino
Thanks. We should be able to let the timer itself do the toggle without us in code toggling it by "PIOB->PIO_ODSR ^= PIO_ODSR_P27; " The manual toggle method works and you could toggle other pins , not just Pin 3 but the Timer has a special setup with Pin3 and should be able to produce a square wave without us toggling the pin. I think I am right in thinking that TC7 should be able to produce a square wave on Pin3 without any toggling by us. I had a quick look at  use tc_lib from antodom (nice) and would have to study it more to see how it works and if it toggles the pin or gets the timer to do it. Thanks again for the reply much appreciated.


Toggling LED_BUILTING is OBVIOUSLY NOT necessary !!!. Hence the interrupt handler is NOT necessary.

Go Up