Blog của Noah Stahl có một ví dụ về việc nhấp nháy đèn LED với Timer2 . Với bảng dữ liệu đó, bạn sẽ có thể điều chỉnh nó theo bất kỳ ngắt nào bạn muốn sử dụng - nghĩa là ngắt có chức năng bình thường mà bạn có thể đủ khả năng nhất để từ bỏ hoặc sẵn sàng sửa đổi. Timer2 thường được sử dụng cho một số chức năng PWM.
Ví dụ của ông trích dẫn ATmega2560; Tôi có thể xác nhận rằng nó cũng hoạt động với ATmega328p. Nhìn xung quanh trang web của anh ấy để biết thêm các ví dụ ngắt Arduino hữu ích.
Biên tập:
Đây là một chút chỉnh sửa của tôi - chủ yếu là trong các nhận xét - phiên bản mã của Nô-ê. Gọi Timer2init () từ chức năng Arduino setup () sau khi bạn khởi tạo mọi cấu trúc dữ liệu hoặc phần cứng có liên quan, vì thời gian - và gián đoạn - sẽ bắt đầu khi bạn thực hiện.
Trước đó, tôi đã sử dụng nó để ghép một màn hình 7 chữ số 3 chữ số để trước khi khởi tạo bộ hẹn giờ, tôi đã khởi tạo các thanh ghi I / O hiển thị và làm trống dữ liệu hiển thị ở nơi ISR sẽ tìm nó.
Có một bảng trong các nhận xét về một số dữ liệu thời gian hữu ích từ bảng dữ liệu và các tính toán của riêng tôi để tham khảo để thiết lập sơ đồ thời gian khác.
Macro ISR () đảm nhiệm việc tạo mã nhập và thoát mã ngắt cho ISR thay vì nhập và thoát của hàm thông thường và liên kết nó với vectơ ngắt thích hợp. Phần còn lại của hàm đó là 1) mã được chạy ở mỗi ngắt và 2) mã mã để đặt lại bộ hẹn giờ cho lần ngắt tiếp theo.
Như đã viết, điều này sẽ rơi vào một bản phác thảo .pde hoặc .ino (hoặc tệp .cpp, nếu bạn sử dụng nhật thực, f / ex). Bản phác thảo cần #define LEDPIN và setup () cần gọi Timer2init (). Hàm lặp có thể trống hoặc không; đèn LED sẽ bắt đầu nhấp nháy khi tải xuống (tốt, theo nghĩa đen, sau khi Timer2init () được gọi).
/*
* 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
};