Запуск функции с заданной частотой
- Войдите на сайт для отправки комментариев
Пнд, 11/04/2016 - 23:35
В этой - http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-bl... - теме подробно описывается, как инвертировать определённый пин по прерыванию, но не понятно, как по нему запускать процедуру.
Или я не нашел, гдк это описано.
Помогите, пожалуйста, нужно выполнять определённые команды через равные зсданные промежутки времени (раз в 3750 мсек).
Вызывай функцию в обработчике прерывания таймера, например:
Естественно, перед этим нужно настроить сам таймер и разрешить прерывания.
Да, можно так. А посмотреть как это делается можно открыв wiring.c "из коробки". Там есть работа и настройка только нулевого таймера и на обруботку переполнения счетчика. Для такой большой задержки ещё можно воспользоваться макросом everyOVF(). Но его точная периодичность вызова - кооперативная и зависит от остальной части программы.
А чем занят основной цикл, что для 3750 мсек таймер задействуется? Может достаточно
Вычисляется текущий каденс. Нагуглил тему [на сайте, похожем на хабр], посмотрел и понял, что код там совсем не код. Пишу свой:
https://gist.github.com/ircphp/ec427a16e0ab5cb9269b9175379d62a8
хотелось бы максимально точно и оптимально считать каденс, не прибегая к усреднению, но чем меньше промежуток его подсчета тем ниже точность. Раз в 4 секунды, вроде, похоже на правду, но все равно мне кажется, что считает он не очень точно.
Тестирую на Atmega128, вместо геркона использую кнопку, но работать будет на Atmega328 и, кроме указанного кода, там еще будет чтение из последовательного порта и запись на SD-карту.
Уже и это почитал - http://avrprog.blogspot.com/2013/03/t2-8.html - всё равно не понятно.
Оставлю, навенрое, как етсь - и так работает.
Нашел почти готовте решение в теме о разряде аккумулятора.
Теперь осталос понять, как уснанавливать значение TCNT1, чтобы получить требуемую задержку - 3750 мсек...
Счётчик считает инкрементом до переполнения, при переполнении вывзывается функция ISR (TIMER1_OVF_vect). Переполнение наступает когда счётчик доходит до 1111111111111111 - 65535. Таким образом, 65535 минус 3036 (значение из скрипта равное задержке 4 сек) = 62499 инкрементов счётчика. Из пропорции:
62499 - 4000 мсек
58592 - 3750 мсек
Для запуска функции с периодом раз в 3750 мс, нужно щёлкать 58592 тактов, а значение CLK_INIT_VAL должно быть 65535-58592=6943=0b0001101100011111.
Проверил - работает:
nkk, решение слегка кривовато. У таймера есть специальный режим сброс по совпадению (CTC).
Забавно:
Переписал скрипт, чтобы выводило только i если a-b != 3750, - выводит те же строки: 6, 8, 14, 18, 22, 27, 30
Вот пришел в ступор от таймеров.
Два примера:
Таймер Т1 код:
Тот же код переделанный для таймера Т2
У меня для таймера Т2 получается задействовать, или счетчик, или пресаклер, а мне нужно таймер Т2 с счетчиком и пресаклером. Что я делаю не так. Может у таймера Т2 какая то особенность.
Okmor, не ясно по какому принципу вы переделывали. 4 строкой второго скетча вы задаёте несуществующий режим для таймера 2 , (даташит страница 155, Table 18-8. Waveform Generation Mode Bit Description ) и прескалер тоже не на 1024, а на 32.
Вот.
Тут есть особенности. Не знаю документировано ли, но таймер Т2 в режиме СТС самостоятельно не обнуляется, потому использование параметра (1<<WGM21) бессмысленно. Может кто то объяснит где я ошибся.
Дял всех оставлю этот кусок работающего таймера с счетчиком и пресаклером.
dimax. Спасибо за наводку.
таймер Т2 в режиме СТС самостоятельно не обнуляется, потому использование параметра (1<<WGM21) бессмысленно. Может кто то объяснит где я ошибся.
Да, маленькая ошибочка у вас, поэтому и не обнуляется. Бит WGM21 "приписан" к регистру TCCR2A, а вы его пытались внести в регистр TCCR2B, поэтому он и не включался.
вам надо выполнять команду раз в 3750 милисек (3.750)секунды или раз в 3750 микросекунд.
Если первый вариант то лучше так.
или раз в 3750 микросекунд.
3750000 микросекунд