общение с ds3132 по программному ic2

Тема в разделе "Arduino & Shields", создана пользователем Unikolai, 25 ноя 2016.

  1. Unikolai

    Unikolai Гик

    #define DS3231_I2C_ADDRESS 0x68
    void readDS3231time(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte*month, byte *year)

    {
    I2CStart();
    I2CWrite((DS3231_I2C_ADDRESS << 1));
    I2CWrite(0);
    I2CStop ();
    I2CStart();
    I2CWrite((DS3231_I2C_ADDRESS << 1) + 1);
    *second = bcdToDec(I2CRead(1) & 0x7f);
    *minute = bcdToDec(I2CRead(1));
    *hour = bcdToDec(I2CRead(1) & 0x3f);
    *dayOfWeek = bcdToDec(I2CRead(1));
    *dayOfMonth = bcdToDec(I2CRead(1));
    *month = bcdToDec(I2CRead(1));
    *year = bcdToDec(I2CRead(0));
    I2CStop ();
    }

    byte I2CRead(boolean ack)
    {
    byte i = 8;
    byte b = 0;
    while (i--)
    {
    b <<= 1;
    SCL_Lo();
    SDA_Hi();
    I2CDelay();
    SCL_Hi();
    //while(!SCL_In());
    if (SDA_In()) b |= 1;
    I2CDelay();
    SCL_Lo();
    }
    if (ack) SDA_Lo();
    else SDA_Hi();
    I2CDelay();
    SCL_Hi();
    //while(!SCL_In());
    I2CDelay();
    SCL_Lo();
    return (b);

    }
    всем привет, объясните, что значит эта строка и как она запрашивает секунды?
    *second = bcdToDec(I2CRead(1) & 0x7f);
     
  2. rkit

    rkit Гуру

    Что конкретно не понятно?
     
  3. Unikolai

    Unikolai Гик

    *second -переменная
    bcdToDec ф-я, преобразующая двоичную в десятичную системц счмсл
    "& 0x7f" вот это, как я понимаю маска, так?
    не понятно как вот это "I2CRead(1)" обращается к регистру секунд часов
    где же обращенеи к регистру секунд, ведь у 3231 ээтот регистр имеет адрес 00H
     
  4. rkit

    rkit Гуру

    Часы просто отправляют всю информацию по запросу, I2CRead читает один байт из потока.
     
  5. Unikolai

    Unikolai Гик

    То есть сами часы запрограммированы так, что если к ним кто-то обращается, они сразу начинают передавать время, начиная с секунд? Или как? Как мне прочитать у часов чисто часы, например? Не запрашивая предварительно секунды и минуты? Можно обратится напрямую к регистру часов?
     
  6. rkit

    rkit Гуру

    Можно. В даташите прописано всё. В режиме записи первый байт устанавливает указатель. Потом переключаемся в режим чтения, и чтение будет с этого указателя.
     
  7. rkit

    rkit Гуру

    Только смысла в этом никакого. Прочитать лишний байт будет быстрее. Да и в любом случае, микрооптимизация.
    Это я не прав, указатель всегда писать надо.
     
    Последнее редактирование: 25 ноя 2016
  8. rkit

    rkit Гуру

    Код (C++):
    I2CStart();
    I2CWrite((DS3231_I2C_ADDRESS << 1));
    I2CWrite(0);
    I2CStop ();
    Ну собственно вот тут указатель устанавливается в 0 перед чтением.
     
  9. Unikolai

    Unikolai Гик

    вы вообще спите?)
     
  10. rkit

    rkit Гуру

    Иногда. Сейчас болею, спится плохо.
     
  11. Unikolai

    Unikolai Гик

    искренне сочувствую, тоже болею, но на работе завалик)
    в даташитах я пока не особо рублю, а как будет выглдеть запрос чисто к регистру секунд, мне просто нужно как-то в этом разобраться)
     
  12. rkit

    rkit Гуру

    Секунды в самом начале. Сразу после прочтения их вызываем stop и всё остальное не читаем.
     
  13. Unikolai

    Unikolai Гик

    ну с секундми то понятно, а дни, к примеру? как будет выглядеть обращение конкретно по адресу регистра дней?
     
  14. rkit

    rkit Гуру

    I2CWrite(0);
    пишем вместо нуля 4, читаем дни так же как в примере, и сразу стоп.
     
  15. Unikolai

    Unikolai Гик

    я наверное чего-то не понимаю, но нам ведь нужно читать
    и ф-я реад может принимать на вход только ноль или единицу
     
  16. rkit

    rkit Гуру

     
  17. Unikolai

    Unikolai Гик

    как-то так?
     
    Последнее редактирование: 25 ноя 2016
  18. Unikolai

    Unikolai Гик

    Код (C++):
    boolean I2CWrite(byte b)//принимает биты с 0-7
    {
      byte i = 1 << 7;//не ясно что делаеть, ведь вроде как "<<" это смещение ведь
      boolean ack = 0;//изначально аск на нуле, то есть чтение не будет продолжаться?
      while (i)//пока что?
      {
      //I2CDelay();
      if (b & i) SDA_Hi(); else SDA_Lo(); опять таки, битовый оператор, что он делает с двумя байтами я понимаю, но как это может быть условием, я не понимаю, да и вообще, транная запись, разве не так должно быть if (b & i) {SDA_Hi();}(n/t/ фигурные скобки)
      I2CDelay();//это потом
      SCL_Hi();//просто устанавливаем пины low/high
      I2CDelay();//как понимаю эти паузы делаются для того, чтобы как раз таки получить вот
    эти вот перепады, чтобы при высоком sda и низком или высокм scl получать 1 или 0
      SCL_Lo();//просто устанавливаем пины low/high
     
      i >>= 1;//вообще не ясно
      }
      SDA_Hi();//просто устанавливаем пины low/high
      I2CDelay();
      SCL_Hi();//просто устанавливаем пины low/high
      // while(!SCL_In());
     
      if ( SDA_In() == 0 ) ack = 1;
      I2CDelay();
      SCL_Lo();//просто устанавливаем пины low/high
      SDA_Hi();//просто устанавливаем пины low/high
      return ack;//возвращаем правду или ложбь
    }
     
    Последнее редактирование: 25 ноя 2016
  19. rkit

    rkit Гуру

    Нет. Это мы устанавливаем в часах внутренний указатель на регистр, с которого начнется следующая операция.
    1 есть 1 в любой системе счисления.
    Системы счисления не переводятся. В компьютере всегда двоичная. Эта функция делает что-то другое, но что именно не знаю, да и не надо это знать. Если указываем 1, то отправляется подтверждение приема.
     
  20. Unikolai

    Unikolai Гик

    но регистров то у нас много, а I2CWrite()принимает числа от 0 до 7
    а зачем делать такую прибавку7