2016-03-28 2 views
1

Я новичок в программировании Arduino и пытаюсь использовать arduino uno в качестве таймера с высоким разрешением. Я хотел бы иметь возможность подсчитывать тактовые циклы с полной частотой 16 МГц между двумя передними прерываниями. У меня есть код, который функционирует с использованием функции micros(), которая имеет разрешение 4 микросекунды, и мне нужно лучше. Ниже приведен пример кода, где я пытаюсь использовать Micros() для синхронизации:Arduino TCNT1 для подсчета тактов между прерываниями?

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); 
    } 

    } 
} 

Я понимаю, что мои MICROS хронометраже забегаем немного компенсируется прерываниями, что может быть проблемой.

Может ли кто-нибудь указать мне правильное направление?

Я думаю, что хочу использовать timer1, так как это 16 бит, и мои события должны быть достаточно быстрыми, чтобы их можно было завершить до того, как произойдет переполнение. Я надеюсь найти простой способ настроить tcnt1 на 0 с первым прерыванием, а затем подсчитать тактовые циклы tcnt1 до второго прерывания. Я даже не знаю, как читать значения из tcnt1, поэтому у меня есть способы пойти.

Я искал примеры, но на самом деле не нашел подходящего. Все, похоже, связано с прерываниями таймера, которые, как я думаю, не совсем то, что мне нужно.

У меня, вероятно, не хватает много необходимого понимания для использования этого счетчика tcnt1, но любая помощь, чтобы указать мне в правильном направлении, была бы очень признательна!

Благодаря

ответ

2

Вы можете попробовать работать с таймером регистрирует непосредственно. Посмотрите руководство по процессору, которое используется на вашей конкретной плате. Для мега это ATmega2560-16AU. Имя регистра таймера - TCNT1. Вы можете сохранить его значение:

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

Обязательно значения настройки предварительного делителя TCCR1B.CSn и обрабатывать прерывание переполнения таймера, в противном случае вы потеряете время данные: ISR(TIMER1_OVF_vect)

Как вы можете прочитать здесь here точности < 1 СШа могут быть достигнуто. More info о том, как работать непосредственно с регистрами таймеров CPU.

+0

Благодарим вас за информацию! Именно то, чего мне не хватало! Это работало. – jtp

Смежные вопросы