Arduino : micros ()보다 더 나은 마이크로 초 해상도?


11

micros () 문서에 따르면 반환 값은 항상 4의 배수가됩니다.

더 높은 해상도의 마이크로 초 클릭을 얻을 수있는 방법이 있습니까?

AVR 수준으로 떨어 뜨릴 수 있습니다.


1
완벽하게 영어로 질문 할 때 태그로 제목을 시작해야하는 이유는 무엇입니까?
stevenvh

4
사과 Steven, 나는 그것을 간결하고 명확하게 표현하는 좋은 방법이라고 진심으로 생각하고 생각했다. 이에 대해 많은 토론이 있었고 Jeff는 경우에 따라 좋은 방법이라고 동의했습니다. 토론은 여기에 있습니다; 히트 맵은 이러한 스타일의 질문에 대해 운영 환경을 강조하는 데 비용이 든다는 것을 확신시켜주었습니다. meta.stackexchange.com/questions/10647/writing-good-titles/… 그러나 귀하의 탁월한 답변을 존중하기 때문에 최선이라고 생각하면 다시 바꾸어 드리겠습니다.
Mark Harrison

pulsein () 함수에 사용할 수 있습니까? 1 usec보다 해상도 les에서 펄스 길이를 측정해야합니다.

이 공간은 맨 위에있는 질문에 대한 답변을 위해 예약되어 있습니다. 물어볼 것이 있으면 스스로 질문을 시작하십시오.
Olin Lathrop 2013 년

답변:


9

예, Arduino의 기본 클럭 속도에 따라 다릅니다. 예를 들어 ATMega2560의 카운터 타이머 2에 대한 사전 스케일링 후 카운터 타이머 입력 주파수 및주기와 16MHz의 기본 클럭 속도가 여기에 있습니다. 타이머에는 "프리스케일러"값 옵션이 내장되어 있으며이 표에 표시된 것처럼 주파수 /주기를 결정합니다.

    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라는 값을 사용합니다. 타이머가 8 비트이기 때문에 0에서 255까지의 카운터가 내장되어 있습니다. 카운터가 TCNT2에 의해 할당 된 값에 도달하면 인터럽트를 트리거합니다. 이 인터럽트를 TIMER2_OVF_vect라고합니다.

이 정보가 주어지면 결과 인터럽트 속도는 16MHz / (prescaler * (255-TCNT2))입니다.

타이머는 최대 16MHz (62.5nSec)에서 작동하도록 할 수 있지만, 필요한 것보다 빠릅니다. 초기 카운트가 (255-2) 인 2MHz는 1MHz 인터럽트 속도를 제공합니다. ISR에서 2로 나눕니다.

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

Mark, Arduino Atmega328 Timer2를 기반으로 오버플로 인터럽트를 사용하여 0.5us의 정밀도를 얻기 위해 새로운 함수 세트를 작성하기로 결정했습니다. 내 코드는 다음에서 다운로드하여 사용할 수 있습니다.

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

간단한 설명은 다음과 같습니다. ""micros () "대체 함수에서 0.5us 정밀도를 얻기 위해"라이브러리 "를 작성하여 PWM 또는 PPM 신호를 1us 내로 반복해서 결과를 얻을 수 있습니다. 인터넷과 비슷하고 사용하기 쉽고 서보 라이브러리를 통해 PWM 신호를 작성할 수있는 Arduino의 기능을 유지 한 것을 찾을 수 없었습니다. 이것이 이것이 Arduino와 Radio Control 세계에 대한 첫 번째 주요한 기여라고 생각합니다. "


3

AVR 레벨로 드롭 다운이 허용되는 경우 (질문에서 언급 한 바와 같이) 타이머를 설정하고 AVR 시계의 눈금을 확인할 수도 있습니다.

ATMegas와 ATTinys가 다르므로 AVR의 데이터 시트를 참조해야합니다. 그러나 절차는 항상 동일합니다. 당신이해야 할 일은 :

  • 사용할 프리스케일러를 결정하십시오 (예 : 실제 CPU 클럭 속도를 원하는 경우 프리 스케일링 없음). 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에게 감사합니다. Arduino 스케치의 컨텍스트 내에서 이러한 인터럽트를 설정할 수 있습니까?
마크 해리슨

1
나는 arduino 프레임 워크에 익숙하지 않습니다. 그러나 모든 타이머를 내부적으로 설정하지 않으면 확실히 할 수 있습니다. 그렇지 않으면 타이머 레지스터를 읽고 스스로 계산할 수 있습니다.
FeeJai

예, 당신은 아두 이노에서 ++ 전체 C로 프로그래밍하고 같은 모든 레지스터와 기호를 사용할 수 있습니다 TIMSK, TOIE0등합니다 (atmega328p 데이터 시트에서 복사 타이머 설정). ISR () 매크로를 사용할 수없는 대신 arduino.cc/en/Reference/AttachInterrupt 를 사용 하십시오 .
joeforker
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.