Where are pinput pin capture ( TIOA0, TIOA7, TIOB6, TIOA6 )?
I wan't to mesure speed water with a sensor.
Thanks
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.
Thank you very much !