DS1307 ไม่จำค่าครับ

  • 11 Replies
  • 3445 Views
*

Offline top

  • **
  • 47
    • View Profile
DS1307 ไม่จำค่าครับ
« on: September 30, 2013, 12:41:44 pm »
สวัสดีครับ ชาว Electoday ทุกท่าน :D
   
  ตอนนี้ DS1307 ไม่สามารถจำค่าที่บันทึกไว้ได้ครับ เมื่อเราปิดเครื่องแล้วเปิดใหม่ค่าที่บันทึกไว้ก่อนจะไม่จำครับ =>เช่น  วัน,วันที่,เดือน,ปี

แต่ ชั้วโมง,นาที่,วินาที สามารถบันทึกและทำงานได้ตามปกติดีครับ

อยากให้ผู้รู้ชี้แนะด้วยครับ ขอขอบคุณมากครับ :-\

Code: [Select]
// main
//#include <18F452.h>

#include <16F877a.h>

#fuses  HS,NOLVP,NOWDT,NOPROTECT
#use   delay(clock=20000000)
//#use I2C(master,sda=pin_c4,scl=pin_c3)

#define Mode PIN_b0  //11
#define UP   PIN_b1  //14  74HC595
#define Down PIN_b2  //12
 
#include <ds1307.c>
#include <lcd.c>

int1 Set,ModeId,UpId,NextId,Blink,DownId;
int1 mov;
int8 rd,y,Mt,Dy,Dt,h,m,s,Next,b;
//int8 DigitId;
int16 mm,DL;

//int1 DemoId,delayId;
//int8 Dat0,Dat1,Dat2,Dat3,Dat4,DigitId,i,DotId;
//int8
//int8 Sec,Min,Sec0,Min0,Hour0,Sec1,Min1,Hour1;
//const char *M[]={"xxx","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
const char DayStr[8][4]={"xxx","Sun","Mon","Tue","Wen","The","Fri","Sat"};


void ShiftClock(void);
void SerialDataOut(int16 DataSend);
void LatchClock(void);
void save (void);


void save (void)
{
 
  ds1307_set_date_time(dy,Mt,y,dt,h,m,s);
}

#zero_ram
void main(void)
{
  BYTE sec;
  BYTE min;
  BYTE hrs;
  BYTE day;
  BYTE month;
  BYTE yr;
  BYTE dow;
  set_tris_b(0x0f);
  set_tris_d(0x00);
  ds1307_init();
 
  // Set date for -> 15 June 2005 Tuesday
  // Set time for -> 15:20:55
//  ds1307_set_date_time(10,9,13,3,hrs,min,sec);
  lcd_init();
   output_high(PIN_D0);
   output_low (PIN_D2);
  while(true)
  {
  //  delay_ms(100);
   
    switch(rd)
    {
      case 0:
      rd=1;
      ds1307_get_date(day,month,yr,dow);
      break;
      case 1:
      rd=0;
      ds1307_get_time(hrs,min,sec);
      break;
    }
    // segment ();
    // Sec  = I2C_Read_RTC (Write_Clock ,0x00,Read_Clock);

  // Hour = I2C_Read_RTC (Write_Clock ,0x02,Read_Clock);
         //  Hour0=Hour&0x0f; //0x59  9
          // Hour1=(Hour&0xf0)>>4; //5
          // Hour=Hour1*10+Hour0;
    if(input(Mode)==0&&ModeId==0)
    {
       mm++;                                 
      if(mm==100)                       
      {                                       
         Set=1;
         DL=0;
      }
       if(NextId==0)
        {
        Blink=0;
         NextId=1;
         Next++;
         if(Next>7)
         {
           Next=1;
         }
      }
       if(mm>=500)                                               
        { 
        if(input(Down)==0)
        {
           lcd_gotoxy(11,2);
           printf(lcd_putc,"Save ");
            delay_ms(500);
           save(); 
           Set=0;
           ModeId=1;
           Next=0;
        }else if(input(Down)==1)
          {
           Set=0;
           ModeId=1;
           Next=0;
          }
        }
     
    }else if(input(Mode)==1)
       {
         ModeId=0;
         mm=0;
         NextId=0;
       }
     if(!Set)
     {
       lcd_gotoxy(0,1);
       printf(lcd_putc,"%02d\/%02d\/%02d > %s",day,month,yr,DayStr[dow]);
       lcd_gotoxy(0,2);
       printf(lcd_putc,"\%02d:\%02d:\%02d        ", hrs,min,sec);
       mov=0;
     }else
        {
          if(++DL>10000)
          {
            Set=0;
            Next=0;
            DL=0;
          }
         if(mov==0)
         {
           dy=day;
           mt=month;
           y=yr;
           dt=dow;
           h=hrs;
           m=min;
           s=sec;
           mov=1;
         }
         
         if(++b>220)
         {
         b=0;
         Blink=~Blink;
         }
         
         switch(Next)
         {
           case 1://sec
          lcd_gotoxy(0,1);//"                "
          printf(lcd_putc,"%02d\/%02d\/%02d > %s",dy,month,yr,DayStr[dt]);
          lcd_gotoxy(0,2);
           if(Blink)printf(lcd_putc,"\%02d:\%02d:\%02d       ", h,m,s);
           else printf(lcd_putc,"\%02d:\%02d:          ", h,m,);
              if(input(UP)==0&&UpId==0)
          {
            UpId=1;
            if(++s>59)
            {
              s=0;
            }
          }else if(input(UP)==1)
                {
                  UpId=0;
                }
             if(input(Down)==0&&DownId==0&&input(Mode)==1)
             {
               DownId=1;
                if(--s<=0)
               {
                 s=59;
               }
             }else if(input(Down)==1)
                   {
                     DownId=0;
                   }
           break;
           
           case 2://Min
           // lcd_gotoxy(0,1);//"                "
         // printf(lcd_putc,"     Set Min     ");
           lcd_gotoxy(0,2);
           if(Blink)printf(lcd_putc,"\%02d:\%02d:\%02d      ", h,m,s);
           else printf(lcd_putc,"\%02d:  :\%02d       ",h,s);
              if(input(UP)==0&&UpId==0)
          {
            UpId=1;
            if(++m>59)
            {
              m=0;
            }
            DL=0;
          }else if(input(UP)==1)
                {
                  UpId=0;
                }
                   if(input(Down)==0&&DownId==0&&input(Mode)==1)
             {
               DownId=1;
                if(--m<=0)
               {
                 m=59;
               }
               DL=0;
             }else if(input(Down)==1)
                   {
                     DownId=0;
                   }
           break;
           
           case 3://Hr
//!            lcd_gotoxy(0,1);//"                "
//!          printf(lcd_putc,"     Set Horn     ");
           lcd_gotoxy(0,2);
         //  printf(lcd_putc," \%02d:\%02d:\%02d", h,m,s);
           if(Blink)printf(lcd_putc,"\%02d:\%02d:\%02d       ", h,m,s);
           else printf(lcd_putc,"  :\%02d:\%02d        ", m,s);
              if(input(UP)==0&&UpId==0)
          {
            UpId=1;
            if(++h>23)
            {
              h=0;
            }
            DL=0;
          }else if(input(UP)==1)
                {
                  UpId=0;
                }
              if(input(Down)==0&&DownId==0&&input(Mode)==1)
             {
               DownId=1;
                if(--h<=0)
               {
                 h=23;
               }
               DL=0;
             }else if(input(Down)==1)
                   {
                     DownId=0;
                   }
           break;
           
           case 4://Day
           lcd_gotoxy(0,1);
           if(Blink) printf(lcd_putc,"%02d\/%02d\/%02d > %s ",dy,mt,yr,DayStr[dt]);
           else printf(lcd_putc,"%02d\/%02d\/%02d >    ",dy,mt,yr);
            lcd_gotoxy(0,2);
            printf(lcd_putc,"\%02d:\%02d:\%02d       ", h,m,s);
           //else printf(lcd_putc,"   :\%02d:\%02d        ", m,s);
              if(input(UP)==0&&UpId==0)
          {
            UpId=1;
            if(++Dt>7)
            {
              Dt=1;
            }
            DL=0;
          }else if(input(UP)==1)
                {
                  UpId=0;
                }
                 if(input(Down)==0&&DownId==0&&input(Mode)==1)
             {
               DownId=1;
                if(--Dt<=0)
               {
                 Dt=7;
               }
               DL=0;
             }else if(input(Down)==1)
                   {
                     DownId=0;
                   }
           break;
           
           case 5://Year
           lcd_gotoxy(0,1);
           if(Blink) printf(lcd_putc,"%02d\/%02d\/%02d > %s ",dy,mt,y,DayStr[dt]);
           else printf(lcd_putc,"%02d\/%02d\/   > %s   ",dy,mt,DayStr[Dt]);
              if(input(UP)==0&&UpId==0)
          {
            UpId=1;
            if(++y>99)
            {
              y=0;
            }
            DL=0;
          }else if(input(UP)==1)
                {
                  UpId=0;
                }
                 if(input(Down)==0&&DownId==0&&input(Mode)==1)
             {
               DownId=1;
                if(--y<=0)
               {
                 y=99;
               }
               DL=0;
             }else if(input(Down)==1)
                   {
                     DownId=0;
                   }
           break;
           case 6://Manth
            lcd_gotoxy(0,1);
           if(Blink) printf(lcd_putc,"%02d\/%02d\/%02d > %s ",dy,mt,y,DayStr[dt]);
           else printf(lcd_putc,"%02d\/  \/%02d > %s ",dy,y,DayStr[Dt]);
              if(input(UP)==0&&UpId==0)
          {
            UpId=1;
            if(++mt>12)
            {
              mt=1;
            }
            DL=0;
          }else if(input(UP)==1)
                {
                  UpId=0;
                }
                     if(input(Down)==0&&DownId==0&&input(Mode)==1)
             {
               DownId=1;
                if(--mt<1)
               {
                 mt=12;
               }
               DL=0;
             }else if(input(Down)==1)
                   {
                     DownId=0;
                   }
           break;
           case 7://Date
            lcd_gotoxy(0,1);
           if(Blink) printf(lcd_putc,"%02d\/%02d\/%02d > %s ",dy,mt,y,DayStr[dt]);
           else printf(lcd_putc,"  \/%02d\/%02d > %s ",mt,y,DayStr[Dt]);
              if(input(UP)==0&&UpId==0)
          {
            UpId=1;
            if(++dy>31)
            {
              dy=1;
            }
            DL=0;
          }else if(input(UP)==1)
                {
                  UpId=0;
                }
                         if(input(Down)==0&&DownId==0&&input(Mode)==1)
             {
               DownId=1;
                if(--dy<1)
               {
                 dy=31;
               }
               DL=0;
             }else if(input(Down)==1)
                   {
                     DownId=0;
                   }
           break;
         
         }
         
         
        }
  }
}

//......................................................DS1307.c

Code: [Select]
  ////////////////////////////////////////////////////////////////////////////////
///                               DS1307.C                                   ///
///                     Driver for Real Time Clock                           ///
///                                                                          ///
/// ds1307_init() - Enable oscillator without clearing the seconds register -///
///                 used when PIC loses power and DS1307 run from 3V BAT     ///
///               - Disable squarewave output                                ///
///                                                                          ///
/// ds1307_set_date_time(day,mth,year,dow,hour,min,sec)  Set the date/time   ///
///                                                                          ///
/// ds1307_get_date(day,mth,year,dow)               Get the date             ///
///                                                                          ///
/// ds1307_get_time(hr,min,sec)                     Get the time             ///
///                                                                          ///
////////////////////////////////////////////////////////////////////////////////

#define RTC_SDA  PIN_C0
#define RTC_SCL  PIN_C1

#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)

BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);

void ds1307_init(void)
{
   BYTE seconds = 0;

   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_start();
   i2c_write(0xD1);      // RD from RTC
   seconds = bcd2bin(i2c_read(0)); // Read current "seconds" in DS1307
   i2c_stop();
   seconds &= 0x7F;

   delay_us(3);

   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_write(bin2bcd(seconds));     // Start oscillator with current "seconds value
   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x07);      // Control Register
   i2c_write(0x00);     // Disable squarewave output pin //0x80
   i2c_stop();

}
#define BIT_VAL(x) (1 << x)
void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec,)
{
  sec &= 0x7F;
  hr &= 0x3F;
//  ap &= 0x3F;

  i2c_start();
  i2c_write(0xD0);              // I2C write address
  i2c_write(0x00);              // Start at REG 0 - Seconds
  i2c_write(bin2bcd(sec));      // REG 0
  i2c_write(bin2bcd(min));      // REG 1
  i2c_write(bin2bcd(hr));      // REG 1 Final
  i2c_write(bin2bcd(hr) |= BIT_VAL(6));         // REG 2
  i2c_write(bin2bcd(dow));      // REG 3
  i2c_write(bin2bcd(day));      // REG 4
  i2c_write(bin2bcd(mth));      // REG 5
  i2c_write(bin2bcd(year));     // REG 6
  i2c_write(0x80);              // REG 7 - Disable squarewave output pin
  i2c_stop();


void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x03);            // Start at REG 3 - Day of week
  i2c_start();
  i2c_write(0xD1);
  dow  = bcd2bin(i2c_read() & 0x7f);   // REG 3
  day  = bcd2bin(i2c_read() & 0x3f);   // REG 4
  mth  = bcd2bin(i2c_read() & 0x1f);   // REG 5
  year = bcd2bin(i2c_read(0));            // REG 6
  i2c_stop();
}

void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);            // Start at REG 0 - Seconds
  i2c_start();
  i2c_write(0xD1);
  sec = bcd2bin(i2c_read() & 0x7f);
  min = bcd2bin(i2c_read() & 0x7f);
  hr  = bcd2bin(i2c_read(0) & 0x3f);
  i2c_stop();

}

BYTE bin2bcd(BYTE binary_value)
{
  BYTE temp;
  BYTE retval;

  temp = binary_value;
  retval = 0;

  while(true)
  {
    // Get the tens digit by doing multiple subtraction
    // of 10 from the binary value.
    if(temp >= 10)
    {
      temp -= 10;
      retval += 0x10;
    }
    else // Get the ones digit by adding the remainder.
    {
      retval += temp;
      break;
    }
  }

  return(retval);
}


// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
  BYTE temp;

  temp = bcd_value;
  // Shifting upper digit right by 1 is same as multiplying by 8.
  temp >>= 1;
  // Isolate the bits for the upper digit.
  temp &= 0x78;

  // Now return: (Tens * 8) + (Tens * 2) + Ones

  return(temp + (temp >> 2) + (bcd_value & 0x0f));
}

*

Offline top

  • **
  • 47
    • View Profile
Re: DS1307 ไม่จำค่าครับ
« Reply #1 on: September 30, 2013, 01:17:46 pm »
เพิ่มเติมครับ




*

Offline skytec

  • *****
  • 1030
  • "จินตนาการสำคัญกว่าความรู้ " --อัลเบิรต ไอสไตน์
    • View Profile
    • R&D , Technical Consultants , Sensor Developer  , Engineering consultants
Re: DS1307 ไม่จำค่าครับ
« Reply #2 on: September 30, 2013, 05:41:50 pm »
หากเป็นผมจะทำแบบนี้
1. หา DS1307 ตัวใหม่แล้วลองดูว่ามันเป็นเหมือนตัวแรกไหม
2. หากเป็นค่อยดูว่าเป็นที่โปรแกรมหรือที่ การต่อวงจร ครับ

หมายเหตุ  :  เนื่องจากเราไม่มีบอร์ดอ้างอิง ดังนั้น ลองทำดู ตามข้างบนครับ
"จินตนาการสำคัญกว่าความรู้ ความรู้มีข้อจำกัด จิตนาการไร้ขอบเขต " --อัลเบิร์ต ไอสไตน์

*

Offline top

  • **
  • 47
    • View Profile
Re: DS1307 ไม่จำค่าครับ
« Reply #3 on: October 01, 2013, 07:42:37 am »
ใช่แล้วครับ เมื่อวานไปหาซื้อมา 4 ตัวใช้ได้ 1 ตัวเซงเป็ดงานนี้ :-\

ยังไงต้องขอขอบคุณ sketec ด้วยครับที่ให้คำแนะนำ

สรุปงานนี้ Module RTC มีปัญหาครับ :)




*

Offline skytec

  • *****
  • 1030
  • "จินตนาการสำคัญกว่าความรู้ " --อัลเบิรต ไอสไตน์
    • View Profile
    • R&D , Technical Consultants , Sensor Developer  , Engineering consultants
Re: DS1307 ไม่จำค่าครับ
« Reply #4 on: October 01, 2013, 08:31:22 am »
ดีใจด้วยครับที่แก้ปัญหาได้ตรงจุด  :)
"จินตนาการสำคัญกว่าความรู้ ความรู้มีข้อจำกัด จิตนาการไร้ขอบเขต " --อัลเบิร์ต ไอสไตน์

*

Offline jx

  • **
  • 74
  • Wizard!
    • View Profile
    • Wizard!
Re: DS1307 ไม่จำค่าครับ
« Reply #5 on: October 02, 2013, 07:36:35 pm »
ไม่รู้ว่าที่ vcc ของ ds1307 กับ vbat ของแบตฯแบคอัพมี coupling C 0.1uF ไหมครับ ถ้าไม่มีก็ลองใส่ดู
อาจเกิดจาก spike ของ power supply ตอน turn on/off ครับ

เคยเจอแต่ไม่บ่อยครับ ลองดูไม่เสียหาย

*

Offline pa_ul

  • ***
  • 247
    • View Profile
Re: DS1307 ไม่จำค่าครับ
« Reply #6 on: October 03, 2013, 12:23:19 am »
ถ้าซื้อ 4 ตัว ใช้ได้แค่ตัวเดียว ไม่ใช่ปัญหาไอซีแล้ว คุณภาพไอซีค่าย MAXIM / TI ดีกว่านี้มาก

*

Offline top

  • **
  • 47
    • View Profile
Re: DS1307 ไม่จำค่าครับ
« Reply #7 on: October 03, 2013, 04:09:08 pm »
มันมีปัญหาคนละอาการครับ

มีบางตัวบันทึกได้ แต่พอปิดไฟแล้วเปิด นาฬิกาจะนับต่อจากค่าสุดท้ายที่ก่อนไฟดับ

แล้วแก้ยังไงดีครับ
 
ขอคำแนะนำเหน่อยครับ