2016-03-28 8 views
1

Ich bin neu in Arduino Programmierung und versuchen, den Arduino Uno als hochauflösender Timer zu verwenden. Ich würde gerne in der Lage sein, Taktzyklen mit der vollen 16 MHz-Rate zwischen zwei Anstiegsflankeninterrupts zu zählen. Ich habe einen Code, der mit der Funktion micros() funktioniert, die eine Auflösung von 4 Mikrosekunden hat, und ich brauche etwas Besseres. Hier ist ein Beispiel-Code, wo ich versuche, Mikros() zu verwenden, für das Timing:Arduino TCNT1 um Taktzyklen zwischen Interrupts zu zählen?

volatile int k = 0; 
volatile float t1 = 0; 
volatile float t2 = 0; 

void setup() { 
    // put your setup code here, to run once: 
    Serial.begin(9600); 
    attachInterrupt(digitalPinToInterrupt(2), ISR1, RISING); 
    attachInterrupt(digitalPinToInterrupt(3), ISR2, RISING); 
} 

void ISR2() 
{ 
    k = 1; 
    t1 = micros(); 
    Serial.println(1); 
} 

void ISR1() 
{ 
    k = 2; 
    t2 = micros(); 
    Serial.println(2); 
} 

void loop() 
{ 
    if (t1 != 0 && t2 != 0) { 
    if (t2 - t1 < 0) { 
     t1 = 0; 
     t2 = 0; 
    } 
    else { 
     Serial.print("tdelta "); 
     Serial.print(t2 - t1); 
     t1 = 0; 
     t2 = 0; 
     Serial.println(0); 
    } 

    } 
} 

Ich weiß, dass mein Mikros Timing wahrscheinlich ein wenig von dem Interrupts versetzt bekommen, was ein Problem sein kann.

Kann mir jemand in die richtige Richtung zeigen?

Ich denke, ich möchte Timer1 verwenden, da es 16 Bit ist und meine Ereignisse sollten schnell genug sein, um abgeschlossen zu werden, bevor ein Überlauf auftritt. Ich hoffe, einen einfachen Weg zu finden, tcnt1 mit dem ersten Interrupt auf 0 zu setzen und dann tcnt1 Taktzyklen bis zum zweiten Interrupt zu zählen. Ich weiß nicht wirklich, wie ich die Werte von tcnt1 lesen soll, also habe ich einen Weg zu gehen.

Ich habe nach Beispielen gesucht, aber habe nicht wirklich eine gefunden, die angemessen scheint. Alles scheint auf Timer-Interrupts ausgerichtet zu sein, von denen ich nicht ganz überzeugt bin.

Ich vermisse wahrscheinlich viel Verständnis, um diese tcnt1-Zähler zu verwenden, aber jede Hilfe, um mich in die richtige Richtung zu zeigen, würde sehr geschätzt werden!

Danke

Antwort

2

Sie können versuchen, mit Timer-Registern direkt zu arbeiten. Sehen Sie sich die CPU an, die auf Ihrer speziellen Platine verwendet wird. Für Mega ist es ATmega2560-16AU. Der Name des Timer-Registers lautet TCNT1. Sie können den Wert speichern:

int t1;// declare global variable somewhere 
t1 = TCNT1; //save timer value in ISRx interrupts 

Setup Vorteilerwert Stellen Sie sicher, TCCR1B.CSn und Timer-Overflow-Interrupt behandeln, sonst werden Sie Zeitdaten verlieren: ISR(TIMER1_OVF_vect)

Wie Sie hier here Präzision von < 1 uS lesen kann sei erreicht. More info wie direkt mit CPU-Timer-Registern arbeiten.

+0

Vielen Dank für die Info! Genau das, was mir gefehlt hat! Habe es funktioniert. – jtp