sadr0b0t / arduino-timer-api

Cross-platform Arduino timer API
GNU Lesser General Public License v3.0
35 stars 18 forks source link

Провести замеры максимальной частоты вызова прерывания #4

Closed sadr0b0t closed 6 years ago

sadr0b0t commented 6 years ago

Провести замеры максимальной частоты вызова прерывания на разных чипах

sadr0b0t commented 6 years ago

https://github.com/sadr0b0t/arduino-timer-api/commit/c7d54b2b885d2e132274c04fb042563fa791c5bf

Эксперименты с высокими частотами прерываний на разных чипах

cкетч: Examples/timer-api/timer-api-test-max-freq

Для PIC32MX 80МГц самый лучший надежный вариант - 200КГц: целевой период 5мкс совпадает с замерами. На 500КГц (целевой период 2мкс) замер периода показывает 4мкс (в 2 раза больше), но если просуммировать период 1000 циклов, получается 2006мкс, т.е. всего на 6 мкс больше, чем целевое значение (2*1000=2000мкс). Судя по всему, ошибка не накапливается по циклам, а является константой, т.е. скорее всего добавляется на одном из циклов, например, при проведении замера вызовом mikros (т.е. на такой частоте сам замер дает значимую погрешность). Для частоты 1МГц (целевой период 1мкс) ошибка уже накапливается - на 1000 циклов суммарный период получается те же 2005мкс против целевых 1000мкс, т.е. частота для прерываний полностью не рабочая.

Для AVR 16МГц лучший относительно надежный вариант - 20КГц (целевой период - 50мкс): есть кое-какая погрешность +/-4 (на пике 6) микросекунды, но на сумме 2х вызовов период получается почти все время ровно 100мкс. Варианты 50КГц (период 20мкс) и 100КГц (период 10мкс), вообще, тоже работают, но та же погрешность +/4 микросекунды на одном периоде уже становится существенной по сравнений с целевым периодом, хотя на сумме 1000 периодов погрешность остаётся той же константой +/-4мкс. Судя по всему, эти +/4 микросекунды являются допустимой погрешностью при вызове прерывания на этом чипе. Вариант 200КГц (целевой период 5мкс) уже полностью не рабочий: на одном периоде замер показывает те же 12-16мкс, на сумме ошибка не остаётся константой, а нарастает (10 периодов - 84мкс вместо нужных 50ти).

    // period = 1us
    // PIC32MX (ChipKIT Uno32): 3us, x2=5us, x10=21us, x1000=2005us (fail)
    // AVR (Arduino Leonardo): 12/16us, x10=80/84/92us (fail)
    timer_init_ISR_1MHz(TIMER_DEFAULT);
    // period = 2us
    // PIC32MX (ChipKIT Uno32): 4us, x2=6us, x10=22us, x1000=2006us (+2-6us, ~fail)
    // AVR (Arduino Leonardo): 12/16us, x10=84us (fail)
    timer_init_ISR_500KHz(TIMER_DEFAULT);
    // period = 5us
    // PIC32MX (ChipKIT Uno32): 5us, x10=50us (ok)
    // AVR (Arduino Leonardo): 12/16us, x2=20us, x10=84us (fail)
    timer_init_ISR_200KHz(TIMER_DEFAULT);
    // period = 10us
    // PIC32MX (ChipKIT Uno32): 10us (ok)
    // AVR (Arduino Leonardo): 12us, x2=20us, x10=100/104/108us, x1000=10000  (~ok)
    timer_init_ISR_100KHz(TIMER_DEFAULT);
    // period = 20us
    // PIC32MX (ChipKIT Uno32): 20us (ok)
    // AVR (Arduino Leonardo): 12/20/24us, x2=40/44/48us, x1000=19996/20000/20004 (~ok)
    timer_init_ISR_50KHz(TIMER_DEFAULT);
    // period = 50us
    // PIC32MX (ChipKIT Uno32): 50us (ok)
    // AVR (Arduino Leonardo): 48/52/56us, x2=100us (ok)
    timer_init_ISR_20KHz(TIMER_DEFAULT);
    // period = 100us
    // PIC32MX (ChipKIT Uno32): 100us (ok)
    // AVR (Arduino Leonardo): 96/100/104us, x2=200/204us (ok)
    timer_init_ISR_10KHz(TIMER_DEFAULT);