Добрый вечер,
стоит задача производить некое действие один раз в несколько (скажем 10 минут) минут. Для этого кажется логичным использовать прерывание от встроенного таймера, т.к. в остальное время устройство занято другими задачами и варианты с WAIT() или пустыми циклами не проходят. В случае ATMega 328 имеем один 16 разрядный таймер, который при 16 МГЦ кварце и максимальном предделителе 1024 дает максимальную задержку 1024/16 000 000 х 65536 = 4,2 с, т.е. явно мало. При этом на борту имеется еще как минимум один 8-разрядный таймер. В случае железа вопрос решить очень легко: подключить тактовый вход второго таймера к старшему разряду первого, в итоге имеем 16 +8 =24 разрядный таймер с временем переполнения порядка 18 минут, что вполне устраивает. Но в в случае нашего МП все таймеры тактируются от одного генератора и программно реализовать такое подключение по сути нельзя. Зато, учитывая что таймер по сути обычный регистр, в него можно писать значения. Этим я и попытался воспользоваться:
Ledb Alias Portd.7
Config Ledb = Output
Config Timer1 = Timer , Prescale = 1024
Config Timer2 = Timer , Prescale = 1
Ledb = 0
Enable Interrupts
Enable Timer1
Enable Timer2
On Timer2 Pulse
On Timer1 Cycl
Stop Timer2
Do
Loop
End
Cycl:
Incr Timer2
Stop Timer2
Return
Pulse:
Toggle Ledb
Return
В теории каждые четыре секунды происходит прерывание от 16 разрадного таймера в обработке которого на единицу увеличивается значение 8 разрядного тамера, по прерыванию которого выполняется нужное действие. На практике к сожалению это не работает, насколько я смог понять потому, что при переполнении 8 разрядного таймера прерывание не генерируется, видимо из-за того что он увеличивается "вручную".
Вопросы собственно:
1) что здесь не так?
2) есть ли другие способы программного формирования длительных задержек? (Железные часы реального времени просьба не предлагать)
Спасибо!