Arduino: лучшее разрешение микросекунды, чем микрос ()?

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

Есть ли способ получить микросекундный клик с более высоким разрешением, предпочтительно до уровня 1 микросекунды?

Допускается снижение до уровня AVR.

10 голосов | спросил Mark Harrison 22 22011vEurope/Moscow11bEurope/MoscowTue, 22 Nov 2011 03:28:51 +0400 2011, 03:28:51

3 ответа


8

Да, в зависимости от базовой тактовой частоты Arduino. Например, здесь входные частоты счетчика и периоды после предварительного масштабирования, для счетчика таймера 2 ATMega2560 и базовая тактовая частота 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 МГц /(предварительный делитель * (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 является основным ресурсом; эта статья даст вам ( и дал мне!) хороший старт.

ответил JRobert 26 62011vEurope/Moscow11bEurope/MoscowSat, 26 Nov 2011 21:12:40 +0400 2011, 21:12:40
4

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

http: //electricrcaircraftguy.blogspot. ком /2014/02 /Timer2Counter-более-точный-Arduino-MICROS-function.html

Вот краткое описание: «Я написал« libary », чтобы получить точность 0,5us в функции замены« micros () », чтобы я мог получать повторяющиеся результаты, считывая сигнал PWM или PPM, с точностью до 1us. Я искал по всему Интернету и не мог найти что-то сопоставимое (или это было легко использовать и поддерживало способность Arduino писать сигналы PWM через Servo Libary), поэтому я считаю, что это мой первый крупный вклад в мир Arduino и Radio Control ».

ответил Gabriel Staples 9 FebruaryEurope/MoscowbSun, 09 Feb 2014 21:12:15 +0400000000pmSun, 09 Feb 2014 21:12:15 +040014 2014, 21:12:15
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 22 22011vEurope/Moscow11bEurope/MoscowTue, 22 Nov 2011 03:45:02 +0400 2011, 03:45:02

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132