Electoday 2025

ไมโครคอนโทรลเลอร์ => Microchip PIC => Topic started by: top on September 30, 2013, 12:41:44 PM

Title: DS1307 ไม่จำค่าครับ
Post by: top on September 30, 2013, 12:41:44 PM
สวัสดีครับ ชาว Electoday ทุกท่าน :D
   
  ตอนนี้ DS1307 ไม่สามารถจำค่าที่บันทึกไว้ได้ครับ เมื่อเราปิดเครื่องแล้วเปิดใหม่ค่าที่บันทึกไว้ก่อนจะไม่จำครับ =>เช่น  วัน,วันที่,เดือน,ปี

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

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


// 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


  ////////////////////////////////////////////////////////////////////////////////
///                               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));
}
Title: Re: DS1307 ไม่จำค่าครับ
Post by: top on September 30, 2013, 01:17:46 PM
เพิ่มเติมครับ


(http://s24.postimg.org/97bkb2cgx/RTC.jpg) (http://postimg.org/image/97bkb2cgx/)
Title: Re: DS1307 ไม่จำค่าครับ
Post by: skytec on September 30, 2013, 05:41:50 PM
หากเป็นผมจะทำแบบนี้
1. หา DS1307 ตัวใหม่แล้วลองดูว่ามันเป็นเหมือนตัวแรกไหม
2. หากเป็นค่อยดูว่าเป็นที่โปรแกรมหรือที่ การต่อวงจร ครับ

หมายเหตุ  :  เนื่องจากเราไม่มีบอร์ดอ้างอิง ดังนั้น ลองทำดู ตามข้างบนครับ
Title: Re: DS1307 ไม่จำค่าครับ
Post by: top on October 01, 2013, 07:42:37 AM
ใช่แล้วครับ เมื่อวานไปหาซื้อมา 4 ตัวใช้ได้ 1 ตัวเซงเป็ดงานนี้ :-\

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

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



Title: Re: DS1307 ไม่จำค่าครับ
Post by: skytec on October 01, 2013, 08:31:22 AM
ดีใจด้วยครับที่แก้ปัญหาได้ตรงจุด  :)
Title: Re: DS1307 ไม่จำค่าครับ
Post by: jx on October 02, 2013, 07:36:35 PM
ไม่รู้ว่าที่ vcc ของ ds1307 กับ vbat ของแบตฯแบคอัพมี coupling C 0.1uF ไหมครับ ถ้าไม่มีก็ลองใส่ดู
อาจเกิดจาก spike ของ power supply ตอน turn on/off ครับ

เคยเจอแต่ไม่บ่อยครับ ลองดูไม่เสียหาย
Title: Re: DS1307 ไม่จำค่าครับ
Post by: pa_ul on October 03, 2013, 12:23:19 AM
ถ้าซื้อ 4 ตัว ใช้ได้แค่ตัวเดียว ไม่ใช่ปัญหาไอซีแล้ว คุณภาพไอซีค่าย MAXIM / TI ดีกว่านี้มาก
Title: Re: DS1307 ไม่จำค่าครับ
Post by: top on October 03, 2013, 04:09:08 PM
มันมีปัญหาคนละอาการครับ

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

แล้วแก้ยังไงดีครับ

ขอคำแนะนำเหน่อยครับ
Title: Re: DS1307 ไม่จำค่าครับ
Post by: F on October 03, 2013, 04:46:08 PM
ปัญหานี้เคยเจอครับ  จำไม่ได้ว่าสาเหตุมาจากอะไรกันแน่ระหว่าง
- ไม่ได้ต่อ batt. หรือ
- ใส่ batt กลับขั้วครับ
Title: Re: DS1307 ไม่จำค่าครับ
Post by: top on October 07, 2013, 05:39:08 AM
ตอนนี้เจอปัญหาอืนอีกแล้วครับ :-\

    ช่วงที่จ่ายไฟเข้าวงจร บางครั้งเปิดครั้งเดียวก็ติดแล้ว สามารถแสดงผลได้

แต่บางครั้งต้องเปิดปิดหลายๆครั้ง ถึงจะสามารถแสดงผลได้

( ช่วงที่แสดงผลไม่ได้ หน้าแสดงค่า ADC เป็น 0.00 , RTC  แสดงเป็นภาษาต่างดาวไปเลยครับ )

ตอนนี้ได้เพิ่มตัว C  2200uF  และ C  0.1uF แล้วครับแต่ก็ไม่หายสักที่

ขอคำแนะนำด้วยครับ  ขอบคุณมากครับ :-[
Title: Re: DS1307 ไม่จำค่าครับ
Post by: avr_lover on October 07, 2013, 08:45:37 AM
Quote( ช่วงที่แสดงผลไม่ได้ หน้าแสดงค่า ADC เป็น 0.00 , RTC  แสดงเป็นภาษาต่างดาวไปเลยครับ )
อันนี้น่าจะเกิดจาก LCD Error หรือปล่าว ไม่น่าจะเกิดจาก RTC นะครับ ลองใส่ Loop ให้ LCD Initial ทุกๆ5วินาทีดู(คร่าวๆ๗แล้วดูตอนมันเพี้ยนว่า สามารถกลับมาปรกติได้ไหม ถ้าได้ แสดงว่ามีปัญหาเกียวกับ LCD โดนกวน ในวงจรประกอบด้วยส่วนอื่นไหมครับ Relay, Motor เผื่อจะจินตนาการได้มากขึ้น :)
Title: Re: DS1307 ไม่จำค่าครับ
Post by: top on October 07, 2013, 05:09:27 PM
ตอนนี้ Error หายแล้วครับ

โดยกำหนดค่าเริ่มต้น ขอคำสัง switch(ADC),switch(RTC) ใว้ใน main ด้วย

โง่ตั้งนาน ;D

ขอขอบคุณ k. avr_lover มากครับ ที่ให้ผมคิดอะไรบางอย่างได้