В прошивке измерителя ёмкости аккумуляторов есть код, который считает время разряда аккумулятора. Этот код я нашёл на одном из форумов посвящённых Arduino тематике и он выглядит довольно простым:
volatile uint8_t runTimeIsr = 0;
uint8_t runTimeLoop;
uint32_t runTime;
// https://gist.github.com/raspberrypisig/8bf856ae9b55bb433d4c11ac9540a881
void timerInit() {
noInterrupts();
// Clear registers
TCCR1A = 0;
TCCR1B = 0;
TCNT1 = 0;
// 1 Hz (16000000/((15624+1)*1024))
OCR1A = 15624;
// CTC
TCCR1B |= (1 << WGM12);
// Prescaler 1024
TCCR1B |= (1 << CS12) | (1 << CS10);
// Output Compare Match A Interrupt Enable
TIMSK1 |= (1 << OCIE1A);
interrupts();
}
ISR(TIMER1_COMPA_vect) {
runTimeIsr += 1;
}
После запуска таймера переменная runTimeIsr считывается в основном цикле и затем обнуляется. Поскольку операция сложения с четырёхбайтной переменной занимает несколько циклов, то используется промежуточная переменная runTimeLoop чтобы избежать конфликта с обработчиком прерывания
void timerDo() {
runTimeLoop = runTimeIsr;
runTimeIsr = 0;
runTime += runTimeLoop;
}
В теории обработчик прерывания должен вызываться каждую секунду если микроконтроллер работает на частоте 16 МГц, но в реальности за 3 часа тестирования время, измеренное микроконтроллером отстало от реального на 35 секунд.
При этом посчитанная ёмкость составила 299 мАч вместо ожидаемых 300 - выглядит как допустимая погрешность, но стало любопытно в чём причина.





