Всем привет.
Вопрос следующий - есть задача сделать реле времени на МК.
Управление двумя нагрузками, периодичность:
Первое устройство - 30 мин. работает, 30 мин. выключено;
Второе устройство - 45 мин. работает, 15 мин. выключено.
Имеем цикл в 1 час (60 минут) для обоих устройств.
Мое виденье алгоритма такое:
{
-Ждем 1000 миллисекунд;
-Инкрементируем переменную типа Integer (например, I);
-Проверяем переменную:
--Если I==1800 То PORTA.1=0;
--Eсли I==2700 To PORTB.1=0;
--Eсли I==3600 To PORTA.1=1; PORTB.1=1; I=0;
-Переходим к началу цикла.
}
Вобщем, на мой взгляд, работать должно, но - он-то отсчитает 1000 мс, но и на обработку команд ему надо время. Нужно подбирать значение задержки, что не есть очень гуд. Хотелось бы большей точности, и без возни. Стоит уточнить, что допуск +/- 1 минута.
Ну, а теперь вопрос - может кто-нить предложить более "правильный", с точки зрения контроллера, алгоритм? Например, таймер использовать (проблема в том, что опыта работы с таймером нету, т.к. контроллеры только начинаю осваивать).
Спасибо.
Реле времени. Вопрос по алгоритму.
Реле времени. Вопрос по алгоритму.
Never argue with an idiot. They bring you down to their level, then beat you with experience!!!
Какой микроконтроллер? Какая среда разработки?
Если делать, например, на ATtiny2313, то можно так. Для стабилизации тактовой частоты использовать кварц. Установить для таймера1 режим CTC. Прескалер таймера и число в регистре сравнения, до которого он будет считать, подобрать так, чтобы перезапуск таймера происходил 1 раз в секунду. Настроить прерывание от таймера, которое называется "Compare A Match". Прерывание будет происходить 1 раз в секунду. В обработчике прерывания декрементировать счётчики.
В главной программе:
включть нагрузку1 задать значение счётчика1
включть нагрузку2 задать значение счётчика2
В основном цикле проверять, досчитал ли счётчик до нуля. Если да, то выключить нагрузку, и задать счётчик паузы. Потом проверять счётчик паузы... и т.д.
Если делать, например, на ATtiny2313, то можно так. Для стабилизации тактовой частоты использовать кварц. Установить для таймера1 режим CTC. Прескалер таймера и число в регистре сравнения, до которого он будет считать, подобрать так, чтобы перезапуск таймера происходил 1 раз в секунду. Настроить прерывание от таймера, которое называется "Compare A Match". Прерывание будет происходить 1 раз в секунду. В обработчике прерывания декрементировать счётчики.
В главной программе:
включть нагрузку1 задать значение счётчика1
включть нагрузку2 задать значение счётчика2
В основном цикле проверять, досчитал ли счётчик до нуля. Если да, то выключить нагрузку, и задать счётчик паузы. Потом проверять счётчик паузы... и т.д.
Контроллер - Мега 8. Среда разработки - CodeVisionAVR.
Знаю, что мега-8 с большим запасом, но он есть в наличии, а устройство нужно в одном экземпляре.
Ткните, пожалуйста, носом, где почитать про использование таймера в атмегах. Если бы там еще были примеры, было бы просто здорово - на примерах проще учить:)
Еще добавлю.
1. Я думаю, можно использовать внутренний осциллятор, ибо точность на цикле допускается в 1 минуту туда-обратно. Хотя, конечно, если это достижимо на встроенном осцилляторе.
2. Вопрос - а почему декрементировать счетчики? Имхо логичнее инкрементировать, и ловить не "0", а "1800", или что-то еще. Или я неправ?
Просьба не пинать, ибо нуб.
Спасибо.
Знаю, что мега-8 с большим запасом, но он есть в наличии, а устройство нужно в одном экземпляре.
Ткните, пожалуйста, носом, где почитать про использование таймера в атмегах. Если бы там еще были примеры, было бы просто здорово - на примерах проще учить:)
Еще добавлю.
1. Я думаю, можно использовать внутренний осциллятор, ибо точность на цикле допускается в 1 минуту туда-обратно. Хотя, конечно, если это достижимо на встроенном осцилляторе.
2. Вопрос - а почему декрементировать счетчики? Имхо логичнее инкрементировать, и ловить не "0", а "1800", или что-то еще. Или я неправ?
Просьба не пинать, ибо нуб.
Спасибо.
Never argue with an idiot. They bring you down to their level, then beat you with experience!!!
Мяу всем..
Имеем цикл в 1 час (60 минут) для обоих устройств.
Это период - 1 час, а цикл тут может быть 15 минут..
Т.е. имеем период их 4-х циклов..
1-цикл включены оба устройства,
2-цикл включены оба устройства,
3-цикл устр.1 - вкл, устр.2 - выкл,
4-цикл устр.1 - выкл, устр.2 - выкл.
Таким образом имеем минимальную дискретность 15 минут и счётчик циклов = 4...
Если не надо что-то менять в алгоритме, то считать минуты - вовсе не обязательно...
Имеем цикл в 1 час (60 минут) для обоих устройств.
Это период - 1 час, а цикл тут может быть 15 минут..
Т.е. имеем период их 4-х циклов..
1-цикл включены оба устройства,
2-цикл включены оба устройства,
3-цикл устр.1 - вкл, устр.2 - выкл,
4-цикл устр.1 - выкл, устр.2 - выкл.
Таким образом имеем минимальную дискретность 15 минут и счётчик циклов = 4...
Если не надо что-то менять в алгоритме, то считать минуты - вовсе не обязательно...
О, спасибо за быстрый ответ:)
Итак, насколько я понял, можно использовать мой алгоритм, но считать не до 3600, а до 900 секунд? Как это отразится на точности? Хотелось бы просто отбросить изначально неправильные варианты, а потом выбрать самый простой и надежный.
Спасибо еще раз.
ЗЫ: Кстати, нашел вот тут: http://radiokot.ru/forum/viewtopic.php?t=13499 более-менее внятную инструкцию работе с таймером. В частности, упоминается часовой кварц на 32768 Гц - если переключить МК на внешний кварц, как он будет работать на такой частоте?
Спасибо еще раз всем за ответы.
Вот нашел такой текст:
Насколько я понимаю, если по умолчанию МК работает на 1 MHz на встроенном осцилляторе, то можно считать частоту прерывания так:
1 000 000 - тактовая частота МК
64 - прескалер
1000000 / 64 = те же 15625 Гц, т.е., теоретически, ошибки хода таймера могут быть обусловлены только погрешность внутр. осциллятора?
(я понимаю, что задаю довольно тупые вопросы, но хотелось бы думать, что иду в правильном направлении:))
Итак, насколько я понял, можно использовать мой алгоритм, но считать не до 3600, а до 900 секунд? Как это отразится на точности? Хотелось бы просто отбросить изначально неправильные варианты, а потом выбрать самый простой и надежный.
Спасибо еще раз.
ЗЫ: Кстати, нашел вот тут: http://radiokot.ru/forum/viewtopic.php?t=13499 более-менее внятную инструкцию работе с таймером. В частности, упоминается часовой кварц на 32768 Гц - если переключить МК на внешний кварц, как он будет работать на такой частоте?
Спасибо еще раз всем за ответы.
Вот нашел такой текст:
Код: Выделить всё
Настройка таймера.
У таймера есть счётчик "Prescaler" который делит тактовую частоту МК. Произвольное значение счётчика задать нельзя, есть только фиксированые: Fclk/8; Fclk/64; Fclk/256; Fclk/1024;
Если использовать таймер 0, то он может делить, максимум, на 256. Ели таймер1, то можно делить уже на 65536.
Пример настройки таймера для часов, при частоте МК 4мгц., и тикание с частотой 1раз в секунду.
Воспользуемся такими подщётами:
4 000 000 / 256 = 15625 Гц
Где:
4 000 000 - тактовая частота МК
256 - прескалер, взят из таблицы допустимых значений
15625 - конечное значение частоты прерывания
Конечное значение частоты надо подобрать так чтобы после подщётов выходтло целое число без десятичных, иначе будет большая погрешность.
Также надо загнать таймер в режим "Clear Timer on Compare Match (CTC) Mode" и в регистр сравнения
(Output Compare Register) прописать 15625. И некаких ошибок в сутки! Smile
Насколько я понимаю, если по умолчанию МК работает на 1 MHz на встроенном осцилляторе, то можно считать частоту прерывания так:
1 000 000 - тактовая частота МК
64 - прескалер
1000000 / 64 = те же 15625 Гц, т.е., теоретически, ошибки хода таймера могут быть обусловлены только погрешность внутр. осциллятора?
(я понимаю, что задаю довольно тупые вопросы, но хотелось бы думать, что иду в правильном направлении:))
Never argue with an idiot. They bring you down to their level, then beat you with experience!!!
В CodeVisionAVR можно воспользоваться автоматическим генератором кода. Поставить в окошках нужные значения.
На закладке "Chip:"
Chip: ATmega8
Clock: 1,0 MHz
На закладке "Timers: Timer1:"
Clock Sourse: System Clock
Clock Value: 15,625 kHz
Mode: CTC top=OCR1A
Out A: Discon.
Out B: Discon.
Input Capt. : ничего не ставить
Interrupt on: выбрать Compare A Match и поставить галку.
Comp. A: 3d09 - это 15625 в шестнацатеричном виде.
Он сам сгенерит Вам нужный код, который конфигурирует таймер и прерывание. Останется добавить кое-что в основную программу и в обработчик прерывания.
Я так сделал. Что получилось - в присоединённом файле. Предполагается использование внутреннего генератора.
На закладке "Chip:"
Chip: ATmega8
Clock: 1,0 MHz
На закладке "Timers: Timer1:"
Clock Sourse: System Clock
Clock Value: 15,625 kHz
Mode: CTC top=OCR1A
Out A: Discon.
Out B: Discon.
Input Capt. : ничего не ставить
Interrupt on: выбрать Compare A Match и поставить галку.
Comp. A: 3d09 - это 15625 в шестнацатеричном виде.
Он сам сгенерит Вам нужный код, который конфигурирует таймер и прерывание. Останется добавить кое-что в основную программу и в обработчик прерывания.
Я так сделал. Что получилось - в присоединённом файле. Предполагается использование внутреннего генератора.
- Вложения
-
- timer1.c
- (3.5 КБ) 350 скачиваний