Перейти к содержанию
    

Может кто посоветует как выполнить перевод часов.

Скажем регист часов содержит 0x22, что равно 22 часам.

hours = 0х22;

hours++;

но фишка в том, что в ds записывается и 0x25 и 0х29.

Приходится выполнять двойное преобразование:

BCD_DEC(hours); 0x22 -- 0x16

hours = DEC; //DEC возвращается BCD_DEC

hours++;

DEC_BCD_COR(Add_hr,hours); // обратное преобразование с записью в ds

 

к тому же писать функцию сравнения времени

 

Может возможно как-нить непосредстренно с ds, не прибегая к куче преобразований.

Изменено пользователем MMP

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 48м была специальная команда десятичной коррекции. Вот ее алгоритм:

 

Команда DA A

 

По команде DA А результат двоичного сложения упакованных двоично-десятичных чисел в аккумуляторе А преобразуется в упакованное двоично-десятичное число следующим образом. Если число в младших четырех разрядах аккумулятора больше девяти или триггер признака вспомогательного переноса АС установлен в состояние "1", то к содержимому аккумулятора прибавляется число 6;

 

если после этого число в старших четырех разрядах аккумулятора больше девяти или триггер признака переноса С установлен в состояние "1", то к содержимому аккумулятора прибавляют число 60Н.

 

При переносе из 7-го разряда АЛУ триггер признака переноса С устанавливается в состояние "1", в противном случае — в "0".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Можно и без преобразования, просто нужно сделать 3 проверки:

 

hours++;

if(hours>0x23){hours=0;}

if(hours==0x1A){hours=0x20;}

if(hours==0x0A){hours=0x10;}

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тогда уж не три, а четыре

if(hours<0x00){hours = 0x23}

 

плюс восемь на минуты и т.д.

тоже геморно, так тоже пробовал

Изменено пользователем MMP

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Увеличение часов:

 

hours++;

if(hours == 0x24) { hours = 0; }

if((hours & 0x0F) == 0x0A) {hours += 0x06; }

 

Увеличение минут:

 

minutes++;

if(minutes == 0x5A) { minutes = 0; }

if((minutes & 0x0F) == 0x0A) { minutes += 0x06; }

 

Уменьшение часов:

 

hours--;

if(hours == 0xFF) { hours = 0x23; }

if((hours & 0x0F) == 0x0F) {hours -= 0x06; }

 

Уменьшение минут:

 

minutes--;

if(minutes == 0xFF) { minutes = 0x59; }

if((minutes & 0x0F) == 0x0F) { minutes -= 0x06; }

 

Это если время можно менять только с помощью кнопок "плюс" и "минус". Если возможен прямой ввод, то нужн писать функцию Validate_Time, которая будет исправлять все возможные ситуации. Потребуется много проверок, с этим ничего не поделать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вот за что я не люблю часы с "человеческим" интерфейсом.

Годятся только для отображения, а МК с ними работать весьма проблематично.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Очень многие человеческие единицы измерения неудобны для машин. Не говоря уже о 60-и минутах и 24-х часах, неудобно и то, что "кило" это не 1024, а всего 1000 и т.д. :) Вот с дюймами раньше всё правильнее было - дюйм делили на 2, 4, 8 и т.д. Да и речь человеческая очень сильно отличается от всех языков программирования. Видно, не в том направлении техника развивается...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А вот еще задача, кажущаяся простой, но пока не нашел преемлимого решения.

 

Есть контроллер с часами DS1307.

 

Некое внешнее устройство время от времени передает в контроллер "эталонное" время. Необходимо установить часы DS1307, но только в том случае, если время на часах DS1307 отличается от принятого "эталонного" более чем на N секунд (например, N=10).

 

Читаем из часов: hour, min, sec.

Принимаем: Ehour, Emin, Esec.

 

Какам то образом сравниваем hour, min, sec и Ehour, Emin, Esec. Если разница между ними меньше N секунд, то hour=Ehour, sek=Esek, min=Emin и записываем все это в DS1307.

 

Но как сравнить hour, min, sec и Ehour, Emin, Esec??? С учетом перехода через час и через сутки!

 

Был вариант пересчитать время в число секунд с начала суток и потом сравнивать. Может есть еще варианты?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А зачем выдерживать минимальную разницу 10 сек? У меня такая же задача, обновляю DS1307 всегда, когда хост время шлет.

 

Если все-таки нужно вычислять разницу времени, вот откопал исходник на asm51, когда-то вычитал часы и минуты :)

 

;Input: R6,R5 = TM_H,TM_M
;Input: R4,R3 = Tn_H,Tn_M
;Out:   R4,R3 = TM_H,TM_M - Tn_H,Tn_M

SUB_T: CLR C
    MOV A,#5AH
    SUBB A,R3
    ADD A,R5
    DA A
    JC SU1
    CJNE A,#60H,$+3H
    CPL C
    JNC SU2
SU1:    ADD A,#40H
    DA A
    SETB C
SU2:      MOV R3,A
    PUSH PSW
    CLR C
    MOV A,#23H
    SUBB A,R4
    JNB AC,SU3
    SUBB A,#06H
SU3:    POP PSW
    ADDC A,R6
    DA A
    CJNE A,#24H,$+3H
    JC SU4
    ADD A,#76H
    DA A
SU4:    MOV R4,A
    RET

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А зачем выдерживать минимальную разницу 10 сек?
Не обязательно 10 секунд, можно и 2 сек, это как бы время неопределенности. Т.е. время передачи данных от хоста может быть каждый раз разным (у меня медленный радиоканал). Если мы каждый раз будем сразу устанавливать время в контроллере, то время в контроллере будет идти неравномерно (из за разного времени передачи), а длительность минуты будет 60 сек +- разница времени передачи от хоста к контроллеру. Чтобы все же в контроллере минута была точно 60 секунд, мы корректируем время не всякий раз после приема данных, а только в том случае, если оно отличается от эталонного на 10 сек (тогда одна минута будет не 60 секунд, зато все остальные точно 60).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А зачем корректировать время каждый раз после приема данных? Автономные часы ведьтак быстро не убегают. Достаточно корректировать один раз в сутки, например.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А зачем корректировать время каждый раз после приема данных? Автономные часы ведьтак быстро не убегают. Достаточно корректировать один раз в сутки, например.
Ну предположим, мы решили корректировать внутренние часы один раз в сутки в 00 часов. Первый раз включаем прибор, там произвольное время. Принимаем от хоста точное время, но не устанавливаем его, т.к. ждем, когда будет 00 часов. Нелогично! Или на хосте изменили время (зимнее/летнее или просто подкорректировали) то же самое, синхронизация произойдет только в назначенное время.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А зачем корректировать время каждый раз после приема данных? Автономные часы ведьтак быстро не убегают. Достаточно корректировать один раз в сутки, например.

Ну предположим, мы решили корректировать внутренние часы один раз в сутки в 00 часов. Первый раз включаем прибор, там произвольное время. Принимаем от хоста точное время, но не устанавливаем его, т.к. ждем, когда будет 00 часов. Нелогично! Или на хосте изменили время (зимнее/летнее или просто подкорректировали) то же самое, синхронизация произойдет только в назначенное время.

Ну дык корректируйте его при включении, а далее 1 раз в сутки.

 

Да, забыл сказать, дневную коррекцию делаем между 2 и 3 часами ночи

(ну или когда у нас там официально переводят часы зима/лето)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

(ну или когда у нас там официально переводят часы зима/лето)

В ноль часов по Гринвичу в ночь с последней субботы на последнее воскресенье марта или октября.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В ноль часов по Гринвичу в ночь с последней субботы на последнее воскресенье марта или октября.

С такими обобщениями - осторожнее, если собираетесь эксплуатировать прибор за пределами

Украины. По Европейским часовывым поясам час перехода завязан на GMT+2, что лишь случайно для Украины совпадает с GMT 0, Для многих других стран расположенных дальше от Британии - привязан к 0 по локальному времени +2..3 часа. Даты перехода тоже разные для разных регионов в "нормальных" регионах разбегаются месяца Апрель/Март и Первая/Последняя неделя месяца. Для "ненормальных" регионов с "мусульманским" летоисчислением - вообще полный мрак встречается :-(.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...