Ардуїно: краща роздільна здатність мікросекунди, ніж micros ()?


11

Документація micros () зазначає, що повернене значення завжди буде кратним 4.

Чи є спосіб отримати клацання мікросекунди з більшою роздільною здатністю, бажано до рівня 1 мікросекунда?

Зниження до рівня AVR є прийнятним.


1
Чому ти наполягаєш на тому, щоб починати свою назву тегом, коли я поставив це ідеально англійським питанням?
stevenvh

4
Вибачте Стівен, я щиро подумав (і думаю), що це хороший спосіб викласти питання лаконічно і чітко. Про це було багато дискусій, і Джефф погодився в деяких випадках, що це гарний спосіб запитати. Дискусія тут; теплові карти - це те, що мене переконало, що для цих стильових питань варто акцентувати увагу на робочому середовищі. meta.stackexchange.com/questions/10647/writing-good-titles/… Але, з поваги до ваших чудових відповідей, я би радий змінити його, якщо ви вважаєте, що це найкраще.
Марк Гаррісон

Чи можна використовувати його для функції pulsein ()? Мені потрібно виміряти довжину імпульсів у роздільній здатності менше 1 Usec.

Цей простір зарезервовано для відповідей на запитання вгорі. Якщо у вас є що запитати, починайте власне запитання.
Олін Латроп

Відповіді:


9

Так, залежно від основної тактової частоти вашого Arduino. Наприклад, ось вхідні частоти лічильника таймера та періоди після попереднього масштабування, для лічильника таймера ATMega2560 2 та основної тактової частоти 16 МГц. Таймер має вбудовані параметри значення "докаскалер", які визначають частоту / період, показані в цій таблиці:

    TCCR2B bits 2-0    Prescaler    Freq [KHz], Period [usec] after prescale
          0x0          (TC stopped)      --         --
          0x1                1        16000.        0.0625
          0x2                8         2000.        0.500
          0x3               32          500.        2.000
          0x4               64          250.        4.000
          0x5              128          125.        8.000
          0x6              256           62.5      16.000
          0x7             1024           15.625    64.000

Для кращої роздільної здатності часу ви використовуєте значення під назвою TCNT2. Існує вбудований лічильник, який йде від 0 до 255, оскільки таймер - 8 біт. Коли лічильник досягає значення, призначеного TCNT2, він запускає переривання. Ця переривання називається TIMER2_OVF_vect.

з огляду на цю інформацію, результуюча швидкість переривання буде: 16 МГц / (prescaler * (255 - TCNT2))

Ви можете змусити таймер працювати на повному 16 МГц (62,5nSec), хоча це швидше, ніж вам потрібно; 2 МГц з початковим числом (255-2) дасть вам швидкість переривання 1 МГц. Розділіть це на 2 у вашому ISR:

extern uint32_t MicroSecClock = 0;

ISR(TIMER2_OVF_vect) {// this is a built in function that gets called when the timer gets to the overflow counter number
  static uint_8 count;            // interrupt counter

  if( (++count & 0x01) == 0 )     // bump the interrupt counter
    ++MicroSecClock;              // & count uSec every other time.

  digitalWrite(53,toggle);// pin 53 is arbitrary
  TCNT2 = 253;                    // this tells the timer when to trigger the interrupt. when the counter gets to 253 out of 255(because the timer is 8 bit) the timmer will trigger an interrupt
  TIFR2 = 0x00;                   // clear timer overflow flag
};

Лист даних для вашого MCU є основним ресурсом; Ця стаття дасть вам (і дала мені!) хороший початок.


4

Позначте, я вирішив написати новий набір функцій, заснований на Arduino Atmega328 Timer2, і використовуючи переповнення переповнення, щоб отримати точність до 0,5us. Мій код доступний для завантаження та використання тут:

http://electricrcaircraftguy.blogspot.com/2014/02/Timer2Counter-more-precision-Arduino-micros-function.html

Ось короткий опис: "Я написав" бібліотеку ", щоб отримати 0,5-точну точку функції заміни на" micros () ", щоб я міг отримати повторювані результати, читаючи сигнал PWM або PPM, в межах 1ус. Я шукав все навколо Інтернет і не міг знайти щось порівнюване (або це було просто у використанні, і підтримував здатність Arduino писати ШІМ-сигнали через Servo Libary), тому я думаю, що це мій перший великий внесок у світ Arduino і Radio Control ".


3

Якщо зниження до рівня AVR прийнятне (як ви згадували у своєму запитанні), ви можете встановити таймер і навіть отримати кліщі годинника AVR.

Потрібно звернутися до таблиці даних AVR, оскільки він відрізняється в різних ATMegas та ATTinys. Але процедура завжди однакова. Що вам потрібно зробити:

  • Вирішіть, який дошкільний пристрій використовувати (наприклад, встановіть його на 1, тобто немає повторного звучання, якщо ви хочете фактичну тактову частоту процесора), зверніться до документації TCCR
  • встановити переривання переповнення таймера, обробник переривання та активувати переривання в усьому світі
  • активуйте таймер у реєстрі таймера / лічильника TCCR

Таким чином можна отримати точні галочки з реєстру таймерів, однак перерахунки потрібно рахувати вручну. Це максимально точно за технологією.

Ось кілька прикладів коду для застарілого AT90S2313, але він дає хороші підказки, що робити в основному:

/* uC: AT90S2313 */
#include <avr/io.h>
#include <avr/interrupt.h>

int main(void)
{
  // set up timer 0
  TCCR0 = (1<<CS01); // Prescaler 8

  // enable overflow interrupt
  TIMSK |= (1<<TOIE0);

  // activate interrupts
  sei();

  while(1)
  {
     /* Do whatever you like */
  }
}


ISR (TIMER0_OVF_vect)
{    
   /*
      This gets called everytime there in an overflow in the timer register  
   */
}

Дякую FeeJai. Чи можу я встановити ці переривання в контексті ескізу Ардуїно?
Марк Гаррісон

1
Я не знайомий з рамками ардуїно. Але якщо він не встановить всі таймери внутрішньо, ви, звичайно, можете. Інакше ви все ще можете прочитати регістри таймерів та обчислити самостійно.
FeeJai

Так, ви програмуєте на повному C ++ в Arduino і можете використовувати всі регістри та символи, такі як TIMSKі TOIE0т. Д. (Скопіюйте налаштування таймера з листа даних atmega328p). Схоже, ви не можете використовувати макрос ISR (), а замість цього використовувати arduino.cc/en/Reference/AttachInterrupt .
joeforker
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.