Деякий час тому ми опублікували більше інформації про функція millis(). de ArduinoЗараз ми заглибимося в Таймер Arduino, щоб розпочати роботу з цією функцією для цієї функції, зрозумійте, як ця плата управляє часом з MCU, а також іншими функціями, крім millis().
Що таке таймер Arduino?
El Таймер Arduino, або таймер, це функція, реалізована апаратним забезпеченням (в мікроконтролері за допомогою кварцового кристала, який генерує тактові імпульси і задає «ритм», без необхідності зовнішнього обладнання чи мікросхем 555), що дозволяє контролювати тимчасові події завдяки годинникам внутрішній. Наприклад, виконувати завдання через певні проміжки часу, проводити точні вимірювання часу тощо, незалежно від коду ескізу.
Уявіть, що ви використовуєте функція delay()., це заблокує виконання на мікроконтролері Arduino до закінчення зазначеного часу, а потім продовжить виконання програми, але таймер не блокується. Це буде час, оскільки MCU продовжує виконувати інші інструкції одночасно. Це велика перевага.
Таймер пов’язаний з перерви Arduino, оскільки вони будуть виконуватися через них для виконання певного завдання. Іншими словами, таймер Arduino - це функція, яка запускається в певний час, виконуючи функцію переривання. Тому також важливо знати про ці перерви.
Режими
Таймер Arduino має 2 режими роботи, мати можливість використовувати його в:
- ШІМ сигнал: Ви можете керувати Виводи Arduino (~).
- CTC (Очистити таймер під час порівняння): підраховує час всередині лічильника, і коли він досягає значення, зазначеного в регістрі таймерів, виконується переривання.
Скільки в ньому таймерів? Типи таймерів
Там 3 таймери на тарілках Arduino UNO, хоча на інших верхніх пластинах може бути більше:
- Таймер 0: 8-бітний, може рахувати від 0 до 255 (256 можливих значень). Використовується такими функціями, як delay(), millis() і micros(). Його модифікація не рекомендується, щоб не змінювати програми.
- Таймер 1: дорівнює Таймеру 0. Використовується бібліотекою Servo в UNO (Таймер 5 для MEGA).
- Таймер 2: 16-розрядний і може варіюватися від 0 до 65.525 65.536 (можливих XNUMX XNUMX значень). Використовується для функції tone(), якщо не використовується, її можна вільно використовувати для вашої програми.
- Таймер 3, 4, 5 (тільки на Arduino MEGA): всі 16-розрядні.
Як працює таймер Arduino?
Уміти працювати з таймером Arduino, важливо знати, як все це працює в електронному вигляді в MCU цієї плати розробника:
- Тактова частота: це кількість циклів в секунду, яку він здатний розвинути, у випадку Arduino це 16 МГц, або що те саме, тактовий сигнал коливається 16.000.000 XNUMX XNUMX разів за секунду (циклів).
- Період: представлено T, вимірюється в секундах і є оберненим до циклів. Наприклад, T=1/C, що призведе до 1/16000000 = 0.0000000625, часу, необхідного для завершення кожного циклу. А частота є оберненою до періоду, тому f = 1/T.
- Цикл: кожне з повторень сигналу, які відбуваються за одиницю часу. На Arduino це буде 16 МБ за секунду. Або що те саме, в даному випадку, коли пройшло 16 мільйонів циклів, пройшла одна секунда. Отже, можна сказати, що один цикл займає 625 нс.
- край сигналу: Сигнали годинника мають квадратну форму, а межі можуть зростати або спадати. Край – це пряма лінія сигналу, коли вона змінюється з:
- 0 (низький) до 1 (високий): висхідний фронт.
- 1 (високий) до 0 (низький): спадний фронт.
Краї важливі, оскільки таймери Arduino вимірюють цикли від фронтів сигналу. А) Так контадор він збільшується з кожним циклом, і коли досягає значення регістра, переривання виконується.
Тому, коли ви це знаєте, якщо знаєте 16 МГц на Arduino MCU, і використовується 8-бітний таймер, можна сказати, що переривання відбуватимуться кожні 16 мкс (256/16000000) або 4 мс для 16-біт (65536/16000000). Тому, якщо встановити 16-розрядний регістр лічильника на максимальне значення зі значенням 65535, то переривання виникне через 4 мс для виконання будь-якого завдання.
Коли лічильник досягне максимально можливого значення, він знову повернеться до 0. Тобто відбувається переповнення, і відлік почнеться з початку.
Для контролю швидкості збільшення таймера також можна використовувати прескейлер, який приймає значення 1, 8, 64, 256 і 1024 і змінює час таким чином:
Швидкість таймера (Гц) = тактова частота Arduino / Prescaler
Якщо це 1, то частота попереднього масштабування регулятора збільшиться до 16 МГц, якщо 8–2 МГц, якщо від 64 до 250 кГц тощо. Пам'ятайте, що буде компаратор стану лічильника таймера, щоб порівняти значення лічильника і попереднього масштабування, поки вони не зрівняються, а потім виконати дію. Так, частота переривань задається за формулою:
Швидкість переривання (Гц) = тактова частота Arduino / Prescaler (значення регістра компаратора + 1)
На щастя, ми не повинні змінювати записи таймерів Arduino, оскільки про це будуть займатися бібліотеки, які ми використовуємо в коді. Але якщо вони не використовуються, їх слід налаштувати.
Приклади в Arduino IDE
Щоб зрозуміти все це трохи краще, тут я показую два ескізних коди для Arduino IDE, за допомогою яких ви можете випробувати використання таймерів. Перший - це код, який щосекунди буде блимати світлодіодом, підключеним до контакту 8 Arduino:
#define ledPin 8 void setup() { pinMode(ledPin, OUTPUT); // Configurar Timer1 TCCR1A = 0; //Registro control A a 0, pines OC1A y OC1B deshabilitados TCCR1B = 0; //Limpia el registrador TCCR1B |= (1<<CS10)|(1 << CS12); //Configura prescaler a 1024: CS12 = 1 y CS10 = 1 TCNT1 = 0xC2F8; //Iniciar timer para desbordamiento a 1 segundo //65536-(16MHz/1024/1Hz - 1) = 49912 = 0xC2F8 en hexadecimal TIMSK1 |= (1 << TOIE1); //Habilitar interrupción para Timer1 } void loop() { } ISR(TIMER1_OVF_vect) //Interrupción del TIMER1 { TCNT1 = 0xC2F7; // Reniciar Timer1 digitalWrite(ledPin, digitalRead(ledPin) ^ 1); //Invierte el estado del LED }
Запрограмуйте миготіння або миготіння світлодіода, як і в попередньому випадку кожну секунду, але цього разу за допомогою CTC, тобто порівняння:
#define ledPin 8 void setup() { pinMode(ledPin, OUTPUT); // Configuración Timer1 TCCR1A = 0; //Registro de control A a 0 TCCR1B = 0; //Limpiar registro TCNT1 = 0; //Inicializar el temporizador OCR1A = 0x3D08; //Carga el valor del registro de comparación: 16MHz/1024/1Hz -1 = 15624 = 0X3D08 TCCR1B |= (1 << WGM12)|(1<<CS10)|(1 << CS12); //Modo CTC, prescaler de 1024: CS12 = 1 y CS10 = 1 TIMSK1 |= (1 << OCIE1A); //Habilita interrupción por igualdad de comparación } void loop() { } ISR(TIMER1_COMPA_vect) //Interrupción por igualdad de comparación en TIMER1 { digitalWrite(ledPin, digitalRead(ledPin) ^ 1); //Invierte el estado del LED }
Детальніше про програмування на Arduino
купити тарілку Arduino UNO Версія 3