Реле времени. Вопрос по алгоритму.

Вопросы настройки, программирования, прошивки микроконтроллеров и микросхем программируемой логики
Закрыто
Аватара пользователя
KentornoS
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Пт окт 19, 2007 18:20:19

Реле времени. Вопрос по алгоритму.

Сообщение KentornoS »

Всем привет.
Вопрос следующий - есть задача сделать реле времени на МК.
Управление двумя нагрузками, периодичность:
Первое устройство - 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!!!
Аватара пользователя
Барсик
Друг Кота
Сообщения: 3459
Зарегистрирован: Ср сен 27, 2006 16:18:57

Сообщение Барсик »

Какой микроконтроллер? Какая среда разработки?
Если делать, например, на ATtiny2313, то можно так. Для стабилизации тактовой частоты использовать кварц. Установить для таймера1 режим CTC. Прескалер таймера и число в регистре сравнения, до которого он будет считать, подобрать так, чтобы перезапуск таймера происходил 1 раз в секунду. Настроить прерывание от таймера, которое называется "Compare A Match". Прерывание будет происходить 1 раз в секунду. В обработчике прерывания декрементировать счётчики.
В главной программе:
включть нагрузку1 задать значение счётчика1
включть нагрузку2 задать значение счётчика2
В основном цикле проверять, досчитал ли счётчик до нуля. Если да, то выключить нагрузку, и задать счётчик паузы. Потом проверять счётчик паузы... и т.д.
Аватара пользователя
KentornoS
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Пт окт 19, 2007 18:20:19

Сообщение KentornoS »

Контроллер - Мега 8. Среда разработки - CodeVisionAVR.
Знаю, что мега-8 с большим запасом, но он есть в наличии, а устройство нужно в одном экземпляре.

Ткните, пожалуйста, носом, где почитать про использование таймера в атмегах. Если бы там еще были примеры, было бы просто здорово - на примерах проще учить:)

Еще добавлю.
1. Я думаю, можно использовать внутренний осциллятор, ибо точность на цикле допускается в 1 минуту туда-обратно. Хотя, конечно, если это достижимо на встроенном осцилляторе.
2. Вопрос - а почему декрементировать счетчики? Имхо логичнее инкрементировать, и ловить не "0", а "1800", или что-то еще. Или я неправ?
Просьба не пинать, ибо нуб.
Спасибо.
Never argue with an idiot. They bring you down to their level, then beat you with experience!!!
Аватара пользователя
МитяРа
Модератор
Сообщения: 11492
Зарегистрирован: Чт дек 11, 2008 14:52:26
Откуда: град Нижний

Сообщение МитяРа »

Мяу всем..
Имеем цикл в 1 час (60 минут) для обоих устройств.
Это период - 1 час, а цикл тут может быть 15 минут..
Т.е. имеем период их 4-х циклов..
1-цикл включены оба устройства,
2-цикл включены оба устройства,
3-цикл устр.1 - вкл, устр.2 - выкл,
4-цикл устр.1 - выкл, устр.2 - выкл.
Таким образом имеем минимальную дискретность 15 минут и счётчик циклов = 4...
Если не надо что-то менять в алгоритме, то считать минуты - вовсе не обязательно...
Аватара пользователя
KentornoS
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Пт окт 19, 2007 18:20:19

Сообщение KentornoS »

О, спасибо за быстрый ответ:)
Итак, насколько я понял, можно использовать мой алгоритм, но считать не до 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!!!
Аватара пользователя
Барсик
Друг Кота
Сообщения: 3459
Зарегистрирован: Ср сен 27, 2006 16:18:57

Сообщение Барсик »

В 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 в шестнацатеричном виде.

Он сам сгенерит Вам нужный код, который конфигурирует таймер и прерывание. Останется добавить кое-что в основную программу и в обработчик прерывания.
Я так сделал. Что получилось - в присоединённом файле. Предполагается использование внутреннего генератора.
Вложения
timer1.c
(3.5 КБ) 350 скачиваний
Аватара пользователя
KentornoS
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Пт окт 19, 2007 18:20:19

Сообщение KentornoS »

Спасибо всем ответившим, в особенности, Барсику.
Есть же добрые люди)))
Почитал сишный исходник - там все просто и понятно, с подробными комментариями.
Еще раз спасибо!:)
Never argue with an idiot. They bring you down to their level, then beat you with experience!!!
Аватара пользователя
Ivanchik
Первый раз сказал Мяу!
Сообщения: 23
Зарегистрирован: Чт окт 23, 2008 19:35:08

Сообщение Ivanchik »

есть прога под таню 25, у нее делитель частоты больше, что удобно, да и ножек оптимальное кол-во для вашего случая
лучше делать на внешнем кварце, например 3,2768мгц
Закрыто

Вернуться в «Микроконтроллеры и ПЛИС»