Страница 1 из 1
Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Вс авг 17, 2014 17:05:20
СКАЗОЧНИК
Доброго времени суток, друзья! =)))
Короче... год уже прошел, а я все никак часы доделать не могу... Обычные часики. На АТТини2313 и часах реального времени с протоколом I2C. В свое время досконально разобрался с этим протоколом и даже написал всю программулину на ассемблере, чтобы с часами обмениваться данными. Итого, у меня получилось. По каждому прерыванию один раз в секунду микроконтроллер прибавляет значение секунд. Часы реального времени используются только как источник стабильных импульсов каждую секунду... Хотя, до этого они и устанавливаются в программе в нулевое значение и запускаются.
Организовал вывод значения часов и минут на 7сигментные индикаторы, динамическая индикация. Все показывает и даже считает время с 00:00 прибавляя по минуте.
Встал ступор у меня на том, что надо как-то организовать изначальную установку часов... Как это программно сделать не знаю. Ну и будильника тоже и чтобы потом этот будильник звонил еще...
И еще один момент... Экспериментировал с сенсорными кнопками туда же.... Что-то получилось, что-то нет. Сенсоры простые, которые измеряют время заряда конденсатора при увеличении емкости при прикосновении. Не могу сделать точные измерения, т.е. чтобы часы сами калибровались при включении.
Если что не понятно, спрашивайте. ДОбавлю информации.
Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Вс авг 17, 2014 19:54:34
Jack_A
Ну во-первых, I2C тут вроде как не при делах, поскольку исползуется только 1-секундный импульс. В этом случае RTC можно безболезненно заменить любым кварцованным генератором на 1 Гц. Соль RTC -- в хранении текущего времени за счет автономного питания при выключенном питании самих часов - не используется. Так что для начала нужно организовать действительный обмен по I2C с RTC, чтобы подхватывать с него время при включении питания часов . Когда это выполнится, с коррекцией совсем просто : кнопками настроить на индикаторе время и по сигналу точного времении отправить в RTC, обновить ему хранимое время. Проектов таких в сети -- думаю, вагон. Сам лет 15 тому назад делал хранение точного времени для солидного промышленного устройства, проблем не возникало особых.
PS RTC -- real time clock, если кого озадачила аббревиатура.
Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Вс авг 17, 2014 20:05:48
СКАЗОЧНИК
Jack_A писал(а):Так что для начала нужно организовать действительный обмен по I2C с RTC
Конечно! )))) И это тоже нужно. У меня не укладывается в голове, как это все один МК сможет прожевать.... И чтобы при этом не прегрузить его функциями, чтобы продолжал считать время дальше. А сохранение времени обязательно надо, зачем же тогда батарейку ставил???!!! )))
Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Вс авг 17, 2014 20:27:46
uldemir
А в чем проблема? Нарисуйте простенькие программки, которые для начала отображают время, затем, которая умеет обрабатывать кнопки, а потом можно и всё остальное. Часики - это хороший тренировочный полигон, чтобы поучиться программировать. Вот только недавно закончил писать фирмварь для часиков на панаплексном дисплее.
Спойлер
Код: Выделить всё
void show_humantime() {
unsigned int i, dst_en, dst = 0;
char timezone;
unsigned char keyb, last_second = 99, current_brightness;
while(1) {
if (flag.sec_event == 1) {
flag.sec_event = 0;
current_time.seconds = read_ds1302(0x81);
if (current_time.seconds != last_second) {
last_second = current_time.seconds;
current_time.seconds = read_ds1302(0x81);
current_time.minutes = read_ds1302(0x83);
current_time.hours = read_ds1302(0x85);
current_time.date = read_ds1302(0x87);
current_time.month = read_ds1302(0x89);
current_time.weekday = read_ds1302(0x8b);
if (current_time.weekday == 7) current_time.weekday = 0;
current_time.year = read_ds1302(0x8d);
videobuffer[0] = charset[(current_time.seconds & 0x0f)];
videobuffer[1] = charset[(current_time.seconds & 0xf0)>>4];
videobuffer[2] = charset[(current_time.minutes & 0x0f)] | seg_h;
videobuffer[3] = charset[(current_time.minutes & 0xf0)>>4];
videobuffer[4] = charset[(current_time.hours & 0x0f)] | seg_h;
videobuffer[5] = charset[(current_time.hours & 0xf0)>>4];
i = (current_time.weekday) << 2;
videobuffer[9] = dow[i++];
videobuffer[8] = dow[i++];
videobuffer[7] = dow[i++];
videobuffer[6] = let_;
videobuffer[10] = let_;
}
if (keyb = kbdread()) {
if (keyb == KEY_LEFT) {
current_brightness = read_ds1302(0xC5) & 0x07;
if (current_brightness > 0) {
--current_brightness;
write_ds1302(0x8e, 0x00); // disable write protection
write_ds1302(0xC4, current_brightness);
write_ds1302(0x8e, 0x80); // enable write protection
}
for (i=0; i<12 ;++i) videobright[i] = current_brightness;
}
if (keyb == KEY_RIGHT) {
current_brightness = (read_ds1302(0xC5) & 0x07);
if (current_brightness < 7) {
++current_brightness;
write_ds1302(0x8e, 0x00); // disable write protection
write_ds1302(0xC4, current_brightness);
write_ds1302(0x8e, 0x80); // enable write protection
}
for (i=0; i<12 ;++i) videobright[i] = current_brightness;
}
if (keyb == KEY_BOTH) return;
}
}
}
}
Вот пример просто отображения времени. флаг sec_event выставляется каждые 16мс и проверяется, сменилась секунда или нет. У меня применена микросхема, которая, к сожалению, не даёт секундные импульсы. И если секунда изменилась - обновляется информация на индикаторе. Ну и, разумеется, опрашиваются клавиши, которые изменяют яркость индикатора или переключают другой режим отображения.
Всё отображение и опрос клавиш, организованы в прерываниях (не привожу, так как кристалл не AVR) и выполняется в фоне.
Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Пн авг 18, 2014 11:29:53
Jack_A
СКАЗОЧНИК писал(а): И чтобы при этом не прегрузить его функциями, чтобы продолжал считать время дальше.
Да какая там перегрузка - кроме часов, там ничего нет

Успеет, позевывая и не торопясь.
Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Пн авг 18, 2014 13:27:46
СКАЗОЧНИК
Я вообще думал туда пихать что-нибудь типа РТОС урезанную, но с диспетчером... )))) А кто-нибудь с сенсорами разбирался? Как правильнее сделать на ассемблере подсчет времени заряда конденсатора?
Я пока что-то типа того намутил....
Код: Выделить всё
; ---------- определяем порог для пустого сенсора -----------------------------
clr temp
clr temp1
ldi Counter, 0x04
clr RTCaddr
clr SensorL
clr SensorR
ForCounter:
dec Counter ; Уменьшаем количество циклов на 1
ldi temp, 0b01000001 ; Изначально порт настроен на выход, дергаем сенсор вниз, чтобы разрядить конденсатор
out PORTD, temp
ldi temp, 0b01001111 ; Переключаем порт на вход для сеноров, остальные - выход
out DDRD, temp
SENS4: inc RTCaddr ; Начинаем отсчет времени заряда пустого сенсора
sbis PIND, 4 ; Пропускаем следующую команду, если пин 4 в регистре Д стал равен единице
rjmp SENS4 ; Иначе, проверяем снова
ldi temp, 0b01111111 ; Переключаем порт на выход
out DDRD, temp
ldi temp, 0b01000001 ; Дергаем сенсор вниз, чтобы разрядить конденсатор
out PORTD, temp
ldi temp, 0b01001111 ; Переключаем порт на вход для сеноров, остальные - выход
out DDRD, temp
SENS5: inc temp1 ; Начинаем отсчет времени заряда пустого сенсора
sbis PIND, 5 ; Пропускаем следующую команду, если пин 5 в регистре Д стал равен единице
rjmp SENS5 ; Иначе, проверяем снова
; --------------------------------------------------
cp SensorL, RTCaddr ; Сравниваем два значения, если первое больше
brsh OTHER ; или равно, то выходим на проверку следующих
mov SensorL, RTCaddr ; Иначе, пихаем в первый большее значение
OTHER: cp SensorR, temp1
brsh NEXTFOR
mov SensorR, temp1
NEXTFOR: cpi Counter, 0x00 ; Проверяем, не стал ли счетчик равен 0?
brne ForCounter
Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Пн авг 18, 2014 13:55:11
uldemir
Использовать, например, аппаратный таймер. В АВРах они, ведь, есть? В некоторых кристаллах, есть даже возможность использовать гейт разрешающий/запрещающий работать счетчику. В 18-х пиках есть даже специальный блок измерения коротких интервалов (для измерения емкости от сенсорных кнопок). Вариантов - море.
Тупой метод, вроде инкремента переменной в цикле, не предлагаю, так как точность измерения может оказаться не достаточной.
Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Пн авг 18, 2014 16:42:50
FreshMan
СКАЗОЧНИК писал(а):Доброго времени суток, друзья! =)))
По каждому прерыванию один раз в секунду микроконтроллер прибавляет значение секунд.
правельнее было бы сделать чтобы мк по каждому прерыванию читал время с DS1307
Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Вт авг 19, 2014 15:30:50
Jack_A
FreshMan писал(а):
правильнее было бы сделать чтобы мк по каждому прерыванию читал время с DS1307
А смысл ? При включении питания часов "схлопнули" из RTC сохраненное время, и при каждом импульсе время будет синхронно прибавляться и в часах, и в RTC. Главное -- не пропустить и зафиксировать провал питания , чтобы знать, что нужно повторно синхронизуться.
Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Вт авг 19, 2014 17:06:04
BOB51
Или при подаче питания однократное чтение RTC с запуском внутреннего набора регистров (самостоятельные часики) - приращение по прерываниям слишком роскошно для простейшей конструкции.

Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Вт авг 19, 2014 18:03:56
СКАЗОЧНИК
Зато оно точнее. )))))) мне так кажется.
Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Вт авг 19, 2014 18:23:12
BOB51
На практике для бытовых нужд и автоматики практически неотличимо.

Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Вт авг 19, 2014 18:36:32
СКАЗОЧНИК
Что же мне теперь РТС выкидывать????

Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Вт авг 19, 2014 21:26:05
BOB51
А оно (RTC) для того и существует, чтоб продолжать отсчет при отключенном питании и чтоб каждый раз после включения устройства кнопкодавством не заниматься. Плюс энергонезависимое ОЗУ для собственных параметров каких-нить величин.

Re: Кто сможет объяснить доходчиво алгоритм часов?
Добавлено: Ср авг 20, 2014 01:12:01
nirq
... при отключенном питании от питания более экономичного.
По основной проблеме: не надо пытаться съесть сразу вообще слона.
А надо сначала выбрать какую-то такую часть слона, которая поместилась бы в тарелку. Потом эту часть от слона отрезать, положить в тарелку и съесть. И только потом вспоминать про существование остального слона.