Input pin capture ?

Where are pinput pin capture ( TIOA0, TIOA7, TIOB6, TIOA6 )?
I wan't to mesure speed water with a sensor.

Thanks

To capture frequency and duty cycle of a digital signal, select a Timer Counter in Capture Mode. To see where are TIOAx, look at the Graynomad pinout diagram.

An example of input capture:

/*************************************************************************************************/
/*  a jumper needs to be installed between pin 2 (TIOA0) and pin A7 (TC0 channel 1 TIOA pin)     */
/*************************************************************************************************/

volatile uint32_t CaptureCountA, CaptureCountB, Period, Duty;
volatile boolean CaptureFlag;

void setup() {
  Serial.begin(250000);

  /*************  Timer Counter 0 Channel 0 to generate PWM pulses thru TIOA0  ************/
  PMC->PMC_PCER0 |= PMC_PCER0_PID27;                      // Timer Counter 0 channel 0 IS TC0
  PIOB->PIO_PDR |= PIO_PDR_P25 | PIO_PDR_P27;
  PIOB->PIO_ABSR |= PIO_ABSR_P25 | PIO_ABSR_P27;

  TC0->TC_CHANNEL[0].TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1   // MCK/2, 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 TIOA0 on RA compare match
                              | TC_CMR_ACPC_SET;           // Set TIOA0 on RC compare match


  TC0->TC_CHANNEL[0].TC_RC = 100;                          // Frequency of PWM pulses = MCK/2/TC_RC
  TC0->TC_CHANNEL[0].TC_RA = 40;                           // Duty cycle of PWM pulses = (TC_RA/TC_RC) * 100 %

  TC0->TC_CHANNEL[0].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN; // Software trigger and enable

  /*************  Timer Counter 0 Channel 1 to capture PWM pulses thru TIOA1  ************/
  PMC->PMC_PCER0 |= PMC_PCER0_PID28;                       // Timer Counter 0 channel 1 IS TC1

  TC0->TC_CHANNEL[1].TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1   // capture mode, MCK/2, clk on rising edge
                              | TC_CMR_ABETRG              // TIOA is used as the external trigger
                              | TC_CMR_LDRA_RISING         // load RA on rising edge of trigger input
                              | TC_CMR_LDRB_FALLING;       // load RB on falling edge of trigger input

  TC0->TC_CHANNEL[1].TC_IER |= TC_IER_LDRAS | TC_IER_LDRBS; // Trigger interruption on Load RA and load RB
  TC0->TC_CHANNEL[1].TC_CCR = TC_CCR_SWTRG | TC_CCR_CLKEN;  // Software trigger and enable

  NVIC_DisableIRQ(TC1_IRQn);
  NVIC_ClearPendingIRQ(TC1_IRQn);
  NVIC_SetPriority(TC1_IRQn, 0);                      // Give TC1 interrupt the highest urgency
  NVIC_EnableIRQ(TC1_IRQn);                           // Enable TC1 interrupts

}

void loop() {
  const uint32_t _F_CPU = F_CPU / 2;
  static uint32_t counter;
  float Frequency;
  float _Duty;

  if (counter++ > 100000) {

    if ( CaptureFlag == true) {

      Frequency = _F_CPU / Period  ; //  (Mck/2 is TC1 clock) F in Hz
      _Duty = (Duty * 100.00) / Period;

      Serial.print(" F = "); Serial.print((uint32_t)Frequency); Serial.print(" Hz ");
      Serial.print (" ,  Duty = "); Serial.print((uint32_t)_Duty); Serial.println(" %");
      counter = 0;
      CaptureFlag = false;

    }
  }
}

void TC1_Handler() {

  static uint32_t _CaptureCountA;

  uint32_t status = TC0->TC_CHANNEL[1].TC_SR;       // Read and Clear status register


  //if (status & TC_SR_LOVRS) abort();  // We are loosing some edges

  if (status & TC_SR_LDRAS) {  // If ISR is triggered by LDRAS then ....
    CaptureCountA = (uint32_t) TC0->TC_CHANNEL[1].TC_RA;        // get data from capture register A for TC0 channel 1
    Period = CaptureCountA - _CaptureCountA;
    _CaptureCountA = CaptureCountA;
  }
  else { /*if ((status & TC_SR_LDRBS) == TC_SR_LDRBS)*/  // If ISR is triggered by LDRBS then ....
    CaptureCountB = (uint32_t) TC0->TC_CHANNEL[1].TC_RB;         // get data from caputre register B for TC0 channel 1
    Duty = CaptureCountB - _CaptureCountA;
    CaptureFlag = true;                      // set flag indicating a new capture value is present
  }

}

tc_lib from antodom provides an example of input capture too.

1 Like

Thank you very much !