Перевод DS1307 библиотеки в v1.0

Alex1503
Offline
Зарегистрирован: 16.06.2012

Всем здравствуйте!
Есть очень удобная и простая в использовании библиотека для часов DS1307.
Взято отсюда:arduino-info.wikispaces.com/RTC

DS1307.h:

/*
  DS1307.h - library for DS1307 rtc
*/

// ensure this library description is only included once
#ifndef DS1307_h
#define DS1307_h

// include types & constants of Wiring core API
#include <WConstants.h>

// include types & constants of Wire ic2 lib
#include <../Wire/Wire.h>

#define DS1307_SEC 0
#define DS1307_MIN 1
#define DS1307_HR 2
#define DS1307_DOW 3
#define DS1307_DATE 4
#define DS1307_MTH 5
#define DS1307_YR 6

#define DS1307_BASE_YR 2000

#define DS1307_CTRL_ID B1101000  //DS1307

 // Define register bit masks
#define DS1307_CLOCKHALT B10000000

#define DS1307_LO_BCD  B00001111
#define DS1307_HI_BCD  B11110000

#define DS1307_HI_SEC  B01110000
#define DS1307_HI_MIN  B01110000
#define DS1307_HI_HR   B00110000
#define DS1307_LO_DOW  B00000111
#define DS1307_HI_DATE B00110000
#define DS1307_HI_MTH  B00110000
#define DS1307_HI_YR   B11110000

// library interface description
class DS1307
{
  // user-accessible "public" interface
  public:
    DS1307();
    void get(int *, boolean);
    int get(int, boolean);
	void set(int, int);
    void start(void);
    void stop(void);

  // library-accessible "private" interface
  private:
    byte rtc_bcd[7]; // used prior to read/set ds1307 registers;
	void read(void);
	void save(void);
};

extern DS1307 RTC;

#endif

DS1307.cpp:

extern "C" {
#include <../Wire/Wire.h>
}
#include "DS1307.h"

DS1307::DS1307()
{
  Wire.begin();
}

DS1307 RTC=DS1307();

// PRIVATE FUNCTIONS

// Aquire data from the RTC chip in BCD format
// refresh the buffer
void DS1307::read(void)
{
  // use the Wire lib to connect to tho rtc
  // reset the resgiter pointer to zero
  Wire.beginTransmission(DS1307_CTRL_ID);
  Wire.send(0x00);
  Wire.endTransmission();

  // request the 7 bytes of data    (secs, min, hr, dow, date. mth, yr)
  Wire.requestFrom(DS1307_CTRL_ID, 7);
  for(int i=0; i<7; i++)
  {
    // store data in raw bcd format
    rtc_bcd[i]=Wire.receive();
  }
}

// update the data on the IC from the bcd formatted data in the buffer
void DS1307::save(void)
{
  Wire.beginTransmission(DS1307_CTRL_ID);
  Wire.send(0x00); // reset register pointer
  for(int i=0; i<7; i++)
  {
    Wire.send(rtc_bcd[i]);
  }
  Wire.endTransmission();
}


// PUBLIC FUNCTIONS
void DS1307::get(int *rtc, boolean refresh)   // Aquire data from buffer and convert to int, refresh buffer if required
{
  if(refresh) read();
  for(int i=0;i<7;i++)  // cycle through each component, create array of data
  {
    rtc[i]=get(i, 0);
  }
}

int DS1307::get(int c, boolean refresh)  // aquire individual RTC item from buffer, return as int, refresh buffer if required
{
  if(refresh) read();
  int v=-1;
  switch(c)
  {
  case DS1307_SEC:
    v=(10*((rtc_bcd[DS1307_SEC] & DS1307_HI_SEC)>>4))+(rtc_bcd[DS1307_SEC] & DS1307_LO_BCD);
    break;
  case DS1307_MIN:
    v=(10*((rtc_bcd[DS1307_MIN] & DS1307_HI_MIN)>>4))+(rtc_bcd[DS1307_MIN] & DS1307_LO_BCD);
    break;
  case DS1307_HR:
    v=(10*((rtc_bcd[DS1307_HR] & DS1307_HI_HR)>>4))+(rtc_bcd[DS1307_HR] & DS1307_LO_BCD);
    break;
  case DS1307_DOW:
    v=rtc_bcd[DS1307_DOW] & DS1307_LO_DOW;
    break;
  case DS1307_DATE:

    
       v=rtc_bcd[DS1307_DATE]/16 * 10 +  rtc_bcd[DS1307_DATE] % 16;
    
    break;
  case DS1307_MTH:
    v=(10*((rtc_bcd[DS1307_MTH] & DS1307_HI_MTH)>>4))+(rtc_bcd[DS1307_MTH] & DS1307_LO_BCD);
    break;
  case DS1307_YR:

    
      v=2000 + rtc_bcd[DS1307_YR]/16 * 10 + rtc_bcd[DS1307_YR] % 16;
    
    break; 

  } // end switch
  return v;
}

void DS1307::set(int c, int v)  // Update buffer, then update the chip
{
  switch(c)
  {
  case DS1307_SEC:
    if(v<60 && v>-1)
    {
      //preserve existing clock state (running/stopped)
      int state=rtc_bcd[DS1307_SEC] & DS1307_CLOCKHALT;
      rtc_bcd[DS1307_SEC]=state | ((v / 10)<<4) + (v % 10);
    }
    break;
  case DS1307_MIN:
    if(v<60 && v>-1)
    {
      rtc_bcd[DS1307_MIN]=((v / 10)<<4) + (v % 10);
    }
    break;
  case DS1307_HR:
    // TODO : AM/PM  12HR/24HR
    if(v<24 && v>-1)
    {
      rtc_bcd[DS1307_HR]=((v / 10)<<4) + (v % 10);
    }
    break;
  case DS1307_DOW:
    if(v<8 && v>-1)
    {
      rtc_bcd[DS1307_DOW]=v;
    }
    break;
  case DS1307_DATE:
    if(v<32 && v>-1)
    {
      rtc_bcd[DS1307_DATE]=((v / 10)<<4) + (v % 10);
    }
    break;
  case DS1307_MTH:
    if(v<13 && v>-1)
    {
      rtc_bcd[DS1307_MTH]=((v / 10)<<4) + (v % 10);
    }
    break;
  case DS1307_YR:
    if(v<50 && v>-1)
    {
      rtc_bcd[DS1307_YR]=((v / 10)<<4) + (v % 10);
    }
    break;
  } // end switch
  save();
}

void DS1307::stop(void)
{
  // set the ClockHalt bit high to stop the rtc
  // this bit is part of the seconds byte
  rtc_bcd[DS1307_SEC]=rtc_bcd[DS1307_SEC] | DS1307_CLOCKHALT;
  save();
}

void DS1307::start(void)
{
  // unset the ClockHalt bit to start the rtc
  // TODO : preserve existing seconds
  rtc_bcd[DS1307_SEC]=0;
  save();
}

Тестовый скетч:

/*Reads the value from a Real Time Clock (RTC) DS1307 and displays it in the serial monitor
 *
 *Created by D. Sjunnesson 1scale1.com d.sjunnesson (at) 1scale1.com
 *
 *Created with combined information from 
 *<a data-cke-saved-href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1180908809" href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1180908809" rel="nofollow">http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1180908809</a>
 *<a data-cke-saved-href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1191209057" href="http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1191209057" rel="nofollow">http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1191209057</a>
 *
 *
 *Big credit to  mattt (please contact me for a more correct name...) from the Arduino forum 
 *which has written the main part of the library which I have modified
 *
 */

#include <WProgram.h>
#include <Wire.h>
#include <DS1307.h> // written by  mattt on the Arduino forum and modified by D. Sjunnesson

void setup()
{
  Serial.begin(9600);

  RTC.stop();
  RTC.set(DS1307_SEC,1);        //set the seconds
  RTC.set(DS1307_MIN,23);     //set the minutes
  RTC.set(DS1307_HR,12);       //set the hours
  RTC.set(DS1307_DOW,4);       //set the day of the week
  RTC.set(DS1307_DATE,5);       //set the date
  RTC.set(DS1307_MTH,3);        //set the month
  RTC.set(DS1307_YR,9);         //set the year
  RTC.start();

}

void loop()
{

  Serial.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
  Serial.print(":");
  Serial.print(RTC.get(DS1307_MIN,false));//read minutes without update (false)
  Serial.print(":");
  Serial.print(RTC.get(DS1307_SEC,false));//read seconds
  Serial.print("      ");                 // some space for a more happy life
  Serial.print(RTC.get(DS1307_DATE,false));//read date
  Serial.print("/");
  Serial.print(RTC.get(DS1307_MTH,false));//read month
  Serial.print("/");
  Serial.print(RTC.get(DS1307_YR,false)); //read year 
  Serial.println();

  delay(1000);

}

Она прекрасно работает в Arduino v0023, но мне очень надо перевести ее в v1.0.
Я обращался за помощью на англоязычный форум Arduino.cc, но все, что мне рекомендовали
было в DS1307.h заменить #include WProgram.h и WConstants.h на Arduino.h и как стандартный
вариант использовать :

#if defined(ARDUINO) && ARDUINO >= 100
#include "Arduino.h"

#else
#include "WProgram.h"
#include "WConstants.h"
#endif

 

А так же где есть wire.send/wire.receive заменить на wire.write/wire.read.
Пробовал я все это проделать, но в силу моей неопытности ничего у меня не вышло.
Была рекомендация взять какую либо другую библиотеку уже работающую в v1.0, но
дело в том, что у меня с этой библиотекой уже написан большой скетч ( не мной ), который мне надо будет дополнить элементом, работающим исключительно в v1.0.
В интернете я нашел сайт, где уже была частично удавшаяся попытка это сделать:

http://arduino.cc/forum/index.php?topic=87912.0

Помогите пожалуйста!
 

LEVV2006
LEVV2006 аватар
Offline
Зарегистрирован: 15.04.2011

ИМХО. Зачем использовать дополнительные библиотеки когда стандартными можно обойтись. Зачем вам посредники!

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68


byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}


byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.write(0);
   Wire.write(decToBcd(second));    
   Wire.write(decToBcd(minute));
   Wire.write(decToBcd(hour));     
   Wire.endTransmission();
}


void getDateDs1307(byte *second,
          byte *minute,
          byte *hour)
{

  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 3);

  *second     = bcdToDec(Wire.read());
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read());  
}

void setup()
{
  byte second, minute, hour;
  Wire.begin();
  Serial.begin(9600);

  second = 45;
  minute = 3;
  hour = 7;

  setDateDs1307(second, minute, hour);
}

void loop()
{
  byte second, minute, hour;

  getDateDs1307(&second, &minute, &hour);
  Serial.print(hour, DEC);
  Serial.print(":");
  Serial.print(minute, DEC);
  Serial.print(":");
  Serial.println(second, DEC);


  delay(1000);
}

 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

LEVV2006 пишет:

ИМХО. Зачем использовать дополнительные библиотеки когда стандартными можно обойтись. Зачем вам посредники!

Сохранил себе в "полезняшки" :) Спасибо.

LEVV2006
LEVV2006 аватар
Offline
Зарегистрирован: 15.04.2011

AlexFisher пишет:

LEVV2006 пишет:

ИМХО. Зачем использовать дополнительные библиотеки когда стандартными можно обойтись. Зачем вам посредники!

 

Сохранил себе в "полезняшки" :) Спасибо.

 

Там код чтобы время изымать. А есть дополнение чтобы и дату знать.
А можешь поделиться полезняками)))) levvarr собака ya.ru
 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Увы, вынужден расстроить :( Идея собирания полезняшек пришла только что, и кроме Вашей там пока ничего нет. Но на будущее - буду иметь в виду. Поделюсь :)

leshak
Offline
Зарегистрирован: 29.09.2011

 Осталось только оформить эту полезняшку в виде библиотеки, для большего удобства повторного использованияи... "Зачем вам посредники!"

;)

Библиотека же, от "просто функции скопировать в скетч" отличается только "удобством использования". Что-бы не засорять собственный скетч вспомогательными функциями. Да и, если скетчей много, не приходилось, если затесалась ошибка, бегать потом по 10-ти местам и везде вносить поправку.

Вообщем библиотеки и возникли для реализации потребности "повторно использовать код". Так что "полезняшки" нужно хранить в виде библиотек :) Copy-paste - зло.

 

AlexFisher
AlexFisher аватар
Offline
Зарегистрирован: 20.12.2011

Согласен. Но библиотека подразумевает нечто большее, чем работающий кусок кода... Как минимум, хорошее описание, функциональный обхват... Будет время - сделаю библу, а пока пускай так полежит :)

Alex1503
Offline
Зарегистрирован: 16.06.2012

Вот ссылка на DS1307 для 1.0:
http://arduino.cc/forum/index.php?topic=93077.0
 

Bim_Sony
Bim_Sony аватар
Offline
Зарегистрирован: 03.10.2012

LEVV2006, а можно в вашем примере сделать функции чтения/записи даты и дня недели?

 

Еще объясниет мне, каким образом назначается адрес:

#define DS1307_I2C_ADDRESS 0x68

 

LEVV2006
LEVV2006 аватар
Offline
Зарегистрирован: 15.04.2011

 

Да можно. Надо посмотреть дома.

Про адрес: я этот код сам откуда то взял. Этот адрес по-моему стандартный для всех часов. По крайней мере я использовал этот код во всех часах и всё нормально работало. 

LEVV2006
LEVV2006 аватар
Offline
Зарегистрирован: 15.04.2011

Вот!!! Часы + календарь

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68

byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.write(0);
   Wire.write(decToBcd(second));    
   Wire.write(decToBcd(minute));
   Wire.write(decToBcd(hour));     
   Wire.write(decToBcd(dayOfWeek));
   Wire.write(decToBcd(dayOfMonth));
   Wire.write(decToBcd(month));
   Wire.write(decToBcd(year));
   Wire.endTransmission();
}

void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{

  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f); 
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

void setup()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  Serial.begin(9600);

  second = 45;
  minute = 3;
  hour = 7;
  dayOfWeek = 5;
  dayOfMonth = 17;
  month = 4;
  year = 8;
  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}

void loop()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  Serial.print(hour, DEC);
  Serial.print(":");
  Serial.print(minute, DEC);
  Serial.print(":");
  Serial.print(second, DEC);
  Serial.print("  ");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(year, DEC);
  Serial.print("  Day_of_week:");
  Serial.println(dayOfWeek, DEC);

  delay(1000);
}

 

ustas
Offline
Зарегистрирован: 12.03.2012

LEVV2006, спасибо. А как Ваш код изменить для использования с мега? (SDA, SCL соответственно на 20, 21 пинах)?

LEVV2006
LEVV2006 аватар
Offline
Зарегистрирован: 15.04.2011

 

У меня меги нет. Так что я не знаю как для неё нужно писать код. Возможно нужно подключить библиотеку Wire.h. для меги

Bim_Sony
Bim_Sony аватар
Offline
Зарегистрирован: 03.10.2012

LEVV2006, спасибо

ustas
Offline
Зарегистрирован: 12.03.2012

LEVV2006, похоже, ничего в коде менять не надо - компилятор и так все слопал. Но на выходе получаю вот такие значения:

 

45:165:85  165/165/165  Day_of_week:165
 
(к слову, остальные библиотеки для часиков дают аналогичные значения)
 
Еще заметил, что если убрать резервную батарейку значения становятся чуть осмысленнее:
 
7:3:45  4/17/8  Day_of_week:5
 
но все равно часы "стоят". 
 
(используется плата IPoard Pro - http://imall.iteadstudio.com/iboard-pro.html)
 
с отдельными модулями RTC проблем не было, а тут что-то запустить не могу :( 
Дайте направление мысли? Куда копать?

 

LEVV2006
LEVV2006 аватар
Offline
Зарегистрирован: 15.04.2011

 

Быстрый поиск результатов. Не дал результата но у меня дома есть где то в закладках как работают эти часы.

Пока так

1)      вы должны проверить правильность подключения микросхемы по даташиту.

2)      Если на отдельном модуле работает нормально а на плате нет. То скорее всего немного неправильный код.

3)      Я точно помню что в часах есть управляющий бит отвечающий за пуск и остановку счётчика времени.

 

 

Зы. Я тоже получал такие значения при неправильном подключении кажется (не судите строга я с часами больше 8 месяцев назад имел дело и сейчас многих деталей не помню)

ps http://avrdevices.ru/chasi-realynogo-vremeni-ds1307/

ustas
Offline
Зарегистрирован: 12.03.2012

Так... вот что удалось выяснить.

1. модуль часов распаян на плате верно (заводская плата, но все равно проверил разводку и убедился, что все правильно)

2. когда батарейки резервной нет часы показывают установленное время и стоят (вполне ожидаемо)

3. когда резервная батарейка стоит, часы дают время-дату: 45:165:85  165/165/165 и часы тоже стоят.

вот интересно, с чем это может быть связано? Если кварц "мертвый" - возможна такая "работа"?

 

еще прочитал про бит "запрет осцилляции"  (7й бит по адресу 0x0h) - по умолчанию он стоит в 1 (часы будут стоять), нужно поставить в "0"

Как это сделать?

LEVV2006
LEVV2006 аватар
Offline
Зарегистрирован: 15.04.2011
Wire.beginTransmission(DS1307_I2C_ADDRESS);
Wire.write(0);
Wire.write(0x0h);    
Wire.write(0);
Wire.endTransmission();

Может быть так? Надо спросить у профессионалов на форуме!!!

ustas
Offline
Зарегистрирован: 12.03.2012

этот кусок не компилируется даже. 

ошибка error: invalid suffix "h" on integer constant

ustas
Offline
Зарегистрирован: 12.03.2012

нашел, в чем причина

оказалось, "железячная". Разработчики платы развели плату таким образом, что 8 нога от DS1307 (Vcc) идет на 3.3В

Таким образом, этот модуль вообще на плате НИКОГДА работать не будет (модуль включается на нормальный режим работы, когда напряжение на Vcc больше, чем 1.25*Vbat). Батарейка используется 3В

error911
Offline
Зарегистрирован: 06.10.2012

у меня была та же проблема. пока я не нашел другую библиотеку и не подключил часы к i2c на мене меге 20 и 21 нога. и все заработало. если надо, могу скинуть библ.

ustas
Offline
Зарегистрирован: 12.03.2012

в данном случае проблема именно с питанием.

после того, как "оторвал" ножку 8 микросхемы DS1307 и не повесил ее на +5В (напомню, была на 3.3В разведена) - система не работала. 

Сейчас работает хорошо, но часы останавливаются, если отключить питание. Описание такой проблемы уже было и на этом форуме (предлагалось конденсатор по питанию этой микросхеме подключить - пробовал, не помогло.. еще предлагали посмотреть цепь сброса у микроконтроллера (подтяжка) - имеется, и все равно часы "встают").

Решение до конца не найдено, но часики тикают.

error911
Offline
Зарегистрирован: 06.10.2012

Можно вопрос почти в тему?...

Приобрел модуль RTC, на нем микросхема часов и еще одна. Как я понял это память чтоль еще? Зачем она вообще?

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

error911 пишет:

Приобрел модуль RTC, на нем микросхема часов и еще одна. Как я понял это память чтоль еще? Зачем она вообще?

Как пишут китайцы: "56 байт слаболетучей памяти имеющеся к потребителю". Использовать - можно вместо eeprom для сохранения данных между перезагрузками, или при отключении питания ардуины. Мне сейчас тоже приехали две таких платы - буду изучать возможности... Про сам чип AT24C32AN-10SU-2.7 пишут, что он 32 килобайта (4096х8), и рассчитан на 1 миллион циклов записи и 100 лет хранения (сравним с встроенным eeprom и порадуемся).

Более вдумчивое чтение

http://robozone.su/info/10-ds1307-chasy-realnogo-vremeni-s.html

и

http://www.henningkarlsen.com/electronics/library.php?id=34

подсказывает, что 56 байт остается свободными в самой микросхеме DS1307, а вторая микруха - это чистые 32К памяти.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

Питание: 5V (а не 3.3, как у китайцев на картинке нарисовано!), GND.

Подтягивающие резисторы уже есть на плате.

Пины для данных: (http://arduino.cc/en/Reference/Wire)

Board I2C / TWI pins
Uno, Ethernet A4 (SDA), A5 (SCL)
Mega2560 20 (SDA), 21 (SCL)
Leonardo 2 (SDA), 3 (SCL)
Due 20 (SDA), 21 (SCL), SDA1, SCL1

Сканируем программой i2c_scanner http://playground.arduino.cc//Main/I2cScanner

Scanning...
I2C device found at address 0x50 !
I2C device found at address 0x68 !
done

Это одна плата с двумя устройствами: часы и микросхема памяти...

С eeprom работает скетч: http://playground.arduino.cc/Code/I2CEEPROM.

saniks
Offline
Зарегистрирован: 09.04.2013

Можете поподробнее разъяснить как работет скетч от LEVV2006, а именно функция getDateDs1307











void getDateDs1307(byte *second,
          byte *minute,
          byte *hour)
{

  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 3);

  *second     = bcdToDec(Wire.read());
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read());  
}






getDateDs1307(&second, &minute, &hour);

Как я понял в нее передаются номера ячеек пямяти переменных second, minute, hour, затем считывается три байта из памяти ds1307 и  Wire.read записывает в соответствующие номерам переменные текущее время.

Я хочу запрашивать только минуты и часы (секунды не нужны), если убрать строки "byte *second" и "*second = bcdToDec(Wire.read());", то в hour записываются минуты, а в minute секунды.

Как можно запрашивать только второй и третий байт из ds1307?


 

 

maksim
Offline
Зарегистрирован: 12.02.2012

Да никак. Просто читаете первый байт впустую, а затем читаете минуты и часы

   Wire.read();
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read()); 

 

Peter
Peter аватар
Offline
Зарегистрирован: 25.02.2012

Добавил день, дату, месяц, год.  Может кому надо будет. 

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68


byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}


byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}


void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,
                   byte day,
                   byte date,
                   byte month,
                   byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.write(0);
   Wire.write(decToBcd(second));    
   Wire.write(decToBcd(minute));
   Wire.write(decToBcd(hour));
   Wire.write(decToBcd(day));  
   Wire.write(decToBcd(date));
   Wire.write(decToBcd(month));  
   Wire.write(decToBcd(year));   
   Wire.endTransmission();
}


void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *day,
          byte *date,
          byte *month,
          byte *year)
{

  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  *second     = bcdToDec(Wire.read());
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read());  
  *day        = bcdToDec(Wire.read());
  *date       = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

void setup()
{
  byte second, minute, hour, day, date, month, year;
  Wire.begin();
  Serial.begin(9600);

  second = 00;
  minute = 26;
  hour = 17;
  day = 3;
  date = 29;
  month = 1;
  year = 14;

  setDateDs1307(second, minute, hour, day, date, month, year);
}

void loop()
{
  byte second, minute, hour, day, date, month, year;

  getDateDs1307(&second, &minute, &hour, &day, &date, &month, &year);
  Serial.print(hour, DEC);
  Serial.print(":");
  Serial.print(minute, DEC);
  Serial.print(":");
  Serial.println(second, DEC);
  
  Serial.print(day, DEC);
  Serial.print("/");
  Serial.print(date, DEC);
  Serial.print(".");
  Serial.print(month, DEC);
  Serial.print(".");
  Serial.println(year, DEC);
  


  delay(1000);
}

Автору исхода спасибо.

Marlen S
Offline
Зарегистрирован: 13.01.2015

LEVV2006 пишет:

Вот!!! Часы + календарь

#include "Wire.h"
#define DS1307_I2C_ADDRESS 0x68

byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
   Wire.beginTransmission(DS1307_I2C_ADDRESS);
   Wire.write(0);
   Wire.write(decToBcd(second));    
   Wire.write(decToBcd(minute));
   Wire.write(decToBcd(hour));     
   Wire.write(decToBcd(dayOfWeek));
   Wire.write(decToBcd(dayOfMonth));
   Wire.write(decToBcd(month));
   Wire.write(decToBcd(year));
   Wire.endTransmission();
}

void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{

  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();

  Wire.requestFrom(DS1307_I2C_ADDRESS, 7);

  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f); 
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}

void setup()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  Wire.begin();
  Serial.begin(9600);

  second = 45;
  minute = 3;
  hour = 7;
  dayOfWeek = 5;
  dayOfMonth = 17;
  month = 4;
  year = 8;
  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
}

void loop()
{
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;

  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  Serial.print(hour, DEC);
  Serial.print(":");
  Serial.print(minute, DEC);
  Serial.print(":");
  Serial.print(second, DEC);
  Serial.print("  ");
  Serial.print(month, DEC);
  Serial.print("/");
  Serial.print(dayOfMonth, DEC);
  Serial.print("/");
  Serial.print(year, DEC);
  Serial.print("  Day_of_week:");
  Serial.println(dayOfWeek, DEC);

  delay(1000);
}

 

 

Братка, Спасибо за код :) Ты как с неба подан :) Часы DS1307 с Китая работают на ура, так же и DS1302 http://ru.aliexpress.com/item/1pc-hot-sale-DS3231-AT24C32-IIC-Precision-RTC-Real-Time-Clock-Memory-Module-Free-Shipping/1997483734.html?recommendVersion=1