Youtube-запись от 2025-08-15: https://youtu.be/_HQXhSQyEck
Ходят слухи, что не всякий код можно писать внутри обработчика прерывания
...
int tick_g = 0;
int sec_g = 0;
#define TICKS_IN_SEC 8
#define WAIT_TO_ALIGN 300
#define RAND_ARRAY_LEN 100
float * a_g[RAND_ARRAY_LEN] = NULL;
...
// выделили память под a_g
// реализовали float randomize()
...
ISR(TIM0_OVF_vect) {
delay(WAIT_TO_ALIGN);
tick_g++;
if (tick_g % TICKS_IN_SEC) {
sec_g++;
a_g[sec_g] = malloc(sizeof(float));
*(a_g[sec_g]) = randomize();
printf("%d: %f\n", sec_g, a_g[sec_g]);
}
}delay()затягивает любое дело- Что происходит при переполнении типов?
- Деление — дорогая операция
- Только
malloc()нам тут и не хватало — да ещё и без проверок - Динамическая память всегда в зоне риска
float— тяжеловесный тип данныхfloat randomize()— вряд ли быстрая функцияprintf()всегда неспешен (и спасибо, что не в файл пишем)- Мы так надеемся на актуальность
tick_gиsec_g— а зря - Вдруг кто-то ещё полезет в массив
a_g?
Ну и просто буквы выглядят некрасиво, а это важно
Время
Ресурсы
Доступы
Скорость
flowchart TB
counter(Счётчики):::green
flag(Флаги):::yellow
subgraph Основной_код
counter_main((•)):::green
flag_main((•)):::yellow
end
subgraph Прерывание
counter_isr((•)):::green
flag_isr((•)):::red
end
counter_main <==> counter <==> counter_isr
flag_main <==> flag <-.-> flag_isr
classDef green fill:#B8BA46;
classDef red fill:#FE8019;
classDef yellow fill:#FABD2F;
Связь есть!
ISR(TIMER1_COMPA_vect) {...}
...
OCR1A = ...; // порог срабатывания
// Включаем прерывание Compare Match A
TIMSK1 |= _BV(OCIE1A);
// Старт таймера с делителем 1
TCCR1B |= _BV(CS10);ISR() {
cnt_g++;
}
int main() {
if(cnt_g > MAX_CT) cnt_g = 0;
}Через маски это быстро. Кстати, и флаги тоже.
ISR() {
if (cnt & 15) {
another_cnt++;
}
flags |= 1 << IMPORTANT_FLAG;
}static uint8_t prev;
uint8_t cur = TCNT1;
uint8_t dt = (uint8_t)(cur - prev); // корректно через переполнение
prev = cur;ISR() {
counter++;
if(!(counter & (0x3))) {...}
}typedef struct {
uint8_t count;
uint8_t reload;
} sw_timer_t;
volatile sw_timer_t timer1 = {0, 50}; // каждые 50 переполнений
volatile sw_timer_t timer2 = {0, 200}; // каждые 200 переполнений
ISR(TIM0_OVF_vect) {
if (timer1.count) timer1.count--;
if (timer2.count) timer2.count--;
}
int main(void) {
if(timer1.count > timer1.reload) timer1.count = timer1.reload;
if(timer2.count > timer2.reload) timer2.count = timer2.reload;
}ISR() {
cli();
...
sei();
}Это только самая-самая база. Там море нюансов. Особенно в ESP32.