В прошивке измерителя ёмкости аккумуляторов есть код, который считает время разряда аккумулятора. Этот код я нашёл на одном из форумов посвящённых 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 - выглядит как допустимая погрешность, но стало любопытно в чём причина.
Кварцевый резонатор перед установкой на плату измерял тестером кварцев и он показал 15,999 МГц. На всякий случай проконтролировал частоту осциллографом - щуп осциллографа переключается в режим 10Х (чтобы снизить влияние ёмкости щупа на генератор микроконтроллера) и подключается к ножке XTAL2 (выход генератора частоты микроконтроллера)
Курсорные измерения показывают частоту 15,92 МГц, но это с округлением. Есть период колебания 62,8 наносекунды (BX - AX) и я могу вычислить частоту как F = 1 / (62,8 * 10^-9) = 15923566 Гц.
Таким образом значение OCR1A в коде нужно скорректировать на 15549 (15923566 / 1024 - 1 = 15549). Заливаю обновленную прошивку и оставляю на час поработать. В результате измеренное время опередило реальное на 11 секунд за один час тестирования.
Сделал несколько тестов каждый раз уточняя значение OCR1A. В итоге мне это надоело и я добавил на плату микросхему часов реального времени DS1307. Из всего функционала этой микросхемы используется только сигнал 1 Гц, который подключён ко входу прерывания INT0.
Батарейка резервного питания не используется. При инициализации часов реального времени устанавливается дата и время изменения прошивки.За один час тестирования измеренное время отстало от реального на 2 с. Чтобы понять виноват сейчас часовой кварц или алгоритм нужно сравнить показания времени RTC с тем что считает по таймеру.
Комментариев нет:
Отправить комментарий