Hi everyone,
I couldn't find a library for measuring frequency's on a Arduino Due, so i tried to do it on my own. My plan was to use the TC in capture mode and TIOA as input for a signal. After saving the counter value of two following rising edges of the signal, it's easy to calculate the frequency.
Unfortunately it's not working. I don't know why but it seems that I get an infinite interrupt in the TC_Handler().
Whenn running the Sketch a lot "Error" lines appear in the Serial Monitor. That's the third case in the if structure in TC_Handler. That's what I don't understand because: as soon as the float measured turns 2 the while loop in measure() should end, the interrupts disabled and the frequency calculated.
I connected pin 12 with pin 2 to measure the pwm, which is configurated in setup().
Could someone please help me?
The sketch:
#include "MeasureFrequency.h"
void setup() {
Serial.begin(115200);
pinMode(12, OUTPUT);
analogWrite(12,125);
pinMode(2, INPUT);
}
void loop() {
Serial.println();
Serial.print("measured frequency: ");
Serial.print(measure());
Serial.println();
delay(1000);
}
And MeasureFrequency.cpp :
#include <MeasureFrequency.h>
#include <Arduino.h>
//global variables
static int measured;
static int captured_ra_1;
static int captured_ra_2;
static float frequence;
#define Timer_CLOCK_1 (0 << 0)
#define Clock_Invert (0 << 2)
#define BURST (0 << 4)
#define LDBSTOP (1 << 6) //Timer stop b loaded
#define LDBDIS (0 << 7) //diable clock b loaded
#define ETRGDG (1 << 8) //falling edge
#define ABETRG (1 << 10) //TIOA as trigger
#define CPCTRG (0 << 11) //kein compare
#define WAVE (0 << 15) // capture mode
#define LDRA (1 << 16) //LDRA Rising
#define LDRB (0 << 18) // LDRB none
#define interruptA (1 << 5)
#define interruptB (1 << 6)
#define TC_Handler TC0_Handler
#define TC_IRQn TC0_IRQn
// Configure TC0 in capture operating mode.
void tc_capture_initialize(void){
// clock enable TC0 channel 0
pmc_enable_periph_clk (TC_INTERFACE_ID + 0*3+0) ;
REG_TC0_WPMR = 0x54494D00; //WPKEY, disable
REG_TC0_CCR0 = ((1 << 2) | (1 <<0)) ; //reset, enable clock
//configure channel_mode_reg in capture mode
REG_TC0_CMR0 = Timer_CLOCK_1 | ETRGDG | ABETRG | CPCTRG | WAVE | LDRA;
REG_TC0_IDR0 = 0b11111111; //disable all interrupts
REG_TC0_IER0 = interruptA; //enable interrupt: load register a
}
//brief Interrupt handler
void TC_Handler(void){
if( ( REG_TC0_SR0 & ( 1 << 5 ) ) == ( 1 << 5 ) ){
if( measured == 0 ){
captured_ra_1 = REG_TC0_RA0; //save counter value of first edge
measured = 1;
}else if( measured == 1 ){
captured_ra_2 = REG_TC0_RA0; //save counter value of second edge
measured = 2;
}else{
// Error, measured wasen't set to 0
// no read out of result
Serial.println("Error");
}
}
}
//method to measure frequency
float measure(){
// Configure PIO Pins for TC0
PIOB -> PIO_ABSR = (1 << 25);
//Disable IO to enable peripheral mode)
PIOB -> PIO_PDR = (1 << 25);
//reset variables
measured = 0;
captured_ra_1 = 0;
captured_ra_2 = 0;
frequence = 0;
// initialize TC0 Channel0
tc_capture_initialize();
//Configure TC interrupts for TC TC_CHANNEL_CAPTURE only
NVIC_DisableIRQ(TC_IRQn);
NVIC_ClearPendingIRQ(TC_IRQn);
NVIC_SetPriority(TC_IRQn, 0);
NVIC_EnableIRQ(TC_IRQn);
while( measured != 2 ){
//do nothing
//Serial.println(measured);
};
//disable interrupts
REG_TC0_IDR0 = 0b11111111; //disable all interrupts
NVIC_DisableIRQ(TC_IRQn);
//measured = 2, calculate frequency, CLK = MST_CLK / 2
frequence = 42000000 / (captured_ra_2 - captured_ra_1);
return frequence;
}