|
DS1307 и день недели |
|
|
|
May 5 2008, 18:47
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
Не получается вытащить номер дня недели из RTC DS1307. Всё остальное вытаскивается нормально, а день недели всё время 2. Вот функция, отвечающая за это: Код void rtc_get_time(rtc_type *rtc_var) { i2c_start(); i2c_write_addr(DS1307_ADDR | WR); i2c_write(0x00); i2c_start(); i2c_write_addr(DS1307_ADDR | RD);
rtc_var->seconds = bcd2dec(i2c_read(ACK) & 0x7F); rtc_var->minutes = bcd2dec(i2c_read(ACK)); rtc_var->hours = bcd2dec(i2c_read(ACK) & 0x3F);
rtc_var->weekday = i2c_read(ACK) & 0x07;
rtc_var->day = bcd2dec(i2c_read(ACK)); rtc_var->month = bcd2dec(i2c_read(ACK)); rtc_var->year = bcd2dec(i2c_read(NOT_ACK)) + 2002;
i2c_stop(); return; }
|
|
|
|
|
May 5 2008, 20:44
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
Цитата(aaarrr @ May 5 2008, 22:50)  День недели автоматом не ставится, это просто счетчик. Очень жаль  Значит эту функцию придётся возложить на МК... Цитата(aaarrr @ May 5 2008, 22:50)  0, 4, 8 и т.д. Спасибо, я так и думал. Цитата(aaarrr @ May 5 2008, 23:28)  2000-й год был високосным (делится на 400), 2100-й не будет. А вышла DS1307 до 2000-го года. Но вряд ли кого-либо интересует сейчас "проблема 2100"  Вообще-то 2100 тоже будет високосным (я имею ввиду не в DS1307, а в жизни). А вот в RTC 2100 года быть не может. Точнее, это зависит от того, какую константу я добавлю к значению года (почему-то принято 2000, но ничего не мешает добавить любой другой, кратный 4). Т.е. после 2099 года будет снова 2000 - високосный год. Или этот регистр не закольцован, как остальные? А вообще эта проблема меня действительно волнует мало, т.к. я скорей всего до этого не доживу
|
|
|
|
|
May 5 2008, 21:02
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
Цитата(aaarrr @ May 5 2008, 23:54)  Не будет: делится на 100 нацело. 2000 тоже делится на 100 нацело. Только он был високосным. У меня ещё один вопрос по теме. Если день недели всего счётчик, то считает ли он перевод часов? Т.е. если я переведу часы (календарь) на сутки вперёд, добавится ли к дню недели единица? Или это тоже надо реализовывать программно?
Сообщение отредактировал TarasG - May 5 2008, 21:08
|
|
|
|
|
May 5 2008, 21:04
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(TarasG @ May 6 2008, 01:02)  2000 тоже делится на 100 нацело. Только он был високосным. 2000 делится еще и на 400. Цитата(TarasG @ May 6 2008, 01:02)  У меня ещё один вопрос по теме. Если день недели всего счётчик, то считает ли он перевод часов? Т.е. если я переведу часы (календарь) на сутки вперёд, добавится ли к дню недели единица? Или это тоже надо реализовывать программно? Нет, нужно делать программно.
|
|
|
|
|
May 5 2008, 21:10
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
Цитата(aaarrr @ May 6 2008, 00:04)  2000 делится еще и на 400. Да, простите. Только что прочитал на Википедии. То, о чём я говорю, называется Юлианским календарём. А современный мир живёт по Григорианскому. А я думал, високосный год идёт каждые 4 года
|
|
|
|
|
May 6 2008, 10:15
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
Цитата(aaarrr @ May 6 2008, 00:04)  Нет, нужно делать программно. Получается, для меня не имеет значения, как RTC считет дни недели - с понедельника или с воскресенья. Я могу присвоить 6 мая 2008 года число 2 (вторник для меня и понедельник для RTC), но об этой разнице никто и не заподозрит, если все мои функции будут 2 обрабатывать как вторник. Правильно я рассуждаю?
Сообщение отредактировал TarasG - May 6 2008, 10:16
|
|
|
|
|
May 6 2008, 11:14
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
Цитата(ILYAUL @ May 6 2008, 13:49)  Дополнительный материал. Собственно можно взять D/S на микросхему и к приложенному файлу подставлять из D/S рисунки и таблицы Так это ж другая микросхема. У меня 1307, а это 1337
|
|
|
|
|
May 6 2008, 12:24
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
К сожалению, самого главного в 1337 нет (как и в 1307). Я имею ввиду автоматическое вычисление дня недели  Но этот вопрос я уже решил. Кстати, ещё интересно, есть ли такая функция в PCF8583 от Philips?
|
|
|
|
|
May 6 2008, 14:05
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
Цитата(arttab @ May 6 2008, 16:42)  Извините что не в тему, но по 1307. если я не делал больших пайз между считыванием данных, то данные косячились. Работал по флагу готовности. А у вас как со считыванием данных? Без проблем? А что Вы называете большими паузами? У меня считывание данных идёт в бесконечном цикле, в котором помимо этого содержится также проверка состояний кнопок (антидребезговая задежка 30ms на 2 кнопки), проверка режима работы устройства и обработка нажатий кнопок (изменение режима работы). Кроме того, примерно 100-150 раз в секунду срабатывает прерывание от таймера (для динамической индикации). Сбоев вроде не было
|
|
|
|
|
May 6 2008, 15:43
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
Цитата(ILYAUL @ May 6 2008, 17:45)  Я считываю по прерыванию от DS каждую секунду , вроде проблем нет Я тоже изначально думал так сделать, но функции работы с i2c и с DS в частности связаны с ожиданием. Поэтому в момент прерывания у меня на мгновение стала пропадать индикация  Пришлось сделать так, как я описал
|
|
|
|
|
May 6 2008, 15:44
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(defunct @ May 6 2008, 00:01)  .. А на деле - ведь нет никакой проблемы. +1 бОльшая проблема будет когда будет 2070 год...от тогда проблема будет..а пока...фигня енто всё... с уважением (круглый)
|
|
|
|
|
May 6 2008, 17:20
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
Цитата(ILYAUL @ May 6 2008, 19:44)  Вот тут же и нашёл , и что интересно ровно год назад . Так сказать все ответы на Ваши вопросы в одной куче http://electronix.ru/forum/index.php?showt...=23755&st=0Та это и проблемами назвать как-то трудно. Работает то всё нормально...
|
|
|
|
|
May 8 2008, 08:41
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
Цитата(arttab) //start TWCR=(1<<TWINT)|(1<<TWSTA)|(0<<TWSTO)|(1<<TWEN); // on TWE and START while (TWCR&(1<<TWINT)==1) {;} // wait set START on the TWI __delay_cycles(9000); // UDR=TWSR; //ask device on adres and Write TWDR=ADRESDS|0x00; // adres and read TWCR=(1<<TWINT)|(0<<TWSTA)|(0<<TWSTO)|(1<<TWEN); // on TWE and Adres R while (TWCR&(1<<TWINT)==1) {;} // wait TWI __delay_cycles(9000); // UDR=TWSR; //read and send adres cell TWDR=0x00; // adres ask cell TWCR=(1<<TWINT)|(0<<TWSTA)|(0<<TWSTO)|(1<<TWEN); // on TWE while (TWCR&(1<<TWINT)==1) {;} // wait TWI __delay_cycles(9000); // UDR=TWSR; У меня сделано немного иначе. Функция не бесконечно ждёт сброса TWINT, а определённое время, по прошествии которого выдаёт сообщение об ошибке. Код void i2c_delay(void) { if (i2c_error) return; for (unsigned char i = 0; i < 100; i++) { if (TWCR & (1 << TWINT)) return; _delay_loop_1(0.000001 * F_CLK); } i2c_error = 1; } Вообще, по-моему, так сильно сложнополучается. Работу с TWI лучше разбить на функции, так проще.
|
|
|
|
|
May 9 2008, 10:15
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
Цитата(arttab @ May 9 2008, 07:12)  Кстати, пока twi не готов его статус 0xff. вот где собачка порылась. надо while ( (TWCR&(1<<TWINT)==1) && (TWCR!=0xff) ) {;} // wait set START on the TWI А зачем? Ведь если TWCR = 0xFF, то и бит TWINT в нём однозначно 1. Т.е. проверки (TWCR & (1 << TWINT) == 1 вполне достаточно. Или Вы имеете ввиду статус (TWSR) 0xFF? Только я при инициализации этот регистр обнуляю: Код void i2c_init(void) { TWSR = 0; TWDR = 0; TWAR = 0; TWBR = TWI_TWBR; //установить скорость шины i2c TWCR = ((1 << TWEN) | (1 << TWINT)); //включить модуль i2c i2c_error = 0; //первоначально ошибок нет return; } Вообще-то это не я придумал, а скачал билиотеку с этого форума. Но я её немного переделал
|
|
|
|
|
May 9 2008, 19:31
|

Местный
  
Группа: Свой
Сообщений: 263
Регистрация: 7-10-05
Из: UA
Пользователь №: 9 342

|
Цитата(TarasG @ May 6 2008, 15:24)  Кстати, ещё интересно, есть ли такая функция в PCF8583 от Philips? Нету. Там, насколько я помню, еще хуже: под год выделено 2 бита, т.е. только 4-годичный цикл отслеживается. Цитата(kolobok0 @ May 6 2008, 18:44)  +1 бОльшая проблема будет когда будет 2070 год...от тогда проблема будет..а пока...фигня енто всё... А что будет в 2070? Вот в 2038 эпоха UNIX-а закончится.
--------------------
Gray©at
|
|
|
|
|
May 9 2008, 20:08
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
Цитата(GrayCat @ May 9 2008, 22:31)  Нету. Там, насколько я помню, еще хуже: под год выделено 2 бита, т.е. только 4-годичный цикл отслеживается. Вообще-то я имел ввиду вычисление дня недели. А 4-годичный цикл хоть и не очень приятно, но терпимо Цитата(GrayCat @ May 9 2008, 22:31)  Вот в 2038 эпоха UNIX-а закончится. Ну это спорный вопрос. Ничего не мешает к тому времени перевести время на 64-битное число. Тогда эта дата отодвинется на несколько миллиардов лет  Не знаю, но в 64-битных система возможно так уже сделано
Сообщение отредактировал TarasG - May 9 2008, 20:09
|
|
|
|
|
May 10 2008, 08:18
|

Местный
  
Группа: Свой
Сообщений: 263
Регистрация: 7-10-05
Из: UA
Пользователь №: 9 342

|
Цитата(TarasG @ May 9 2008, 23:08)  Вообще-то я имел ввиду вычисление дня недели. Я тоже. Т.к. PCF8583 микросхема еще более старая чем Даллас 1307, то фичей в ней меньше, а потребление от батарейки больше. Смысла ее использовать вообще нет. Цитата Ну это спорный вопрос. Ничего не мешает к тому времени перевести время на 64-битное число. Тогда эта дата отодвинется на несколько миллиардов лет  Не знаю, но в 64-битных система возможно так уже сделано  Так сделано даже в хорошо продуманных изначально 32-бит системах. Например, в QNX есть в документации такая строка: "Внимание! Этот 64-битный счетчик наносекунд переполнится в 2483 году! Если вы планируете использование ваших программ после 2483, обязательно предусмотрите соответствующие проверки!"
--------------------
Gray©at
|
|
|
|
|
May 10 2008, 09:15
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
Цитата(GrayCat @ May 10 2008, 11:18)  Я тоже. Т.к. PCF8583 микросхема еще более старая чем Даллас 1307, то фичей в ней меньше, а потребление от батарейки больше. Смысла ее использовать вообще нет. А мне из даташита показалось, что в неё как раз больше функциональность. Например, сотые доли секунды, таймеры и т.д. В моём случае это, конечно, не нужно. Но в других может и понадобится... Цитата(GrayCat @ May 10 2008, 11:18)  Значит проблема разрешима  Думаю, когда реально припечёт - за пару лет до даты Х - быстро выйдут соответствующие патчи и проблема будет решена
|
|
|
|
|
May 11 2008, 03:53
|

Профессионал
    
Группа: Свой
Сообщений: 1 432
Регистрация: 7-12-04
Из: Новосибирск
Пользователь №: 1 371

|
Цитата А зачем? Ведь если TWCR = 0xFF, то и бит TWINT в нём однозначно 1. Т.е. проверки (TWCR & (1 << TWINT) == 1 вполне достаточно. Или Вы имеете ввиду статус (TWSR) 0xFF? Только я при инициализации этот регистр обнуляю: Ляпнул, позабыв чего делал в эксперементе. Мне не понравилось что необходима задержка после выстакления флага готовности прежде чем я могу нормально забрать данные из TWSR. Цитата А зачем? Ведь если TWCR = 0xFF, то и бит TWINT внём однозначно 1. Т.е. проверки (TWCR & (1 << TWINT) == 1 вполне достаточно. Или Вы имеете ввиду статус (TWSR) 0xFF? Только я при инициализации этот регистр обнуляю: Ляпнул, позабыв чего делал в эксперементе. Мне не понравилось что необходима задержка после выставления флага готовности прежде чем я могу нормально забрать данные из TWSR. Вот я и спросил про задержку. толи мне бракованные образцы попались
--------------------
OrCAD, Altium,IAR, AVR....
|
|
|
|
|
May 11 2008, 09:07
|

Участник

Группа: Новичок
Сообщений: 72
Регистрация: 25-02-08
Пользователь №: 35 378

|
По-моему, задержка там нужна не после выставления флага, а пока он ещё не установлен. Другими словами, чтоб выполнить действие (например, что-то отправить) нужно установить этот флаг в 1. На отправку данных уходит какое-то время, поэтому TWI некоторое время занят. По завершении действия флаг TWINT автоматически установтся в 0. Но пока он 1 - надо ждать, для чего и вводится задержка. Ещё раз привожу рабочий код: Код unsigned char i2c_error; void i2c_start(void) { if (i2c_error) return; TWCR = ((1 << TWEN) | (1 << TWINT) | (1 << TWSTA)); i2c_delay(); if ((TWSR != START) && (TWSR != REP_START)) i2c_error = 1; return; } void i2c_delay(void) { if (i2c_error) return; for (unsigned char i = 0; i < 100; i++) { if (TWCR & (1 << TWINT)) return; _delay_loop_1(0.000001 * F_CLK); } i2c_error = 1; return; }
Сообщение отредактировал TarasG - May 11 2008, 09:31
|
|
|
|
|
May 11 2008, 13:50
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
Цитата(TarasG @ May 11 2008, 13:07)  По-моему, задержка там нужна не после выставления флага, а пока он ещё не установлен. Другими словами, чтоб выполнить действие (например, что-то отправить) нужно установить этот флаг в 1. На отправку данных уходит какое-то время, поэтому TWI некоторое время занят. По завершении действия флаг TWINT автоматически установтся в 0. Но пока он 1 - надо ждать, для чего и вводится задержка. Ну , не совсем так При формировании какого либо действия на шине TWI Вы дожны TWCR записать , что Вы собственно хотите от TWI , Код ldi temp, (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); формирование сигнала START sts TWCR, temp Как только выполниться команда STS - дальнейшее от Вас не зависит ибо , TWINT сбросится в 0 , сформируется Start , а вот дальше придётся ждать когда TWINT снова станет 1 и в регистре TWSR появиться код выполнения операции ( в данном случае старт) . Лучше просто проверять TWINT на 1 - просмотреть код возврата , и принять решение, что делать дальше Код ;************************************************* ;* * ;* Подпрограмма Init TWI_START * ;* Формирование START и проверка ответа. * ;* * ;* * ;*************************************************
TWI_START: ldi temp, (1<<TWINT)|(1<<TWSTA)|(1<<TWEN); формирование сигнала START sts TWCR, temp waitST: lds temp,TWCR ; Проверка бита TWINT sbrs temp,TWINT rjmp waitST ; Не получен -цикл lds temp,TWSR; Проверка кода ответа andi temp,$F8 ; cpi temp,START ;code=08 breq RETURN ; Правильный код -выход из подпрограммы brne TWI_START ; Нет - повтор. RETURN: ret И код 0xFF я в TWI не нашёл? есть F8 - не сформирован START (STOP) - вообще-то просто промежуточный код и есть 00- ошибка на шине Остальные коды есть в DS на каждый проц , но они стандартны для всех В такой режиме Вы не пропустите данные и всегда знаете , что делать с шиной.
Сообщение отредактировал ILYAUL - May 11 2008, 13:51
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|