Опрос модуля времени с использованием таймера
- Войдите на сайт для отправки комментариев
Чт, 28/12/2017 - 17:45
Не могу реализовать опрос модуля времени DS1307 (библиотека DS1307RTC.h) раз в секунду, для того чтобы не мешала работе шим (на таймере OCR1A) и основной работе программы.
Так как при обычной работе прошивки мк во время опроса подвисает на несколько миллисекунд из за чего падает вольтаж на шим и прекращается управление портами (мерцает).
В таймерах не разбираюсь толком, но хотелось бы понять. После прочтения этой темы
Опрос модуля происходит так (DS1307RTC.cpp):
// Aquire data from the RTC chip in BCD format bool DS1307RTC::read(tmElements_t &tm) { uint8_t sec; Wire.beginTransmission(DS1307_CTRL_ID); #if ARDUINO >= 100 Wire.write((uint8_t)0x00); #else Wire.send(0x00); #endif if (Wire.endTransmission() != 0) { exists = false; return false; } exists = true; // request the 7 data fields (secs, min, hr, dow, date, mth, yr) Wire.requestFrom(DS1307_CTRL_ID, tmNbrFields); if (Wire.available() < tmNbrFields) return false; #if ARDUINO >= 100 sec = Wire.read(); tm.Second = bcd2dec(sec & 0x7f); tm.Minute = bcd2dec(Wire.read() ); tm.Hour = bcd2dec(Wire.read() & 0x3f); // mask assumes 24hr clock tm.Wday = bcd2dec(Wire.read() ); tm.Day = bcd2dec(Wire.read() ); tm.Month = bcd2dec(Wire.read() ); tm.Year = y2kYearToTm((bcd2dec(Wire.read()))); #else sec = Wire.receive(); tm.Second = bcd2dec(sec & 0x7f); tm.Minute = bcd2dec(Wire.receive() ); tm.Hour = bcd2dec(Wire.receive() & 0x3f); // mask assumes 24hr clock tm.Wday = bcd2dec(Wire.receive() ); tm.Day = bcd2dec(Wire.receive() ); tm.Month = bcd2dec(Wire.receive() ); tm.Year = y2kYearToTm((bcd2dec(Wire.receive()))); #endif if (sec & 0x80) return false; // clock is halted return true; }
это происходит слишком медленно и мешает, прошу помочь реализовать это на таймере.
Будет ли работать цикл while и останавливать работу основного кода программы функция, вызванная таймером?
мк atmega328p, кварц на 8Mhz
прошу помочь реализовать это на таймере.
Это не нужно реализовывать на таймере по нескольким причинам
1.
Таймер будет щелкать когда попало, например посередине секунды (с точки зрения часов) и потому изменения Вашего времени будет не точно когда в часах секунда сменилась, а когда у Вас таймер щёлкнул - то бишь подход сам по себе лоховский.
2.
Зачем занимать таймер? Их не так много, он для чего-нибудь более дельного пригодится.
Это делается гораздо проще.
DS1307 умеет выдавать на пин SQW signal с частотой 1Гц. Вот им и надо воспользоваться. Сигнал завести на любую ногу контроллера, которая умеет выдавать прерывание, и по этому прерыванию спокойно спрашивать время. И время будет точно на переходе секунды обновляться и таймер не будет занят.
Спасибо за ответ, Евгений.
Не вариант, так как будет не красиво смотреться торчащий провод через всю плату печатную...
Есть ли еще способ по другому это реализовать?
Какой торчащий провод? А что, дорожкой его провести не судьба?
Другие варианты - "по уму нет", а колхоз - да хоть через таймер, хоть через millis, но погрешность в среднем в полсекунды Вы получите стопудово, т.к. никак Вы не синхронизуетесь с переходом секунды в часах.
В будущей плате на смд элементах проведу что захочу, а сейчас нет возможности.
Как реализовать Ваш вариант в коде?
Есть вариант повесить таймер на функцию изменения режимов портов (что должно происходить по логике раз в 1мс и происходит, работает через millis) и проверки вольтажа ШИМ (выполняется сразу после вывода данных), timer0 и timer2 свободны.
Думаю на время опроса модуля выводить текущие значения времени, пока не обновит. (мерцаний не должно быть при таком варианте)
Как реализовать Ваш вариант в коде?
Какой вариант? Тут уже три обсуждалось
DS1307 умеет выдавать на пин SQW signal с частотой 1Гц. Вот им и надо воспользоваться. Сигнал завести на любую ногу контроллера, которая умеет выдавать прерывание, и по этому прерыванию спокойно спрашивать время. И время будет точно на переходе секунды обновляться и таймер не будет занят.
Этот вариант
Так всё ж написано.
Береёт пин, который умеете принимать прерывания. Конфигурируете его как INPUT_PULLUP и настраиваете на него прерывание на FALLING.
Соединяете его с пином SQW часов.
Часы конфигурируете, чтобы они туда раз в секунду выдавали низкий уровень (в даташите написано как это делать).
Ну и всё. Случилось прерывание - запрашиваете время и, если надо, обновляете на экране.
Не вариант, так как будет не красиво смотреться торчащий провод через всю плату печатную...
а что, печатная плата будет без корпуса?
Каких только бредовых обьяснений не встретишь на форуме...
Спасибо.
Хотелось еще задать вопрос по поводу таймеров, так как сколько не лазаю не могу понять что мне нужно и как это реализовать.
Помимо ШИМ, который подает ток, у меня есть функция, которая переключает режимы портов раз в 1мс, хочу завести таймер для выполнения этой самой функции на фоне основого цикла программы, без управления другими пинами.
Читал этот пост, работает, но не пойми что творится. (То дросель свистит, то вообще вольтаж перестаёт генерироваться на шим)
С корпусом, еще сертификацию проходить. А так как объем маленький, то заказывать новые печатные платы влетит в копеечку.
Вообще то пост с самого начала меня озадачил - как может что либо вообще влиять на ШИМ ?
Единственное разумное объяснение - у вас таймер в однократном режиме - сделайте режим у перезапуском и будет у Вас чистый ШИМ без всякого влияния.
Вообще то пост с самого начала меня озадачил - как может что либо вообще влиять на ШИМ ?
Единственное разумное объяснение - у вас таймер в однократном режиме - сделайте режим у перезапуском и будет у Вас чистый ШИМ без всякого влияния.
Как раз таки так не нужно, необходимо в зависимости от выставленных настроек менять требуемый вольтаж постоянного тока от 150 до 210 вольт, плюс вольтаж может проседать при смене портов.
Это всё работает. (мосфет не греется, дросель не свистит)
Ну Вы же не меняете вольтаж в каждом такте, сделайте, чтобы он был с перезапуском, а вот границу будете менять по необходимости, зато пока граница постоянна, он будет молотить невзирая ни на что.
Я меняю только период в зависимости от вольтажа (ICR1)
Вопрос про таймер в силе.
http://playground.arduino.cc/Code/Timer1
Я всё правильно делаю?
Мне кажется нужно правильно рассчитать период для Timer1.initialize, только не вижу как это сделать...
Плюс не обрабатываются кнопки из основного цикла программы (void loop)
С корпусом, еще сертификацию проходить. А так как объем маленький, то заказывать новые печатные платы влетит в копеечку.
Вообще-то это хоббийный форум. Какая сертификация? Какой объём? Если у Вас коммерческая разработка, так наймите специалиста, чего задарма-то решения спрашивать?
Нет не коммерческий, но хотелось бы, мечтать нельзя что ли?.. Возможно, что вообще я это делаю для себя или в подарок кому нибудь и свет не увидит...
Просто это причина, почему я не хочу кидать провод через всю плату или печатать новую, у меня тут и так трэш... не хочу усугублять.
Timer1.initialize(50); - цикл программы не выполняется
Timer1.initialize(1000); - цикл программы не выполняется
Timer1.initialize(10000); - выполняется цикл программы, генерируется вольтаж, таймер не выполняется или частота выполнения достаточно редкая...
мк atmega328p, кварц на 8Mhz
неужели нельзя запустить таймер OCR0A без управления пинами на бесконечное выполнение раз в 1мс?
неужели нельзя запустить таймер OCR0A без управления пинами на бесконечное выполнение раз в 1мс?
можно
поизучай. там всё
https://github.com/DetSimen/Arduino-