Преди време публикувахме повече информация за функция millis(). de ArduinoСега ще се задълбочим по-дълбоко в Таймер на Arduino, за да започнете с тази функция за функцията, разберете как тази платка управлява времето с MCU, както и други функции извън millis().
Какво представлява таймерът на Arduino?
El Таймер на Arduino или таймер, е функция, реализирана от хардуер (в микроконтролера, с помощта на кварцовия кристал, който генерира часовниковите импулси и който задава "ритъма", без нужда от външен хардуер или ИС 555), която позволява контролиране на временни събития благодарение на часовниците вътрешни. Например, правене на задача да се изпълнява на интервали, извършване на точни измервания на времето и т.н., независимо от кода на скицата.
Представете си, че използвате функция закъснение()., това ще блокира изпълнението на Arduino MCU, докато изтече определеното време и след това ще продължи с програмата, но таймерът няма да блокира. Това ще бъде времето, тъй като MCU продължава да изпълнява други инструкции едновременно. Това е голямото предимство.
Таймерът е свързан с прекъсвания на Arduino, тъй като те ще бъдат изпълнени чрез тях, за да присъстват на някаква конкретна задача. С други думи, таймерът на Arduino е функция, която се задейства в определен момент, изпълнявайки функция за прекъсване. Ето защо също е важно да знаете за тези прекъсвания.
Режими
Таймерът Arduino има 2 режима на работа, като можете да го използвате в:
- PWM сигнал: Можете да контролирате щифтове на Arduino (~).
- CTC (Изчистване на таймера при съвпадение за сравнение): отчита времето вътре в брояч и когато достигне стойността, посочена в регистър на таймерите, прекъсването се изпълнява.
Колко таймера има? Видове таймери
там 3 таймера върху чиниите Arduino UNO, въпреки че може да има повече на други горни плочи:
- Таймер 0: 8-битов, може да брои от 0 до 255 (256 възможни стойности). Използва се от функции като delay(), millis() и micros(). Не се препоръчва нейната модификация, за да не се променят програмите.
- Таймер 1: равен на таймер 0. Използва се от серво библиотеката в UNO (таймер 5 за MEGA).
- Таймер 2: 16-битова и може да варира от 0 до 65.525 65.536 (XNUMX XNUMX възможни стойности). Използва се за функцията tone(), ако не се използва, може да се използва свободно за вашето приложение.
- Таймер 3, 4, 5 (само на Arduino MEGA): всички 16-битови.
Как работи таймерът на Arduino?
Към работа с таймер Arduino, жизненоважно е да знаете как всичко това работи по електронен път в MCU на тази платка за разработка:
- Тактова честота: е броят на циклите в секунда, които е способен да развие, в случая на Arduino е 16 Mhz, или каквото е същото, часовниковият сигнал осцилира 16.000.000 XNUMX XNUMX пъти в секунда (цикли).
- periodo: се представя от T и се измерва в секунди и е обратното на циклите. Например, T=1/C, което ще доведе до 1/16000000 = 0.0000000625, времето, необходимо за завършване на всеки цикъл. А честотата е обратна на периода, така че f = 1/T.
- цикъл: е всяко едно от повторенията на сигнала, които се случват за единица време. На Arduino това ще бъде 16M в секунда. Или какво е същото, в този случай, когато са минали 16 милиона цикъла, е изминала една секунда. Следователно може да се каже, че един цикъл отнема 625 ns.
- ръб на сигнал: Сигналите на часовника са квадратни, а ръбовете могат да се повишават или намаляват. Ръбът е правата линия на сигнала, когато се промени от:
- 0 (ниско) до 1 (високо): нарастващ ръб.
- 1 (високо) до 0 (ниско): падащ ръб.
Ръбовете са важни, защото таймерите на Arduino измерват цикли от ръбовете на сигнала. А) Да контадорът той се увеличава с всеки цикъл и когато достигне стойността на регистъра, прекъсването се изпълнява.
Следователно, след като знаете това, ако имате 16Mhz на Arduino MCUи се използва 8-битов таймер, може да се каже, че прекъсванията ще се случват на всеки 16 μs (256/16000000) или 4 ms за 16-битов (65536/16000000). Следователно, ако зададете 16-битовия регистър на брояча на максимум, със стойност 65535, тогава прекъсването ще се случи на 4 ms, за да изпълни каквато и да е задача.
Когато броячът достигне максималната възможна стойност, отново ще се върне на 0. Тоест възниква препълване и то ще се брои обратно от началото.
За да контролирате скоростта на нарастване на таймера, можете също да използвате предварителен скалер, който приема стойности 1, 8, 64, 256 и 1024 и променя времето по следния начин:
Скорост на таймера (Hz) = тактова честота на Arduino / Prescaler
Ако е 1, прескалерът ще се увеличи до 16 Mhz, ако е 8 до 2 Mhz, ако е 64 до 250 kHz и т.н. Не забравяйте, че ще има компаратор на състоянието на брояча на таймера, който да сравнява стойността на брояча и прескалера, докато не се изравнят и след това да изпълни действие. Така, честота на прекъсване се дава по формулата:
Скорост на прекъсване (Hz) = Тактова честота на Arduino / Prescaler (стойност на регистъра за сравнение + 1)
За щастие не трябва променят записи на таймерите на Arduino, тъй като за него ще се погрижат библиотеките, които използваме в кода. Но ако не се използват, те трябва да бъдат конфигурирани.
Примери в Arduino IDE
За да разберете всичко това малко по-добре, тук показвам два кода за скица за Arduino IDE, с които можете да изпитате използването на таймери. Първият е код, който ще мига светодиод, свързан към Arduino пин 8 всяка секунда:
#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 Rev3