2013-04-17 43 views
5

Tôi muốn biết thêm về Arduino Nano bộ hẹn giờ.Arduino Nano Timers

  1. Giờ có gì?
  2. Họ có tạo ra ngắt không?
  3. Mã nào sẽ đính kèm trình xử lý ngắt cho họ?
  4. như thế nào delay()delayMicroseconds() thực hiện ...
    • Họ sử dụng ngắt timer? (Nếu vậy, làm cách nào để tôi có thể thực thi mã khác trong thời gian này?)
    • Hoặc họ có thường xuyên thăm dò ý kiến ​​cho đến khi bộ đếm thời gian đạt đến một giá trị nhất định không?
    • Hoặc chúng có tăng giá trị X lần không?
    • Hay họ làm theo cách khác?

Trả lời

17

Cách tốt nhất để suy nghĩ về tính giờ Arduino Nano là để suy nghĩ về tính giờ trong chip cơ bản: các ATmega328. Nó có ba giờ:

  • Timer 0: 8-bit, PWM trên chân con chip 11 và 12
  • Timer 1: 16-bit, PWM trên chân con chip 15 và 16
  • Timer 2: 8- bit, PWM trên chip chân 17 và 5

Tất cả những tính giờ có thể sản xuất hai loại ngắt:

  • các "giá trị khớp lệnh" ngắt xảy ra khi bộ đếm thời gian giá trị, trong đó sẽ được thêm vào mọi dấu tích của bộ hẹn giờ đều đạt giá trị so sánh trong thanh ghi hẹn giờ.
  • Các timer tràn ngắt xảy ra khi giá trị đếm thời gian đạt giá trị tối đa của nó

Thật không may, không có chức năng Arduino để đính kèm ngắt để tính giờ. Để sử dụng ngắt hẹn giờ, bạn sẽ cần phải viết mã cấp thấp hơn một chút. Về cơ bản, bạn cần khai báo một số interrupt routine như sau:

ISR(TIMER1_OVF_vect) { 
    ... 
} 

Điều này sẽ tuyên bố một chức năng để ngắt dòng hẹn giờ1. Sau đó, bạn cần phải bật gián đoạn tràn bộ đếm thời gian bằng cách sử dụng thanh ghi TIMSK1. Trong ví dụ trường hợp trên đây có thể trông như thế này:

TIMSK1 |= (1<<TOIE1); 

hoặc

TIMSK1 |= BV(TOIE1); 

này đặt TOIE1 (tạo timer1 tràn ngắt, xin vui lòng) cờ vào sổ đăng ký TIMSK1. Giả sử rằng các ngắt của bạn được bật, ISR(TIMER1_OVF_vect) của bạn sẽ được gọi mỗi lần tràn bộ đếm thời gian1.


Chức năng Arduino delay() trông như sau trong mã nguồn (wiring.c):

void delay(unsigned long ms) 
{ 
    uint16_t start = (uint16_t)micros(); 

    while (ms > 0) { 
     if (((uint16_t)micros() - start) >= 1000) { 
      ms--; 
      start += 1000; 
     } 
    } 
} 

Vì vậy, trong nội bộ nó sử dụng micros() chức năng, mà thực sự dựa vào số lượng timer0. Khuôn khổ Arduino sử dụng timer0 để tính mili giây, thực sự, đếm timer0 là khi hàm millis() nhận giá trị của nó.

Chức năng delayMicroseconds(), mặt khác, sử dụng các hoạt động bộ vi xử lý tốt nhất định thời gian để tạo độ trễ; chức năng nào được sử dụng tùy thuộc vào bộ vi xử lý và tốc độ đồng hồ; phổ biến nhất là nop() (không có hoạt động) mà phải mất chính xác một chu kỳ đồng hồ. Arduino Nano sử dụng một đồng hồ 16   MHz, và đây là những gì các mã nguồn trông giống như cho rằng:

// For a one-microsecond delay, simply return. The overhead 
// of the function call yields a delay of approximately 1 1/8 µs. 
if (--us == 0) 
    return; 

// The following loop takes a quarter of a microsecond (4 cycles) 
// per iteration, so execute it four times for each microsecond of 
// delay requested. 
us <<= 2; 

// Account for the time taken in the proceeding commands. 
us -= 2; 

Những gì chúng ta học hỏi từ này:

  • 1 ms chậm trễ không có gì (cuộc gọi chức năng là chậm trễ)
  • Sự chậm trễ lâu hơn sử dụng thao tác dịch chuyển trái để thời gian trễ.
+0

Cảm ơn! Rất vui khi bạn thấy nó hữu ích. – angelatlarge