Мені необхідно виконувати деякі дії з певною регулярністю, тому оптимальним рішенням є використання апаратних таймерів. Досить грунтовну інформацію знайшов у матеріалі Timer Interruptions. Використовуючи її, та деякі інші напрацювання, написав скетч "блимання" світлодіодом з використанням переривання таймеру:
Код: Виділити все
// https://radioman.com.ua/viewtopic.php?f=8&t=45
bool A_STATE = true; // статус 13 виводу
void setup ( )
{
pinMode ( 13, OUTPUT ) ;
// ініціалізація Timer1
cli ( ) ; // відключити глобальні переривання
TCCR1A = 0 ; // встановити регістр 1A в 0
TCCR1B = 0 ; // встановити регістр 1B в 0
// Таймер переповнюється кожні 65535 відліків при дільнику 1024 або за 4,194с
// Частота переривань = 16000000 / (1024 * (1 + 15624) = 1 s
OCR1A = 15624 ; // встановлення регістру збігу (1 секунда)
TCCR1B |= ( 1 << WGM12 ) ; // увімкнути CTC режим > скидання таймера за збігом
TCCR1B |= ( 1 << CS10 ) ; // встановити біт CS10 CS12 на дільник 1024
TCCR1B |= ( 1 << CS12 ) ;
TIMSK1 |= ( 1 << OCIE1A ) ; // включити переривання зі збігом таймера
sei ( ) ; // включити глобальні переривання
}
void loop ( )
{
/* програма */
}
ISR ( TIMER1_COMPA_vect ) // Викликається ISR (TIMER1_OVF_vect), це відбувається завжди коли таймер переповнюється
{
A_STATE = !A_STATE; // Інвертуємо статус світлодіода
digitalWrite(13, A_STATE); // Виводимо нове значення на 13 контакт
}