สวัสดีครับ ชาว 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));
}
เพิ่มเติมครับ
(http://s24.postimg.org/97bkb2cgx/RTC.jpg) (http://postimg.org/image/97bkb2cgx/)
หากเป็นผมจะทำแบบนี้
1. หา DS1307 ตัวใหม่แล้วลองดูว่ามันเป็นเหมือนตัวแรกไหม
2. หากเป็นค่อยดูว่าเป็นที่โปรแกรมหรือที่ การต่อวงจร ครับ
หมายเหตุ : เนื่องจากเราไม่มีบอร์ดอ้างอิง ดังนั้น ลองทำดู ตามข้างบนครับ
ใช่แล้วครับ เมื่อวานไปหาซื้อมา 4 ตัวใช้ได้ 1 ตัวเซงเป็ดงานนี้ :-\
ยังไงต้องขอขอบคุณ sketec ด้วยครับที่ให้คำแนะนำ
สรุปงานนี้ Module RTC มีปัญหาครับ :)
ดีใจด้วยครับที่แก้ปัญหาได้ตรงจุด :)
ไม่รู้ว่าที่ vcc ของ ds1307 กับ vbat ของแบตฯแบคอัพมี coupling C 0.1uF ไหมครับ ถ้าไม่มีก็ลองใส่ดู
อาจเกิดจาก spike ของ power supply ตอน turn on/off ครับ
เคยเจอแต่ไม่บ่อยครับ ลองดูไม่เสียหาย
ถ้าซื้อ 4 ตัว ใช้ได้แค่ตัวเดียว ไม่ใช่ปัญหาไอซีแล้ว คุณภาพไอซีค่าย MAXIM / TI ดีกว่านี้มาก
มันมีปัญหาคนละอาการครับ
มีบางตัวบันทึกได้ แต่พอปิดไฟแล้วเปิด นาฬิกาจะนับต่อจากค่าสุดท้ายที่ก่อนไฟดับ
แล้วแก้ยังไงดีครับ
ขอคำแนะนำเหน่อยครับ
ปัญหานี้เคยเจอครับ จำไม่ได้ว่าสาเหตุมาจากอะไรกันแน่ระหว่าง
- ไม่ได้ต่อ batt. หรือ
- ใส่ batt กลับขั้วครับ
ตอนนี้เจอปัญหาอืนอีกแล้วครับ :-\
ช่วงที่จ่ายไฟเข้าวงจร บางครั้งเปิดครั้งเดียวก็ติดแล้ว สามารถแสดงผลได้
แต่บางครั้งต้องเปิดปิดหลายๆครั้ง ถึงจะสามารถแสดงผลได้
( ช่วงที่แสดงผลไม่ได้ หน้าแสดงค่า ADC เป็น 0.00 , RTC แสดงเป็นภาษาต่างดาวไปเลยครับ )
ตอนนี้ได้เพิ่มตัว C 2200uF และ C 0.1uF แล้วครับแต่ก็ไม่หายสักที่
ขอคำแนะนำด้วยครับ ขอบคุณมากครับ :-[
Quote( ช่วงที่แสดงผลไม่ได้ หน้าแสดงค่า ADC เป็น 0.00 , RTC แสดงเป็นภาษาต่างดาวไปเลยครับ )
อันนี้น่าจะเกิดจาก LCD Error หรือปล่าว ไม่น่าจะเกิดจาก RTC นะครับ ลองใส่ Loop ให้ LCD Initial ทุกๆ5วินาทีดู(คร่าวๆ๗แล้วดูตอนมันเพี้ยนว่า สามารถกลับมาปรกติได้ไหม ถ้าได้ แสดงว่ามีปัญหาเกียวกับ LCD โดนกวน ในวงจรประกอบด้วยส่วนอื่นไหมครับ Relay, Motor เผื่อจะจินตนาการได้มากขึ้น :)
ตอนนี้ Error หายแล้วครับ
โดยกำหนดค่าเริ่มต้น ขอคำสัง switch(ADC),switch(RTC) ใว้ใน main ด้วย
โง่ตั้งนาน ;D
ขอขอบคุณ k. avr_lover มากครับ ที่ให้ผมคิดอะไรบางอย่างได้