Приветствую! Вопрос про Timer_1 в Arduino Nano на базе процессора ATMega 328P. Программирую в Arduino IDE.
Подскажите, пожалуйста, как правильно с помощью команд на C/C++ включить таймер и считывать с него миллисекунды внутри функции прерывания ISR(PCINTx_vect) (прерывание по пину), при этом чтобы он не переполнялся хотя бы секунд 30.
Стандартные функции языка Arduino и функции библиотеки GyverTimers ориентированы на работу со временем по прерываниям, мне же нужно, чтобы функция ISR(PCINTx_vect) оставалась активной всё время выполнения алгоритма, а в режиме сна отсчёт времени не нужен вообще. Функциями setup() и loop() не пользуюсь.
Предварительная версия программы организована также, но "отсчитывает" время по количеству выполненных циклов. Проблема в том, что в зависимости от условий алгоритм одного цикла состоит из разного количества операторов, что приводит к непредсказуемости времени работы, а время нужно точное. Предварительная версия работает вполне исправно, если закрыть глаза на то, что весь алгоритм может работать 5 секунд вместо 6 и наоборот. Идентичная (с поправкой на другие регистры, тактирующую частоту и предделители таймера) программа для MSP430 также исправно работает.
В функции main() - только отключение WatchDog, инициация пинов и переход в режим сна со следующими параметрами:
В функции прерывания по пину пытаюсь активировать таймер таким образом:
Текущее значение таймера в цикле получаю через
Перед завершением функции прерывания - выключение таймера:
Согласно даташиту ATMega 328P, при таких настройках значение переменной timer в цикле должно приблизительно равняться количеству миллисекунд, прошедшему с момента включения таймера минус время, прошедшее с последнего присваивания: тактирующая частота 1Mhz, предделитель таймера на 1024, итого - около 977 прибавлений к регистру TCNT1 в секунду, переполнение чуть больше, чем через минуту.
По всей видимости, в реальности значение отличается, причём критически, т.к программа в лучшем случае работает не то время, которое ожидается, в худшем - вообще не срабатывает.
Программатора нет, и я не умею (в общем-то новичок в теме) без него "подсмотреть" значения переменных, при этом проект одноразовый, поэтому о приобретении или сборке программатора речь не идёт. Возможно, кто-то может подсказать, что не так с настройками? Заранее спасибо.
Подскажите, пожалуйста, как правильно с помощью команд на C/C++ включить таймер и считывать с него миллисекунды внутри функции прерывания ISR(PCINTx_vect) (прерывание по пину), при этом чтобы он не переполнялся хотя бы секунд 30.
Стандартные функции языка Arduino и функции библиотеки GyverTimers ориентированы на работу со временем по прерываниям, мне же нужно, чтобы функция ISR(PCINTx_vect) оставалась активной всё время выполнения алгоритма, а в режиме сна отсчёт времени не нужен вообще. Функциями setup() и loop() не пользуюсь.
Предварительная версия программы организована также, но "отсчитывает" время по количеству выполненных циклов. Проблема в том, что в зависимости от условий алгоритм одного цикла состоит из разного количества операторов, что приводит к непредсказуемости времени работы, а время нужно точное. Предварительная версия работает вполне исправно, если закрыть глаза на то, что весь алгоритм может работать 5 секунд вместо 6 и наоборот. Идентичная (с поправкой на другие регистры, тактирующую частоту и предделители таймера) программа для MSP430 также исправно работает.
В функции main() - только отключение WatchDog, инициация пинов и переход в режим сна со следующими параметрами:
C:
PRR |= 0xEF; // Отключение периферии для экономии энергии
SMCR |= 0x04; // Режим сна Power-down
while(1) {
SMCR |= 0x01; // Разрешение режима сна
asm("sleep"); // Уход в режим сна
}
C:
TCCR1B |= 0x05; // Выбор предделителя на 1024
PRR &= ~0x08; // Включение Timer_1
timer = TCNT1;
(timer переменная типа unsigned long, погрешность в пределах времени выполнения одного-двух циклов для моей задачи вполне допустима).Перед завершением функции прерывания - выключение таймера:
C:
PRR |= 0x08; // Выключение Timer_1
TCNT1 = 0x00; // Сброс регистра отсчёта Timer_1
По всей видимости, в реальности значение отличается, причём критически, т.к программа в лучшем случае работает не то время, которое ожидается, в худшем - вообще не срабатывает.
Программатора нет, и я не умею (в общем-то новичок в теме) без него "подсмотреть" значения переменных, при этом проект одноразовый, поэтому о приобретении или сборке программатора речь не идёт. Возможно, кто-то может подсказать, что не так с настройками? Заранее спасибо.
Изменено: