Arduino로 타이머 인터럽트를 어떻게 만듭니 까?


9

Arduino로 시간 지연 인터럽트를 만들려고합니다. 인터럽트 () 함수는 내부 인터럽트이므로 사용하고 싶습니다.

예 : 인터럽트 타이밍만으로 표시등을 켜고 끄고 싶습니다.

샘플 코드가 있지만 외부 인터럽트 (attachInterrupt ())를 사용합니다. 내부 인터럽트를 계속 사용하고 싶습니다.


2
Kortuk이 보여준 요점은 attachInterrupt가 추상적 인 것이므로 외부 구성 요소를 첨부하지 않는다고 생각합니다. :)
clabacchio

이 기사가 도움이 될 수 있습니다. engblaze.com/…
세스 아처 브라운

답변:


10

Noah Stahl의 블로그는 Timer2로 LED를 깜박이 있습니다. 이 데이터 시트와 데이터 시트를 사용하면 사용하려는 인터럽트, 즉 정상적인 기능을 포기하거나 수정할 의향이있는 인터럽트에 적용 할 수 있어야합니다. Timer2는 일반적으로 일부 PWM 기능에 사용됩니다.

그의 예는 ATmega2560을 인용합니다. ATmega328p에서도 작동한다는 것을 확인할 수 있습니다. 더 유용한 Arduino 인터럽트 예제는 그의 사이트를 둘러보십시오.

편집하다:

여기 노아의 코드가 약간 편집되었습니다. 타이밍과 인터럽트는 일단 시작되면 관련 데이터 구조 나 하드웨어를 초기화 한 후 Arduino setup () 함수에서 Timer2init ()를 호출하십시오.

F / ex, 3 자리 7 세그먼트 디스플레이를 다중화하는 데 사용했기 때문에 타이머를 초기화하기 전에 디스플레이 I / O 레지스터를 초기화하고 ISR이 찾을 위치에 디스플레이 데이터를 비 웠습니다.

데이터 시트의 유용한 타이밍 데이터에 대한 의견과 다른 타이밍 체계를 설정하기 위해 참조한 내 계산표가 있습니다.

ISR () 매크로는 일반 함수의 입력 및 종료 대신 ISR에 대한 인터럽트 입력 및 종료 코드를 작성하고 적절한 인터럽트 벡터와 링크하는 작업을 처리합니다. 그 기능의 나머지 부분은 1) 각 인터럽트에서 실행될 코드와 2) 다음 인터럽트에 대한 타이머를 재설정하는 코드 코드입니다.

작성된 바와 같이 이것은 .pde 또는 .ino 스케치 (또는 eclipse를 사용하는 경우 .cpp 파일, f / ex)로 드롭됩니다. 스케치는 LEDPIN을 #define해야하며 setup ()은 Timer2init ()를 호출해야합니다. 루프 기능이 비어 있거나 없을 수 있습니다. 다운로드시 LED가 깜박이기 시작해야합니다 (문자 그대로 Timer2init ()가 호출 된 후).

/*
 * From sample interrupt code published by Noah Stahl on his blog, at:
 * http://arduinomega.blogspot.com/p/arduino-code.html
 * 
 */


/*** FUNC

Name:           Timer2init

Function:       Init timer 2 to interrupt periodically. Call this from 
                the Arduino setup() function.

Description:    The pre-scaler and the timer count divide the timer-counter
                clock frequency to give a timer overflow interrupt rate:

                Interrupt rate =  16MHz / (prescaler * (255 - TCNT2))

        TCCR2B[b2:0]   Prescaler    Freq [KHz], Period [usec] after prescale
          0x0            (TC stopped)     0         0
          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


Parameters: void

Returns:    void

FUNC ***/

void Timer2init() {

    // Setup Timer2 overflow to fire every 8ms (125Hz)
    //   period [sec] = (1 / f_clock [sec]) * prescale * (255-count)
    //                  (1/16000000)  * 1024 * (255-130) = .008 sec


    TCCR2B = 0x00;        // Disable Timer2 while we set it up

    TCNT2  = 130;         // Reset Timer Count  (255-130) = execute ev 125-th T/C clock
    TIFR2  = 0x00;        // Timer2 INT Flag Reg: Clear Timer Overflow Flag
    TIMSK2 = 0x01;        // Timer2 INT Reg: Timer2 Overflow Interrupt Enable
    TCCR2A = 0x00;        // Timer2 Control Reg A: Wave Gen Mode normal
    TCCR2B = 0x07;        // Timer2 Control Reg B: Timer Prescaler set to 1024
}



/*** FUNC

Name:       Timer2 ISR

Function:   Handles the Timer2-overflow interrupt

Description:    Maintains the 7-segment display

Parameters: void

Returns:    void

FUNC ***/

ISR(TIMER2_OVF_vect) {
    static unsigned int led_state = 0; // LED state

    led_state = !led_state;         // toggles the LED state
    digitalWrite(TOGGLE_PIN, led_state);

    TCNT2 = 130;     // reset timer ct to 130 out of 255
    TIFR2 = 0x00;    // timer2 int flag reg: clear timer overflow flag
};

(@Kortuk : 귀하가 언급 한 의견은 여기에있는 여러 의견 제시 자들에 대한 저의 관찰이며 개인적으로 겨냥한 것이 아니며 불필요합니다. 사과하고 삭제했습니다.) 제안한대로 답변을 넓히고 싶습니다. 이제는 실증적 일뿐만 아니라 유익한 것도 있습니다. 여기에는 본인이 사용하기 위해 코드에 작성한 주석 (의미 : 6 개월 후에 이해할 수 있다면 다른 사람도 가능할 것임)과 몇 가지 "사용 방법"지침이 포함됩니다. 대답. 제안 해 주셔서 감사합니다.
JRobert

timer0 및 timer1 (atmega328에서 가장 작음)에는 32 및 128의 프리 스케일을 사용할 수 없습니다.
tuupola

알아두면 좋습니다. 감사합니다. 나는 이것을 Timer2 (지금까지)에 사용하며 기본적으로 드롭 인입니다.
JRobert

5

attachInterrupt () 실제로 핀 외부 상태 변화에 인터럽트를 부착되는 기능은, 어떤 다른 선택이 없다.

같은 페이지 모드 옵션은 다음과 같이 나열되어 있습니다 :

mode는 언제 인터럽트가 트리거되어야 하는지를 정의합니다. 4 개의 상수는 유효한 값으로 미리 정의되어 있습니다.

  • 낮은핀이 낮을 때마다 인터럽트를 트리거하려면
  • 변화핀이 값을 변경할 때마다 인터럽트를 트리거하는
  • 상승 핀이 로우에서 하이로 갈 때 트리거,
  • FALLING 핀이 하이에서 로우로 갈 때 대한.

나쁜 소식을 전하는 것이 유감입니다. 제가 찾은 첫 번째 것 중 하나입니다.


나는 그가 외부 장치 대신 내부 타이머를 사용하고 싶다는 것을 의미한다고 생각하지만 ... 아두 이노를 잘 알지 못하므로 가능한지 말할 수 없습니다.
clabacchio

@ clabacchio, 유일한 옵션은 외부 트리거를 사용하는 것이며 내부 타이머 기능은 없습니다.
Kortuk

아, 좋습니다 :) 적어도 Arduino 보드에는 타이머가 있습니까?
clabacchio

예, 그것이 지연과 같은 것들을 성취하는 방법입니다.
Kortuk

1
@ icarus74 ATMega328에는 실제로 3 개의 타이머 (하나는 16b, 2는 8b)가 있지만 모두 Arduino에서 사용합니다. 하나는 delay () 및 millis ()와 같은 함수에 사용되며 세 가지 모두 PWM에 사용됩니다 (Arduino IDE의 'wiring.c'파일 'init ()'에서 자세한 정보를 찾을 수 있습니다).
vasco

2

PWM에 관한기사 는 Arduino 타이머 사용에 관한 많은 의심을 없애줍니다. Arduino에는 8 비트 타이머 2 개와 16 비트 타이머 1 개가 있습니다. Arduino SDK와 함께 제공되는 타이머에 ISR 기능을 직접 연결하는 고급 API는 없지만 (예 : 표준 라이브러리) 특수 기능 레지스터 및 비트 산술 / 비트 산술 / 그들에 대한 작업. 그러나 Timer one 이라는 사용자 제공 라이브러리가 있습니다.


어떤 Arduino가 참조되는지에 따라 가능한 여러 가지 타이머 조합이 있습니다. 대답은 오도의 소지가 있습니다.
겉으로보기 그래서

@SeeminglySo, 정교하게 관리? Arduino 하드웨어에 대해 이야기하는 경우, 답변은 질문과 관련하여 질문에 대한 시간입니다.
icarus74

Arduino Mega (ATmega1280 기반)는 2009 년 3 월 26 일에 릴리스되었으며 Mega 2560 (ATmega2560)은이 질문이 제기되기 훨씬 전에 2010 년 9 월 24 일에 릴리스되었습니다. 두 마이크로 컨트롤러 모두 답변에 지정된 2x 8 비트 및 1x 16 비트 타이머 / 카운터 이상을 가지고 있습니다.
겉으로보기 So

지금까지 본 대부분의 상호 작용에는 Duemilanove 또는 Uno, 즉 328 시리즈 기반 보드와 같은 것을 의미하는 Arduino에 대한 명확한 참조가 있습니다. 다른 보드는 항상 uP 시리즈 번호로 명시 적으로 인증되었습니다. 또는 Mega, Nano, Micro 등 어쨌든, 나는 겸손하게 정정을 받아 들일 것입니다. 이와 관련하여 설명이 더 좋습니다.
icarus74

1

Arduino는 ATMega328에서 세 개의 타이머를 모두 사용하고 있습니다. Timer1(16 비트)와 같은 기능을 위해 사용 delay()하고 millis()핀 (5) 및 (6)의 다른 2 개 개의 타이머에 PWM 출력 - Timer0Timer2핀 3, 9, 10, 11에 PWM 출력에 사용된다.

따라서 타이머 인터럽트에는 Arduino 기능이 없습니다. 그러나 방법이 있습니다. 이 코드를 사용하여 타이머 인터럽트를 활성화 할 수 있습니다 Timer2.

ISR(TIMER2_OVF_vect) {
  // Interrupt routine.
}

void setup() {
  // Enable Timer2 interrupt.
  TIMSK2 = (0<<OCIE2A) | (1<<TOIE2);
}

void loop() {
  // Your main loop.
}

테스트하지 않고이 코드를 작성 했으므로 실수했을 가능성이 있습니다. 이 경우 데이터 시트를 확인하십시오 ( p.156) .

타이머 주파수 (프리스케일러)를 변경하려면 간단히 register를 변경하십시오 TCCR2A. 자세한 내용은 데이터 시트 (153 페이지)를 참조하십시오. 그러나 타이머의 주파수를 변경하면 두 개의 출력 핀에서 PWM 신호의 주파수도 변경됩니다!


ATmega328에 AFAIK Timer0Timer28 비트이며, 유일한 Timer116 비트입니다.
tuupola

아니요, 정확하지 않습니다. 타이머 1이 아니라 타이머 0이며 지연 () 및 millis () 및 핀 5와 6의 PWM 출력에 사용됩니다. 타이머 0은 8 비트 타이머입니다. 예를 들어 Arduino 타이머 및 인터럽트를 참조하십시오 .
피터 Mortensen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.