как использовать таймер в определенное время?

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

Здравствуйте, помогите пожалуйста, уже всю голову сломал как построить логику, смысл такой:

1) имеется код с очень нужными задержками на связь. не хочу пока переделывать полностью без задержек, переписывать придётся все  строк... и тут я вспомнил, что нигде не применял таймеры. из за этих задержек не вовремя мигает светодиод, выставлен через каждые 4 секунды зажечься на пол секунды. так вот в некоторые моменты проверок модема, "подвисает" на включенном или выключенном состоянии, этот светодиод. но светодиод должен работать как статусный, т.е. по нему видно что твориться сейчас с микроконтроллером, поэтому он может начать моргать через 10-15 даже секунд но строгое количество раз. 

Вот допустим мне надо что бы светодиод проморгал 3 раза, пол секунды включить, через 3.

Потом другая ситуация, мне надо что бы моргал бесконечно пока его не выключат, через пол секунды через 5.

потом проморгал 2 раза. и т.д. 

так вот вопрос, ответ вроде чувствую на поверхности, надо создать таймер, в нем написать функцию и условие, и что бы таймер каждые 0.01 сек. залазил и проверял, потом где то в коде разрешать таймеры и задавать параметры в функции. но с другой стороны надо что бы это происходило моментально. не затрагивая основного кода, ну или с минимально возможной задержкой.

А еще у меня присутствуют внешне прерывания. (Вдруг важно)

свой код с 2987 строками и 99% занятой флеш памяти думаю смысла нет выкладывать. если надо выложу.. но мне стыдно за него, начинал писать как только учился, много ляпов там, но это работает)) а полностью переписывать думаю смысла нет, так как еще не все приемы изучил

и еще:

2) есть прерывания внешние, так вот там более мне хорошо но вот из за задержек в основном коде - тоже проблемы. в общем брелок считывает код безупречно, спасибо помогли тоже на форуме, задает флаг что ключ брелка полностью получен и готов к дальнейшим действиям, в лупе есть функция которая смотрит, пришел ли код, но пока до этой функции дойдет время, пройдет "вечность" знаю что нельзя загружать функцию прерывания, но мне надо выполнить несколько действий все же. могу ли я в прерываниях не просто задавать флаг, а после успешного считывания ключа сразу лететь выполнять? т.е. останавливать основной код переходить на следующую функцию. делеев там нет. только миллис. т.е. в дальнейшем не надо просто поднимать флаги и включать выставлять пару пинов в значение HIGH или LOW.

 
andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

Если Вам нужно, скажем, зажечь или погасить светодиод, нет никаких противопоказаний сделать это в прерывании.

Собственно, код в прерывании имеет ограничения по времени выполнения:

1. Максимальное время исполнения кода в прерывании должно быть строго меньше интервала между прерываниями (желательно в 2 или более раз).

2. Время исполнения кода в прерывании должгно быть таково, чтобы не вносить искажений в процессы, чувствительные ко времени.

Примеры:

При вызове прерывания 100 раз в секунду время его исполнения не должно превосходить 5 мс.

Если мы работает с чем-то вроде SoftSerial на частоте 9600, то на передачу одного бита приходится примерно 100 мкс, поэтому время исполнения прерывания не должно превосходить 50 мкс.

 

В общем - все, исходя из здравого смысла. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

d13lider пишет:

Вот допустим мне надо что бы светодиод проморгал 3 раза, пол секунды включить, через 3.

мои таймеры позволяют лехко это сделать, не таща за собой лишние сучности. 

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

andriano пишет:

Если Вам нужно, скажем, зажечь или погасить светодиод, нет никаких противопоказаний сделать это в прерывании.

 

В общем - все, исходя из здравого смысла. 

понял, т.е. несколько флагов я поднять могу там. этого вполне достаточно

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

DetSimen пишет:

мои таймеры позволяют лехко это сделать, не таща за собой лишние сучности. 

это очень хорошо, я рад что вы представляете логику программ так просто))

b707
Offline
Зарегистрирован: 26.05.2017

d13lider пишет:

Вот допустим мне надо что бы светодиод проморгал 3 раза, пол секунды включить, через 3.

Потом другая ситуация, мне надо что бы моргал бесконечно пока его не выключат, через пол секунды через 5.

потом проморгал 2 раза. и т.д. 

так вот вопрос, ответ вроде чувствую на поверхности, надо создать таймер, в нем написать функцию и условие, и что бы таймер каждые 0.01 сек. залазил и проверял, потом где то в коде разрешать таймеры и задавать параметры в функции. но с другой стороны надо что бы это происходило моментально. не затрагивая основного кода, ну или с минимально возможной задержкой.

 

в своем первом большом проекте как раз решал эту же задачку. Если надо, могу и код поискать, пока на словах:

Принцип следующий - пишете битовую последовательность, в которой 1 означает диод включен, 0 - выключен. Тогда 01010101 - будет означать мигание диодом с равными периодами, 011011011 - мигание, когда диод включен в 2 раза дольше, чем выключен и тд Таким образом можно любые сложные сигналы кодировать, хоть "SOS" диодом промигать.

Работает это просто - настраиваете прерывания по любому системному таймеру, скажем, раз в 1мс. В прерывании увеличиваете счетчик, скажем, до значения 500. Раз в 500мс берете очередную цифру из бинарной последовательности и если там единица - зажигаете диод, если ноль - гасите.

Работает четко, просто - и совершенно независимо от задержек основной программы.

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

b707 пишет:

в своем первом большом проекте как раз решал эту же задачку. Если надо, могу и код поискать, пока на словах:

Принцип следующий - пишете битовую последовательность, в которой 1 означает диод включен, 0 - выключен. Тогда 01010101 - будет означать мигание диодом с равными периодами, 011011011 - мигание, когда диод включен в 2 раза дольше, чем выключен и тд Таким образом можно любые сложные сигналы кодировать, хоть "SOS" диодом промигать.

Работает это просто - настраиваете прерывания по любому системному таймеру, скажем, раз в 1мс. В прерывании увеличиваете счетчик, скажем, до значения 500. Раз в 500мс берете очередную цифру из бинарной последовательности и если там единица - зажигаете диод, если ноль - гасите.

Работает четко, просто - и совершенно независимо от задержек основной программы.

ага, вот я так и думал что ответ на поверхности. не мог правльно сформулировать.но все равно еще остатеься непонятно как мигать до тех пор, пока не дам команду остановиться мигать, т.е. получаеться надо сделать небольшой цикл, но как правильно его реализовать в функции таймера... как флаг правильно задать что начался цикл

b707
Offline
Зарегистрирован: 26.05.2017

d13lider пишет:

ага, вот я так и думал что ответ на поверхности. не мог правльно сформулировать.но все равно еще остатеься непонятно как мигать до тех пор, пока не дам команду остановиться мигать

либо флаг, либо, например, перключить мигалку на последовательность 00000000000000

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

d13lider пишет:
ага, вот я так и думал что ответ на поверхности. не мог правльно сформулировать.но все равно еще остатеься непонятно как мигать до тех пор, пока не дам команду остановиться мигать, т.е. получаеться надо сделать небольшой цикл, но как правильно его реализовать в функции таймера... как флаг правильно задать что начался цикл
Изучайте автоматы. Флаги конечно похожи на примитивные автоматы, но не помогают выработать подход к программированию таких задач.

d13lider
d13lider аватар
Offline
Зарегистрирован: 19.10.2015

qwone пишет:

Изучайте автоматы. Флаги конечно похожи на примитивные автоматы, но не помогают выработать подход к программированию таких задач.

а можно по пдробнее?

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

d13lider пишет:

qwone пишет:

Изучайте автоматы. Флаги конечно похожи на примитивные автоматы, но не помогают выработать подход к программированию таких задач.

а можно по пдробнее?

 

Только что давал эту ссылку в другой теме: https://ru.wikipedia.org/wiki/%D0%9A%D0%BE%D0%BD%D0%B5%D1%87%D0%BD%D1%8B%D0%B9_%D0%B0%D0%B2%D1%82%D0%BE%D0%BC%D0%B0%D1%82

qwone
qwone аватар
Offline
Зарегистрирован: 03.07.2016

  Как вариант #258  Мне просто не хочется в этой теме тоже самое расжевывать