Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Меню для RTC
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > AVR
ILYAUL
Всем добрый вечер! И с наступающим OLD NEW YEAR!!

"Ледяной" дождь и отключение электричества выявило одну проблемку в проекте , где часы синхронизировались от компа.
Решено было , дописать "МЕНЮ" внеся в него установку часов в MANUAL MODE.
Часы - DS1337 - код сжатый BCD
Вот никак не выберу решение из двух возможных ( по моему мнению)

1. Распоковать BCD на десятки и единицы и установить каждый отдельно. Но "вылезают" проблемы с часами и датой ( день месяца) и месяцем - не может быть 24 часа и выше и конечно 32 и выше дня.
Т.е. приходится отслеживать десятки , что бы задать диапазон изменения единиц - что "утяжеляет" программу
2. Перевести BCD to HEX ( элементарно). НО - если из 00:00 надо выставить 12:30 - 42 нажатия кнопок . Да забыл , кнопок is used всего 4 (+) (-) (MENU) (SET) Таймер 16 - свободен , можно конечно устроить "залипание" кнопки......
Вообщем за неделю так и не пришёл к окончательному пути. Help.
rx3apf
Цитата(ILYAUL @ Jan 13 2011, 21:57) *
Таймер 16 - свободен , можно конечно устроить "залипание" кнопки......
Вообщем за неделю так и не пришёл к окончательному пути. Help.

Делать так, как в наручных электронных часах (бывает по-разному, в данном случае вполне можно сделать с реверсом, т.е. больше/меньше). Крутить все поле целиком, с залипанием и, вполне возможно, с ускорением при длительном удержании. Если проскочит - всегда можно вернуться. По цифрам удобно, когда есть цифровая клавиатура, иначе удобство сомнительное.
rezident
Унутре микроконтроллера обычно используют время в UNIX/POSIX-формате - 32-х разрядное число секунд, прошедшее от 1 января 1970 года. Или чтобы избежать проблемы 2038 года, то 64-х разрядное число. Число это преобразуется в привычный для человека вид (ЧЧ:ММ:СС и ДД-ММ-ГГГГ) только при визуализации его во время отображения или при редактировании. Ну а вашем случае еще и при сохранении его в регистры м/с RTC. Для перевода даты/времени туда и обратно существуют уже готовые функции.
По поводу кнопок управления. При их ограниченном количестве используют функцию автоповтора, когда при удержании кнопки в нажатом состоянии некоторое время генерируется повторяющийся код этой кнопки. Иногда для дополнительного удобства при длительном удержании увеличивают скорость генерации повтора вдвое и вчетверо. Но опять же для вашего случая автоповтор следует сделать только для кнопок (+) и (-). Либо функцию автоповтора сделать отключаемой, включая ее в зависимости от текущего состояния меню.
ILYAUL
Цитата(rezident @ Jan 13 2011, 22:40) *
Унутре микроконтроллера обычно используют время в UNIX/POSIX-формате - 32-х разрядное число секунд, прошедшее от 1 января 1970 года. Или чтобы избежать проблемы 2038 года, то 64-х разрядное число. Число это преобразуется в привычный для человека вид (ЧЧ:ММ:СС и ДД-ММ-ГГГГ) только при визуализации его во время отображения или при редактировании. Ну а вашем случае еще и при сохранении его в регистры м/с RTC. Для перевода даты/времени туда и обратно существуют уже готовые функции.
По поводу кнопок управления. При их ограниченном количестве используют функцию автоповтора, когда при удержании кнопки в нажатом состоянии некоторое время генерируется повторяющийся код этой кнопки. Иногда для дополнительного удобства при длительном удержании увеличивают скорость генерации повтора вдвое и вчетверо. Но опять же для вашего случая автоповтор следует сделать только для кнопок (+) и (-). Либо функцию автоповтора сделать отключаемой, включая ее в зависимости от текущего состояния меню.

Мне всегда нравились Ваши пояснения. biggrin.gif Но в данном проекте секунд , как таковых нет . Я всегда не понимал тех , кто выводя на экран минуты и часы , "дергал" проц каждую секунду. Поэтому и в данном проекте проц практически целую минуту просто спит. Через минуту просыпается ~ на 500 mc и снова спит. Я пишу на ASM , единственный мой проект на СИ(удачно) - кнопка и моргание светодиодов и то за последние 10 дней НГ- изучаю. На asm ,как я понял Вашу фразу (Для перевода даты/времени туда и обратно существуют уже готовые функции) т.е BCD- HEX и обратно , я даже не рассматриваю - это настолько элементарно , что и говорить не о чем.
Как я Вас понял ,Вы склоняетесь ко второму варианту .
AHTOXA
Цитата(rezident @ Jan 14 2011, 00:40) *
Или чтобы избежать проблемы 2038 года, то 64-х разрядное число.

На самом деле достаточно 32-х разрядного, но беззнакового.
ILYAUL
Цитата(rezident @ Jan 13 2011, 22:40) *
Или чтобы избежать проблемы 2038 года, то 64-х разрядное число.

Кстати , дожить бы . Апокалипсис обещают уже 2012 в декабре, слабо верится , но ...... Конечно хорошо , если наши творения нас переживут , но кому они будут нужны ... Sorry bb-offtopic.gif
rezident
Цитата(ILYAUL @ Jan 14 2011, 01:07) *
На asm ,как я понял Вашу фразу (Для перевода даты/времени туда и обратно существуют уже готовые функции)
Нет, я имел в виду готовые функции на Си. Они используются, например, в Linux.
Цитата(ILYAUL @ Jan 14 2011, 01:07) *
Как я Вас понял ,Вы склоняетесь ко второму варианту .
Я не знаю полностью всей задачи, которую выполняет ваш МК. Если это просто часы, то нет ничего проще, чем считать текущее значение регистра из м/с RTC и в зависимости от типа поля (день, минута или месяц) гонять его по кольцу в заданном для данного типа поля диапазоне (секунды/минуты от 0 до 59, часы от 0 до 23, день от 1 до максимального в данном месяце и т.д.), инкрементируя или декрементируя значение на единицу при каждом нажатии клавиши. Чтобы не приходилось давить кнопку много раз, то лучше приделать к клавишам (+) и (-) функцию автоповтора.
Цитата(AHTOXA @ Jan 14 2011, 01:16) *
На самом деле достаточно 32-х разрядного, но беззнакового.
Это уже не будет UNIX/POSIX-формат. В UNIX используется 32-х битное знаковое число. Хотя лично мне тоже непонятно, зачем было для переменной времени использовать знаковое число? Ведь время назад не течет laughing.gif
kolobok0
Цитата(ILYAUL @ Jan 13 2011, 21:57) *
1....приходится отслеживать десятки...


установка поразрядно. причём левые разряды сбрасывают правые. правые ограничиваются левыми. выставляют обычно с лева на право.

удачи вам
(круглый)
ЗЫ
Обожаю азм.
mempfis_
Цитата(ILYAUL @ Jan 13 2011, 21:57) *
1. Распоковать BCD на десятки и единицы и установить каждый отдельно. Но "вылезают" проблемы с часами и датой ( день месяца) и месяцем - не может быть 24 часа и выше и конечно 32 и выше дня.
Т.е. приходится отслеживать десятки , что бы задать диапазон изменения единиц - что "утяжеляет" программу
2. Перевести BCD to HEX ( элементарно). НО - если из 00:00 надо выставить 12:30 - 42 нажатия кнопок . Да забыл , кнопок is used всего 4 (+) (-) (MENU) (SET) Таймер 16 - свободен , можно конечно устроить "залипание" кнопки......
Вообщем за неделю так и не пришёл к окончательному пути. Help.


Только вчера закончил подменю настройки даты/времени в одном устройстве. 4 кнопки +, -, ENTER, BACK.
ENTER выбирает что настраиваем - день, месяц, год, час, минута, секунда - под соотв позицию подводится нижнее подчёркивание на LCD-индикаторе, +/- - инкремент/декремент параметра (для месяца учитывается кол-во дней (для февраля ещё и учёт високосного года)), по нажатию на BACK время сохраняется если было фактическое изменение. По нажатию и удержанию кнопки автоповтор инкремента/декремента соотв позиции. Получилось довольно удобно и оперативно настраивать время. По поводу кода - написал процедуры инкремента/декремента параметра с органичением:

Код
//----------------------------------
unsigned int incParam(unsigned int val, unsigned int low,unsigned int high)
{
  unsigned int result = val;
  
  if(result >= high) result = low;
  else result++;
  return result;
}
//----------------------------------

//----------------------------------
unsigned int decParam(unsigned int val, unsigned int low,unsigned int high)
{
  unsigned int result = val;
  
  if(result <= low) result = high;
  else result--;
  return result;
}
//----------------------------------


Применяется при настройке абсолютно всех параметров часов, занимает минимум кода.

Пример инкремента по нажатию кнопки +

Код
              if(KEYBOARD.key_status & MENU_UP_KEY)
              {
                common_val = 1; //изменение параметра
                
                if(common_index == 0)
                {
                  //day
                  if( (LocalTime.RTC_Mon == 2) && ((LocalTime.RTC_Year % 4) == 0) )
                  {
                    //високосный год
                    LocalTime.RTC_Mday = incParam(LocalTime.RTC_Mday, 1, MONTH_LIMIT_DAY[LocalTime.RTC_Mon]+1);
                  }
                  else
                  {
                    LocalTime.RTC_Mday = incParam(LocalTime.RTC_Mday, 1, MONTH_LIMIT_DAY[LocalTime.RTC_Mon]);
                  }
                  
                }
                else if(common_index == 1)
                {
                  LocalTime.RTC_Mon = incParam(LocalTime.RTC_Mon, 1, 12);
                }
                else if(common_index == 2)
                {
                  LocalTime.RTC_Year = incParam(LocalTime.RTC_Year, 2011, 2099);
                }
                else if(common_index == 3)
                {
                  LocalTime.RTC_Hour = incParam(LocalTime.RTC_Hour, 0, 23);
                }
                else if(common_index == 4)
                {
                  LocalTime.RTC_Min = incParam(LocalTime.RTC_Min, 0, 59);
                }
                else if(common_index == 5)
                {
                  LocalTime.RTC_Sec = incParam(LocalTime.RTC_Sec, 0, 59);
                }
                
                RTC_Display_Time(&LocalTime);
                
                //задержка отображения
                setServiceTimeoutStatus(MENU_KEY_SHIFT_TIMEOUT, 35);
                  
                return;
              }
ILYAUL
Цитата(kolobok0 @ Jan 14 2011, 15:27) *
...причём левые разряды сбрасывают правые. правые ограничиваются левыми. выставляют обычно с лева на право.

Левые - это десятки ? Правые - единицы ?

Цитата
mempfis_ Только вчера закончил подменю настройки даты/времени в одном устройстве. 4 кнопки +, -, ENTER, BACK.
Спасибо! И поздравляю!
В общих чертах я понял подход.
AHTOXA
Цитата(mempfis_ @ Jan 14 2011, 20:09) *
по нажатию на BACK время сохраняется если было фактическое изменение.

А как отменить ввод? Никак? Это неправильно, должна быть отмена. Имхо, конечно.
mempfis_
Цитата(AHTOXA @ Jan 15 2011, 20:22) *
А как отменить ввод? Никак? Это неправильно, должна быть отмена. Имхо, конечно.


Была мысль сделать по нажатию BACK запрос сохранять или нет, но отказался от этого - меню и так довольно разветвлённоеsm.gif
У нас не винда чтобы требовать подтверждение на каждое действие sm.gif
Если заказчик захочет подтверждение - введу, а пока что пусть будет так как есть.
AHTOXA
Цитата(mempfis_ @ Jan 15 2011, 23:26) *
У нас не винда чтобы требовать подтверждение на каждое действие sm.gif

При чём тут винда? У пользователя должен быть путь отступления!
У меня так - кнопка ENTER передвигает на следующую позицию, а на последней позиции сохраняет изменения. А кнопка BACK - возвращает на предыдущую позицию, а на первой позиции - отменяет весь ввод.
Железобетонно, никаких подтверждений, и у пользователя есть куда убежать, если он заблудился sm.gif
Dog Pawlowa
Обработка событий клавиатуры в меню:
Код
        case evUp:
            if (rtc_adjustment)
            {    if (!(rtc_adjustment&1))
                    Change(    1);
                else
                    Change( 10);
            }
        break;

        case evDn:
            if (rtc_adjustment)
            {    if (!(rtc_adjustment&1))
                    Change(-1);
            else
                    Change(-10);
            }
        break;


Собственно изменение:
Код
const char max[13]    = {0,31,31,11,11,134,134,23,23,59,59,59,59};
const char min[13]    = {0,1 , 1, 0, 0, 109,109, 0, 0, 0, 0, 0, 0};

void Change(sint dif )
{    int    my_max=max[rtc_adjustment];
    int    my_min=min[rtc_adjustment];
     *rtc_ptr+=dif;
    if (dif>0)
        {    if (*rtc_ptr>my_max) *rtc_ptr=my_max;}
    else
        {    if (*rtc_ptr<my_min) *rtc_ptr=my_min; }
}

ILYAUL
Цитата
Dog Pawlowa Собственно изменение:


Код
const char max[13]    = {0,31,31,11,11,134,134,23,23,59,59,59,59};
const char min[13]    = {0,1 , 1, 0, 0, 109,109, 0, 0, 0, 0, 0, 0}


Зачем две таблицы? Это же высчитывание двух разных адресов для Z . Данные по мин и мах кратны 2 - их можно расположить друг за другом

Цитата
AHTOXA При чём тут винда? У пользователя должен быть путь отступления!
...а на первой позиции - отменяет весь ввод

Но и мозги тоже . См. что вводишь , не то вернись на эту позицию . А отменять весь предыдущий ввод , зачем ? Ну ошибся я в дне недели - вернусь поправлю.
AHTOXA
Цитата(ILYAUL @ Jan 16 2011, 15:40) *
Но и мозги тоже .

Мозги пользователь иметь не обязан. Это прерогатива программиста.
Цитата(ILYAUL @ Jan 16 2011, 15:40) *
А отменять весь предыдущий ввод , зачем ? Ну ошибся я в дне недели - вернусь поправлю.

А если человек случайно зашёл в это меню? Что ему делать? Вводить 14 цифр просто потому, что программист не предусмотрел отмены?
Ну и вообще, это хороший тон в программировании пользовательских интерфейсов - дать пользователю возможность выбора -- принять сделанные изменения или отказаться.
demiurg_spb
Цитата(Dog Pawlowa @ Jan 16 2011, 01:09) *
Код
const char max[13]    = {0,31,31,11,11,134,134,23,23,59,59,59,59};
const char min[13]    = {0,1 , 1, 0, 0, 109,109, 0, 0, 0, 0, 0, 0};

Мысль Ваша ясна, за исключением года.
Смею предположить, что отсчёт Вы ведёте от 1900 года, тогда Вы рассчитываете что после 2034=(1900+134) года прибор будет уже никому не нужен. Мне тогда стукнет лишь 54 года - даже не пенсионный возрастsm.gif С чего такой пессимизм? :-)
rx3apf
Цитата(ILYAUL @ Jan 16 2011, 13:40) *
Но и мозги тоже . См. что вводишь , не то вернись на эту позицию . А отменять весь предыдущий ввод , зачем ? Ну ошибся я в дне недели - вернусь поправлю.

Человек дело говорит, прислушайтесь. Отмена всего ввода - удобная и правильная вещь.
forever_student
Цитата(rx3apf @ Jan 16 2011, 17:15) *
...Отмена всего ввода - удобная и правильная вещь.

Удобно или нет - это еще и от всего интерфейса зависит. Если в других настройках её нет,
то в часах отмена ввода будет выглядеть несколько странно. (imho)

Цитата(AHTOXA @ Jan 16 2011, 15:48) *
...А если человек случайно зашёл в это меню? Что ему делать? Вводить 14 цифр просто потому, что программист не предусмотрел отмены?...

Нажать кнопку "Выход" rolleyes.gif

Цитата(AHTOXA @ Jan 15 2011, 23:00) *
...У меня так - кнопка ENTER передвигает на следующую позицию, а на последней позиции сохраняет изменения. А кнопка BACK - возвращает на предыдущую позицию, а на первой позиции - отменяет весь ввод.
..

А если человеку нужно только минуты подправить? Для сохранения изменений потом сколько раз еще "ENTER" нажимать?
AHTOXA
Цитата(forever_student @ Jan 16 2011, 20:26) *
А если человеку нужно только минуты подправить? Для сохранения изменений потом сколько раз еще "ENTER" нажимать?

Это ему по-любому придётся сделать.
Dog Pawlowa
Цитата(demiurg_spb @ Jan 16 2011, 16:48) *
...С чего такой пессимизм? :-)

sm.gif Дык мне уже почти столько, сколько Вам будет в 2034! crying.gif
Стандартный time - в 2034 все равно кирдык.
Я и у заказчика спрашивал - оставить или переделать, он тоже сказал, что не доживет.

Цитата(ILYAUL @ Jan 16 2011, 13:40) *
Зачем две таблицы? Это же высчитывание двух разных адресов для Z . Данные по мин и мах кратны 2 - их можно расположить друг за другом

Тю ...
если заниматься преждевременной оптимизацией, ничего в своей жизни не создашь, кроме превосходно работающего кода в 20 строк.
Оптимизацией должен заниматься компилятор, у него это получается быстрее и лучше.
forever_student
Цитата(AHTOXA @ Jan 16 2011, 16:30) *
Это ему по-любому придётся сделать.

А кнопка "Выход"?
AHTOXA
Цитата(forever_student @ Jan 17 2011, 00:57) *
А кнопка "Выход"?

Я думал, вы пошутили. А вы, оказывается, просто не прочитали тему. Специально для вас процитирую исходные данные:
Цитата(mempfis_ @ Jan 14 2011, 17:09) *
4 кнопки +, -, ENTER, BACK.

Где здесь кнопка "Выход"?

---
Я кажется понял, вы про кнопку "BACK"? Да, она поможет выйти после редактирования, но добраться до редактируемого параметра (в данном случае - минут) она не поможет. А если это не минуты, а год? Ценность кнопки "BACK" в этом случае ниже? А на последнем параметре?
kolobok0
Цитата(ILYAUL @ Jan 15 2011, 17:13) *
Левые - это десятки ? Правые - единицы ?..


да
forever_student
Цитата(AHTOXA @ Jan 17 2011, 00:04) *
...А вы, оказывается, просто не прочитали тему...

Тему прочитал. Да, конечно, я имел в виду кнопку "ВАСК". (I'm sorry, что непонятно сказал)

Цитата(AHTOXA @ Jan 17 2011, 00:04) *
Да, она поможет выйти после редактирования, но добраться до редактируемого параметра (в данном случае - минут) она не поможет.

Вариантов интерфейса ОЧЕНЬ много. Например, можно сделать кнопку "ВАСК" только на выход из меню (или на переход на один уровень вверх). "ENTER" гоняет по кругу параметры. И, по моему, для пользователя будет проще запомнить: одна кнопка - одна функция, чем помнить, что в каком-то положении кнопка еще сохраняет ввод, а в каком-то отменяет его ( последнее предложение - imho)
ILYAUL
Вообщем получилось так. ВСЕМ СПАСИБО за ИДЕИ!!!
forever_student
Цитата(ILYAUL @ Jan 23 2011, 14:54) *
Вообщем получилось так...

День недели вычисляется из даты?
ILYAUL
Цитата(forever_student @ Jan 24 2011, 22:54) *
День недели вычисляется из даты?

Зачем - его передает DS1337 от 1-7 , а уж написать вместо цифры название дня недели - дело техники
нечитатель
Вспомнил про две возможности я:

- нажимать одновремеменно две кнопки (и более);
- на дисплее показывать функционал кнопок в данный момент (за которое расплачиваться лишними знакоместами).

К названию темы с трудом подходит, но к содержанию.
forever_student
Цитата(ILYAUL @ Jan 25 2011, 01:00) *
Зачем - его передает DS1337 от 1-7...

Просто подумал, если еще день недели выставлять кнопками, тогда все cranky.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.