Сопряжение 5V Arduino с 3.3V часами DS1302

Тема в разделе "Глядите, что я сделал", создана пользователем Unixon, 22 апр 2012.

  1. а почему нельзя воспользоватся для двунаправленного канала обмена вот такой схемой?
    [​IMG]
     
  2. Unixon

    Unixon Оракул Модератор

    Можно и такой, только нужно удостовериться, что для логической "1" в верхнем плече падение напряжения будет не меньше необходимого, а в нижнем - не больше необходимого. Для уровней 5V и 3.3V в верхнем плече должны стоять диоды с максимальным Vf от 0.7V и больше, а в нижнем один диод Шоттки с минимальным Vf порядка 0.25-0.3V. Трансляция с 5V на 3.3V будет надежной, а вот обратно нужно смотреть конкретную технологию микросхем по обе стороны, уровни немного отличаются, хотя, скорее всего, никаких проблем не должно быть.
     
  3. Warlock

    Warlock Нуб

    Подскажите, как вывести время с DS1302 на LCD 16х2 ??? Не могу разобраться с библиотекой на DS1302. Добился только вывода дня недели.
     
  4. Unixon

    Unixon Оракул Модератор

    Я вот таким скетчем пользовался:
    Код (Text):
    #include <LiquidCrystal.h>
    #include <DS1302.h>
     
    const int pin_rtc_clk = 31;
    const int pin_rtc_io = 33;
    const int pin_rtc_ce = 35;
     
    const int pin_btn_1 = 41;
    const int pin_btn_2 = 43;
    const int pin_btn_3 = 45;
    const int pin_btn_4 = 47;
    const int pin_btn_5 = 49;
     
    const int pin_btn_left = pin_btn_1;
    const int pin_btn_minus = pin_btn_2;
    const int pin_btn_plus = pin_btn_3;
    const int pin_btn_right = pin_btn_4;
    const int pin_btn_clkset = pin_btn_5;
     
    const int pin_v_pwr = A14;
    const int pin_v_bat = A15;
     
    boolean mode_show = false;
    boolean mode_edit = false;
    int item_index = 0;
    int item_value = 0;
    int item_limit = 0;
     
    // LCD // RS, E, DB5, DB6, DB7, DB8
    LiquidCrystal lcd(22, 24, 26, 28, 30, 32);
    // DS1302 // CE, IO, SCLK
    DS1302 rtc(pin_rtc_ce, pin_rtc_io, pin_rtc_clk);
     
    boolean is_powered()
    {
      float v_pwr = analogRead(pin_v_pwr)*5.0/1023.0;
      float v_bat = analogRead(pin_v_bat)*5.0/1023.0;
      return ((v_pwr >= 2.0) || (v_bat >= 2.0));
    }
     
    void read_item(Time& t)
    {
    switch(item_index)
    {
      case 0: { item_value = t.hr; item_limit=23; break; }
      case 1: { item_value = t.min; item_limit=59; break; }
      case 2: { item_value = t.sec; item_limit=59; break; }
      case 3: { item_value = t.date; item_limit=31; break; }
      case 4: { item_value = t.mon; item_limit=12; break; }
      case 5: { item_value = t.yr; item_limit=2100;  break; }
    }
    }
     
    void write_item(Time& t)
    {
    switch(item_index)
    {
      case 0: { t.hr = item_value; break; }
      case 1: { t.min = item_value; break; }
      case 2: { t.sec = item_value; break; }
      case 3: { t.date = item_value; break; }
      case 4: { t.mon = item_value; break; }
      case 5: { t.yr = item_value;  break; }
    }
    rtc.time(t);
    }
     
    void setup()
    {
    Serial.begin(9600);
    // LCD width, height
    lcd.begin(20, 4);
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("Initializing...");
    while(!is_powered())
    {
      lcd.setCursor(0,3);
      lcd.print("NO POWER");
      delay(1000);
    }
      /* Initialize a new chip by turning off write protection and clearing the
        clock halt flag. These methods needn't always be called. See the DS1302
        datasheet for details. */
      //rtc.bus_delay = 4;
      rtc.write_protect(false);
      rtc.halt(false);
     
      /* Make a new time object to set the date and time */
      /*  Tuesday, May 19, 2009 at 21:16:37.            */
      Time t(2012, 1, 1, 0, 0, 0, 0);
      /* Set the time and date on the chip */
      rtc.time(t);
      read_item(t);
    delay(1000);
    //
    pinMode(pin_rtc_clk,OUTPUT);
    pinMode(pin_rtc_io,OUTPUT);
    pinMode(pin_rtc_ce,OUTPUT);
    digitalWrite(pin_rtc_clk,LOW);
    digitalWrite(pin_rtc_io,LOW);
    digitalWrite(pin_rtc_ce,LOW);
    //  
    pinMode(pin_btn_1,INPUT);
    pinMode(pin_btn_2,INPUT);
    pinMode(pin_btn_3,INPUT);
    pinMode(pin_btn_4,INPUT);
    pinMode(pin_btn_5,INPUT);
    }
     
    void loop()
    {
    while(!is_powered())
    {
      lcd.setCursor(0,3);
      lcd.print("NO POWER");
      delay(1000);
    }
    Time t = rtc.time();
    lcd.clear();
    lcd.setCursor(0,0);
    lcd.print("DS1302 RTC");
    lcd.setCursor(0,1);
    lcd.print(t.hr);
    lcd.print(":");
    lcd.print(t.min);
    lcd.print(":");
    lcd.print(t.sec);
    lcd.print(" ");
    lcd.print(t.date);
    lcd.print(":");
    lcd.print(t.mon);
    lcd.print(":");
    lcd.print(t.yr);
    lcd.print(" ");
    //
    Serial.print(t.hr);
    Serial.print(":");
    Serial.print(t.min);
    Serial.print(":");
    Serial.print(t.sec);
    Serial.print(" ");
    Serial.print(t.date);
    Serial.print(":");
    Serial.print(t.mon);
    Serial.print(":");
    Serial.println(t.yr);
    //
    if (digitalRead(pin_btn_clkset)==HIGH)
    {
      if (mode_edit)
      {
      write_item(t);
      rtc.time(t);
      rtc.halt(false);
      mode_edit = false;
      }
      else
      {
      mode_edit = true;
      rtc.halt(true);
      read_item(t);
      }
      while (digitalRead(pin_btn_clkset)==HIGH) {}
    }
    if (mode_edit)
    {
      lcd.setCursor(0,3);
      lcd.print("SET ");
      switch(item_index)
      {
      case 0: { lcd.print("HOUR: "); lcd.print(item_value); break; }
      case 1: { lcd.print("MINUTE: "); lcd.print(item_value); break; }
      case 2: { lcd.print("SECOND: "); lcd.print(item_value); break; }
      case 3: { lcd.print("DATE: "); lcd.print(item_value); break; }
      case 4: { lcd.print("MONTH: "); lcd.print(item_value); break; }
      case 5: { lcd.print("YEAR: "); lcd.print(item_value); break; }
      }
      if (digitalRead(pin_btn_left)==HIGH)
      {
      if (item_index>0)
      {
        write_item(t);
        item_index--;
        read_item(t);
      }
      while (digitalRead(pin_btn_left)==HIGH) {}
      }
    }
    if (digitalRead(pin_btn_right)==HIGH)
    {
      if (item_index<5)
      {
      write_item(t);
      item_index++;
      read_item(t);
      }
      while (digitalRead(pin_btn_right)==HIGH) {}
    }
    if (digitalRead(pin_btn_minus)==HIGH)
    {
      if (item_value>0)
      {
      item_value--;
      write_item(t);
      }
      while (digitalRead(pin_btn_minus)==HIGH) {}
    }
    if (digitalRead(pin_btn_plus)==HIGH)
    {
      if (item_value<item_limit)
      {
      item_value++;
      write_item(t);
      }
      while (digitalRead(pin_btn_plus)==HIGH) {}
    }
    //
    if (!mode_edit)
    {
      float v_pwr = analogRead(pin_v_pwr)*5.0/1023.0;
      float v_bat = analogRead(pin_v_bat)*5.0/1023.0;
      lcd.setCursor(0,3);
      lcd.print("Vpwr=");
      lcd.print(v_pwr);
      lcd.print(" Vbat=");
      lcd.print(v_bat);
    }
    //
    delay(250);
    }
     
  5. Warlock

    Warlock Нуб

    Спасибо, часики затикали :)
     
  6. red

    red Нуб

    Спасибо "Unixon" за мысли !!!
    столкнулся с проблемой когда при переключении с резервного питания на основное ds1302 коротила VCC2 на землю...
    переводить на 3.3v не стал, а реализовал ее питание с порта atmegи - таймер потребляет немного и порт справляется с нагрузкой.
    -изначально пин питания и дата-пины выставлены в 0.
    -перед инициализацией RTC, пин питания в 1 и через небольшую паузу восстанавливаем настройки дата-пинов и продолжаем основной код.
    проверка в железе показала отличную работоспособность такого решения !
     
  7. Unixon

    Unixon Оракул Модератор

    Это будет работать, только если вам не нужно, чтобы часики тикали, пока все остальное отключено.
     
  8. red

    red Нуб

    Почему ? к RTC подключена резервная батарея, все сохраняется.
    получается: еcли перед подачей основного питания (при переключении с резервного на основной источник) зашунтировать RST, I/O, SCLK на землю, то переключение происходит без глюков, а если просто подавать питание, то микросхемка превращается в маленький утюг...

    ps: ds1302 покупал у китайцев на ebay
     
  9. Unixon

    Unixon Оракул Модератор

    А, ну с батареей то понятно, я то про запитку от ноги МК.
     
  10. KENG

    KENG Нуб

    Если не сложно, то будьте добры подробнее расскажите, как это все реализовано. Замечательно будет, если с иллюстрацией и куском программного кода. Только начинаю осваивать азы работы с Ардуино, поэтому в аппаратной части еще мало что понимаю. Еще было сказано, что нужно зашунтировать RST, I/O, SCLK на землю - вот об этом тоже чуть детальнее хотелось бы услышать, что да как.