PDA

View Full Version : Đồng hồ số dùng DS1307


hatuan296
27-01-2007, 09:55 PM
Mình có làm 1 đồng hồ số dùng Pic 18f458 , kết nối DS1307 qua i2c . hiển thị trên lcd . mình đã làm cho chạy , nhưng lại hiển thị không đúng kết quả . anh em nào đã từng làm cái này rồi thì giúp mình nha . Lỗi cụ thể như sau ;

- mình nhập giá trị ban đầu : $00,$00,$00,$07,$1B,$01,$07,$90
' Sec Min Hr Day D M Y Control

giây(sec) : 00
phút(min) : 00
giờ (hr) : 00
thứ (Day) : 7.
ngày (D) : 27
tháng(M) : 1
năm(y):7

lcd hiển thị như sau :

thu 7 27-1-7
0:0:0
h m s

mình nhập vào DS1307 thì ok . đọc ra thì cũng ok luôn . nhưng khi bắt đầu đếm . thì con số s chỉ đếm đến 9 thôi , rồi lại nhảy thành số 16 . ngay cả con m và con h cũng vậy . Khi mình nhẩm tính thì đúng là con s nhảy 60 lần thì con m nhảy 1 lần . nhưng hiển thị thì không đúng . có khi con s lên đến hàng 80 luôn .

Mình nghĩ chắc từ số 9 con DS1307 đã bỏ qua A , B , C , D , E , F để đếm đến 16 . Nhưng tại sao lại như vậy ? làm sao đế cho hiển thị đúng ? Và khi nạp lần đầu cho con Ds , thì mình nên để giá trị là gì ? thập phân hay nhị phân hay hệ 16 ? . khi mình đọc ra là số gì ?
mong bạn nào rành thì giúp mình nha . mình vô cùng cảm ơn .

À, còn 1 điều nữa . mình có cần phải đọc ghi theo thứ tự không ? và nếu có thì mình phải đọc cái gì trước , cái gì sau ?
ghi cái gì trước , cái gì sau ?

vnbtech
27-01-2007, 11:04 PM
Cha`o ban,
Ban co' bao gio nghe noi den chuan BCD chua? (Binary coded decimal). Con IC cua ban dung cai BCD do'. Khi no de^'m tu 09 xong len den 10 roi 11...12..
giong nhu dem so^' binh thuong thoi. Neu doc ra 10 tuc la so^' muo*i, ma ban lai nghi~ la hex, thi luc do' ban se doi ra la 16. la se bi. sai lien.

byte hr,
byte StrHH[3] = {0};

rtc_get_time(hr, min, sec);

g_StrHH[0] = (char) (hr/16 + 0x30);
g_StrHH[1] = (char) (hr%16 + 0x30);

lcd_display_string(StrHH);

ban hay tham khao doan ma tren, hy vong se giup duoc ma.

VNBTECH.

hatuan296
27-01-2007, 11:21 PM
Cha`o ban,
Ban co' bao gio nghe noi den chuan BCD chua? (Binary coded decimal). Con IC cua ban dung cai BCD do'. Khi no de^'m tu 09 xong len den 10 roi 11...12..
giong nhu dem so^' binh thuong thoi. Neu doc ra 10 tuc la so^' muo*i, ma ban lai nghi~ la hex, thi luc do' ban se doi ra la 16. la se bi. sai lien.

byte hr,
byte StrHH[3] = {0};

rtc_get_time(hr, min, sec);

g_StrHH[0] = (char) (hr/16 + 0x30);
g_StrHH[1] = (char) (hr%16 + 0x30);

lcd_display_string(StrHH);

ban hay tham khao doan ma tren, hy vong se giup duoc ma.

VNBTECH.

mình đã nghĩ tới việc đó rồi . khi mình đọc giá trị từ DS , mình gửi tạm vào 1 biến . chuyển biến đó từ số hex sang thập phân ( vì lúc nạp vào mình dùng số hex )sau đó suất biến đó ra lcd dưới dạng số thập phân . còn chuẩn BCD của bạn tức là mã 10101010 đúng không ? nếu con DS chỉ dùng BCD thi tai sao luc mình nạp , mình nạp mã là HEX thi nó vẫn nạp được và vẫn chạy ?

vnbtech
28-01-2007, 10:18 AM
chao ban,
BCD uses 4 binary bits to encode each decimal digit. Vi' du. la: ban muon dua du lieu ngay 27 vao trong con IC, thi ban phai dung 0x27, chung khong phai la 0x1B. 0x1B la sai roi, khong phai la ngay 27 theo chuan BCD dau.

Vi' du ban dung thong tin sau de "initialize" con timer IC:
gia^y : 45 second
Phut : 37 phu't
Gio : 8 gio.
Thi ban phai dung cai data sau day de dua vao : 0x45, 0x37, 0x08

sau khi dua vao, gia su*? 50 giay sau, ba.n doc cai thoi gio tu con IC, luc no' con IC se cho ban data sau:
Giay = 0x35
Phut = 0x38
Gio = 0x08
Neu ban muon hien thi. tren LCD cho du'ng thi ban phai doi ra nhu sau:
char second_digit1, second_digit2;
second_digit2 = (Giay / 0x10) + '0' = (0x35 / 0x10) + 0x30 = 0x33
second_digit1 = (Giay % 0x10) + '0' = (0x35 % 0x10) + 0x30 = 0x35

roi ban co' the display giong nhu display character:
lcd_display_char(second_digit2);
lcd_display_char(second_digit1);

Ban cu lam nhu vay, minh tin chac ban se da.p duoc yeu cau. Neu ban co' thac mac gi, thi cu hoi tiep nhe'.

VNBTECH

hatuan296
28-01-2007, 01:23 PM
Cảm ơn các bạn đã quan tâm . hôm nay mình đã làm được rồi . cái con số mình nhập vào DS không qua trọng . là kiểu dữ liệu gi cũng ok , hex hoặc decimal . nhưng quan trọng là lúc đọc ra . mình phải chuyển số đó sang hex , rồi xuất thẳng ra LCD luôn . bây giờ thì ok rồi . nhưng mình còn chưa biết cái vụ AM và PM . lại còn năm nhuận hay không nhuận để mà biết tự cộng thêm ngày cho tháng 2 . nếu các bạn biết , mình mong các bạn chia sẻ nha .

a, mà lúc mình nạp lần đầu , mình nạp thẳng số hex luôn . vd :
năm : $07
tháng : $01
ngày : $28
giờ : $13
phút : $25
giây : $00
tương ứng khi xuất ra LCD là : 28 - 01 - 07 13:25:00

namqn: đây đâu phải là số hex, nó vẫn là dạng BCD đó chứ. Bạn thử nạp $0F vào ô nhớ đếm năm rồi đọc lại xem sẽ được số nào.

namqn
28-01-2007, 08:44 PM
Cảm ơn các bạn đã quan tâm . hôm nay mình đã làm được rồi . cái con số mình nhập vào DS không qua trọng . là kiểu dữ liệu gi cũng ok , hex hoặc decimal . nhưng quan trọng là lúc đọc ra . mình phải chuyển số đó sang hex , rồi xuất thẳng ra LCD luôn . bây giờ thì ok rồi . nhưng mình còn chưa biết cái vụ AM và PM . lại còn năm nhuận hay không nhuận để mà biết tự cộng thêm ngày cho tháng 2 . nếu các bạn biết , mình mong các bạn chia sẻ nha .

a, mà lúc mình nạp lần đầu , mình nạp thẳng số hex luôn . vd :
năm : $07
tháng : $01
ngày : $28
giờ : $13
phút : $25
giây : $00
tương ứng khi xuất ra LCD là : 28 - 01 - 07 13:25:00
Chip DS1307 tự động điều chỉnh ngày theo năm nhuận cho đến 2100. Nếu bạn chọn chế độ 12 giờ (bit6 = 1) ở thanh ghi đếm giờ (02h) thì bit5 sẽ là bit báo PM/AM (mức 1 là PM). Khi đó chỉ có bit4 được dùng cho hàng chục giờ. Ngược lại, khi ở chế độ 24 giờ (bit6 = 0) thì bit5 sẽ được dùng làm bit thứ hai của hàng chục giờ. Nếu thay đổi giữa 12 và 24 giờ thì phải nhập lại giá trị giờ.

Bạn chịu khó đọc datasheet đi.

Thân,

hatuan296
29-01-2007, 01:17 AM
Chip DS1307 tự động điều chỉnh ngày theo năm nhuận cho đến 2100. Nếu bạn chọn chế độ 12 giờ (bit6 = 1) ở thanh ghi đếm giờ (02h) thì bit5 sẽ là bit báo PM/AM (mức 1 là PM). Khi đó chỉ có bit4 được dùng cho hàng chục giờ. Ngược lại, khi ở chế độ 24 giờ (bit6 = 0) thì bit5 sẽ được dùng làm bit thứ hai của hàng chục giờ. Nếu thay đổi giữa 12 và 24 giờ thì phải nhập lại giá trị giờ.

Bạn chịu khó đọc datasheet đi.

Thân,

Cảm ơn bạn đã trả lời tin . trước khi thử nghiệm con DS này , mình cũng đã xem datasheet của nó rất nhiều lần . và datasheet thì ai xem cũng như ai mà thôi . quan trọng là người nào nắm bắt được vấn đề nhanh lẹ . Và hiện giờ thì mình cũng đã làm được chế độ AM\PM . Dù sao cũng rất cảm ơn những kinh nghiệm mà các bạn đã chia sẽ . :)

hatuan296
29-01-2007, 03:16 AM
sẵn tiện đây mình đưa lên diễn đàn đề tài đồng hồ số dùng DS1307 mà mấy hôm nay mình nghiên cứu , học hỏi kinh nghiệm của anh em .

Đề tài dùng ngôn ngữ Picbasic pro . pic 18f458 kết nối I2c với DS1307 .bạn thông cảm , mình chưa rành về Proteus cho lắm nên cũng chưa biết con xtal và pin backup ở đâu . nên đành thay 2 con đó bằng 2 con điện trở .:o .
Sơ đồ kết nối như sau :

1\dành cho lcd :
portb từ b.4 đến b.7 kết nối từ D4 đến D7 của lcd
portb.1 >> rs
portb.2 >>rw
portb.3 >>e

2\ dành cho DS1307 :
porta.0 >> sda
porta.1 >> sc

3\ dành cho các nú bấm :
portc.0 >> nút nạp dữ liệu vào DS
portc.1 >> nút vào chương trình cài ngày giờ
portc.2 , portc.3 >> tương ứng với nút giảm , tăng dữ liệu .

các bạn xem file đính kèm sẽ rõ nha .
nếu có thắc mắc , hãy liên hệ mình . h_a_tuan2002@yahoo.com
đây là phần mềm cho con pic . mình mới làm quen nên chắc sẽ có nhiều sai sót . nếu có gì mong anh em giúp đỡ mình hoàn thiện phần mềm nha . cảm ơn nhiều .

huychuongn
29-01-2007, 02:12 PM
Mình có làm 1 đồng hồ số dùng Pic 18f458 , kết nối DS1307 qua i2c . hiển thị trên lcd . mình đã làm cho chạy , nhưng lại hiển thị không đúng kết quả . anh em nào đã từng làm cái này rồi thì giúp mình nha . Lỗi cụ thể như sau ;

- mình nhập giá trị ban đầu : $00,$00,$00,$07,$1B,$01,$07,$90
' Sec Min Hr Day D M Y Control

giây(sec) : 00
phút(min) : 00
giờ (hr) : 00
thứ (Day) : 7.
ngày (D) : 27
tháng(M) : 1
năm(y):7

lcd hiển thị như sau :

thu 7 27-1-7
0:0:0
h m s

mình nhập vào DS1307 thì ok . đọc ra thì cũng ok luôn . nhưng khi bắt đầu đếm . thì con số s chỉ đếm đến 9 thôi , rồi lại nhảy thành số 16 . ngay cả con m và con h cũng vậy . Khi mình nhẩm tính thì đúng là con s nhảy 60 lần thì con m nhảy 1 lần . nhưng hiển thị thì không đúng . có khi con s lên đến hàng 80 luôn .

Mình nghĩ chắc từ số 9 con DS1307 đã bỏ qua A , B , C , D , E , F để đếm đến 16 . Nhưng tại sao lại như vậy ? làm sao đế cho hiển thị đúng ? Và khi nạp lần đầu cho con Ds , thì mình nên để giá trị là gì ? thập phân hay nhị phân hay hệ 16 ? . khi mình đọc ra là số gì ?
mong bạn nào rành thì giúp mình nha . mình vô cùng cảm ơn .

À, còn 1 điều nữa . mình có cần phải đọc ghi theo thứ tự không ? và nếu có thì mình phải đọc cái gì trước , cái gì sau ?
ghi cái gì trước , cái gì sau ?

Bạn xem lại đi vì con DS 1307 nhận và phát mã BCD chứ không phải mã DEC bạn phải đổi lại cho đúng để hiển thị.,.

hatuan296
29-01-2007, 04:45 PM
Bạn xem lại đi vì con DS 1307 nhận và phát mã BCD chứ không phải mã DEC bạn phải đổi lại cho đúng để hiển thị.,.

mình đã nói , khi ghi con DS , mã nào cũng được ( mình đã kiểm tra với mã BCD , HEX , DEC .) còn khi đọc ra , mình nên chuyển sang Hex là để tương thích với LCD . chứ đâu có nói là bắt buộc khi đọc ra phải là số HEX đâu ?:confused: . mà vấn đê này đã được giải quyết xong . dù sao cũng cảm ơn bạn đã quan tâm . nếu bạn có thời gian . mong bạn xem giúp đề tài mình vừa gửi lên về mạch đồng hồ có dùng DS1307 .
chào bạn .

namqn
29-01-2007, 07:40 PM
Bạn đã xin ý kiến những ai đã từng làm với DS1307, nhưng những người góp ý lại không được bạn hoan nghênh. Tôi đã viết tutorial cho dsPIC sử dụng DS1307, cũng đã viết tutorial cho dsPIC sử LCD, nghĩa là tôi không lạ lẫm gì với những thứ này.

Lời khuyên của tôi là bạn đọc kỹ datasheet, chỗ nào không hiểu thì hãy hỏi, như vậy bạn sẽ nắm được nó rõ hơn.

Bạn chưa hiểu rõ về số BCD thì làm sao phân biệt được nó với số hex, như vậy làm sao có thể khẳng định là nạp số BCD và số hex đều được (tôi giả sử bạn ngụ ý là đều cho giá trị đúng). BCD là binary-coded decimal, nghĩa là số thập phân mã hóa bằng nhị phân, mỗi chữ số nhị phân sẽ dùng 4 bit để mã hóa, như vậy các tổ hợp cho các giá trị A, B, C, D, E, và F sẽ không được dùng.

Số thập phân 10 có mã hex là 0x0A, và mã BCD là 0x10. Bạn thử nạp 0x0A và 0x10 xem có ghi được cùng kết quả vào một thanh ghi nào đó của DS1307 hay không?

Thân,

hatuan296
29-01-2007, 10:58 PM
Bạn đã xin ý kiến những ai đã từng làm với DS1307, nhưng những người góp ý lại không được bạn hoan nghênh. Tôi đã viết tutorial cho dsPIC sử dụng DS1307, cũng đã viết tutorial cho dsPIC sử LCD, nghĩa là tôi không lạ lẫm gì với những thứ này.

Lời khuyên của tôi là bạn đọc kỹ datasheet, chỗ nào không hiểu thì hãy hỏi, như vậy bạn sẽ nắm được nó rõ hơn.

Bạn chưa hiểu rõ về số BCD thì làm sao phân biệt được nó với số hex, như vậy làm sao có thể khẳng định là nạp số BCD và số hex đều được (tôi giả sử bạn ngụ ý là đều cho giá trị đúng). BCD là binary-coded decimal, nghĩa là số thập phân mã hóa bằng nhị phân, mỗi chữ số nhị phân sẽ dùng 4 bit để mã hóa, như vậy các tổ hợp cho các giá trị A, B, C, D, E, và F sẽ không được dùng.

Số thập phân 10 có mã hex là 0x0A, và mã BCD là 0x10. Bạn thử nạp 0x0A và 0x10 xem có ghi được cùng kết quả vào một thanh ghi nào đó của DS1307 hay không?

Thân,

vấn đề nào , câu nói nào của mình mà bạn cho là đã " không hoan nghênh " những người giúp mình ? Còn việc xem datasheet , đương nhiên là mình đã xem rồi , và đã không hiểu nên mới lên diễn đàn nhờ giúp đỡ .chứ nếu đã hiểu thì nói làm gì ? Đồng ý , việc bạn yêu cầu mình xem datasheet cũng là một gợi ý hay . nên mình cũng đã cảm ơn bạn đấy thôi . Nếu bạn còn chưa vừa lòng nữa thì mình cũng đành chịu .

Còn về các tên gọi của hệ thống số đếm . có thể mình đã nắm không rõ . nhưng chắc chắn mình đã nạp cho con DS1307 , phần giờ những loại số sau :

ví dụ , nạp số 10 - tương ứng là 10 giờ
$10 - hex
%00010000 - Binary
16 - decimal
thì con DS khi đọc ra vẫn là 10 h . với điều kiện phải chuyển con số vừa đọc từ DS sang Hex rồi mới xuất ra LCD . Để tương thích với lcd . nếu không thì LCD sẽ hiển thị 1 con số khác ( chuyện này mình cũng đã từng nói ). Việc này mình đã thử đi , thử lại nhiều lần .

Và như mình ĐÃ nói . mọi vấn đề mấy hôm nay mình hỏi đều đã được giải quyết xong , bởi vậy , chúng ta không nên bàn cãi thêm về các con số , tên gọi của chúng nữa mà làm gì .. Mình cũng đã đưa đề tài đó lên để anh em , những người mới chưa biết gì về pic và RTC có thêm thông tin để tham khảo .

bài thực hành này mình đã làm với ngôn ngữ PICBASIC PRO .
.

vnbtech
30-01-2007, 02:02 AM
anh HaTuan,
Co' the anh lam du'ng nhung ca'ch goi cua anh bi. lan lo^.n. Ta ca nhung gi anh chuyen de nap co con DS1300 va doc no ra the hien thi, la theo chuan BCD het. May ban trong nay chi? mong anh hieu ro va dung co' lan lon giua HEX/DEC and BCD....

chuc mung anh da lam duoc.

VNBTECH

hatuan296
30-01-2007, 04:46 PM
cảm ơn bạn VNBTECH về lời khuyên . thực sự mình đã học hỏi rất nhiều từ diễn đàn này . . nếu có thời gian . mong bạn góp ý cho bài thực hành của mình nha .

newuser
02-02-2007, 11:08 AM
anh HaTuan,
Co' the anh lam du'ng nhung ca'ch goi cua anh bi. lan lo^.n. Ta ca nhung gi anh chuyen de nap co con DS1300 va doc no ra the hien thi, la theo chuan BCD het. May ban trong nay chi? mong anh hieu ro va dung co' lan lon giua HEX/DEC and BCD....

chuc mung anh da lam duoc.

VNBTECH

ừ, đúng là bạn Tuấn lẫn lộn các dạng số rồi. Rõ ràng là bạn ghi vào DS1307 số nào cũng được(HEX,BCD,DEC), miễn là đừng vượt quá giá trị cho phép của thanh ghi đó, và với DS1307, nó không phân biệt dạng số bạn nạp vào mà đối với nó, nó chỉ hiểu đó là BCD. Giá trị bạn đọc ra cũng vậy, dạng số mà nó xuất ra cho bạn là BCD, do đó đọan code chuyển từ HEX-->BCD của bạn(nếu bạn có dùng) là thừa.
Bạn đã từng tiếp xúc với RTC DS12887 cũng của Dallas chưa? trong thanh ghi chức năng của nó có một bit cho phép ta chọn dạng số nhập vào và đọc ra là BCD hay HEX đấy!
phần hiển thị của bạn là LCD thì không thể có chuyện để nguyên con số đọc được đem xuất. CPU của LCD không giải mã bảng mã nào khác ngoài ASCII. Lấy ví dụ khi muốn xuất số 1 ra LCD, bạn phải đẩy số 31Hexa (số Hexa theo quan điểm của Vi điều khiển) lên LCD (số 31-ASCII theo quan điểm của LCD). Các số từ số 00Hexa đến số 99hexa (mã BCD - DS1307) được VĐK đọc (VĐK không nghĩ đó là BCD đâu nhé, đối với nó chỉ là HEXA), rồi xuất lên LCD (đối với LCD cũng vậy,chỉ có ASCII thôi). Bạn hiểu rồi chứ?

Sangcao
02-02-2007, 01:02 PM
Code cua DS1307 day:
////////////////////////////////////////////////////////////////////////////////
/// 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_C4
#define RTC_SCL PIN_C3

#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(0x80); // Disable squarewave output pin
i2c_stop();

}

void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec)
{
sec &= 0x7F;
hr &= 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 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(1)
{
// 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));
}

minhtienbk
31-08-2007, 12:15 PM
em cũng đang làm với 1307 ,dùng PIC basic pro ,viec ghi và đọc OK , nhưng nó ko đếm lên , ghi vào thanh ghi 00h ( giây) = 03h ,rồi sau đó đọc lại ,nó vẫn cứ là 03h ,để bao lâu cũng là 03h ,bó tay ,có ai chỉ giùm :)

Mạch OK ,PIN ,dt kéo lên ,thạch anh đầy đủ , ( ghi giá trị dc mà ) ,

thuhang
09-09-2007, 03:41 AM
Anh thử thay con DS1307 khác xem thế nào .

linhnc308
10-09-2007, 06:38 PM
em cũng đang làm với 1307 ,dùng PIC basic pro ,viec ghi và đọc OK , nhưng nó ko đếm lên , ghi vào thanh ghi 00h ( giây) = 03h ,rồi sau đó đọc lại ,nó vẫn cứ là 03h ,để bao lâu cũng là 03h ,bó tay ,có ai chỉ giùm :)

Mạch OK ,PIN ,dt kéo lên ,thạch anh đầy đủ , ( ghi giá trị dc mà ) ,

Bạn gắn một con LED vào chân clokc out của DS1307, rồi quan sát xem sau khi đã cấu hình cho DS thì LED có nháy hay không, nếu chưa nháy thì có lẽ bạn đã cấu hình sai hoặc lỗi có thể nầm ở bus I2C. Xem lại cẩn thận từng bước để phát hiện lỗi xem nó nằm ở đâu.
Chúc thành công.

vandungevn
11-10-2007, 06:06 PM
C18 giao tiếp I2C với DS1307 có ai đã làm cho chạy chưa. Post lên cho Dũng tham khảo với........!

hanspkt
11-10-2007, 10:42 PM
Em dùng CCS để viết chương trình và hiển thị ra LCD (dùng DS1307), đọc và điều chỉnh các dữ liệu từ ô nhớ 00H --> 09H là đúng yêu cầu chỉ gặp rắc rối từ ô nhớ 0Ah trở về sao. Mong các anh giúp đỡ tí !

HueDN
12-10-2007, 11:11 PM
Đây là code của đồng hồ 6 digit của TMdùng để học tập. Tuy nhiên vì mới học PIC nên chưa hiểu được. Nhất là chổ MAP đó. Các cao thủ giải thích dùm nhé
/************************************************** **************
* Real time Clock DS1307
* Dong ho so su dung DS1307 hien thi tren 6 LED 7-segment hh.mm.ss
* Sofware: Compiler CCS Ver 4.018
* Harware: TMe - EasyPIC: (www.tme.com.vn)
- Pull up PORTD, Pull-down Switches, connect PORTD to Switches
- Switches: T1 - Mode, T2 - set time, T3 - clean status
- DIP Swich SW2 all ON (Enable 7-segment and RTC DS1307)
************************************************** ***************/

#include <16F877A.h>
#include <def_877a.h> //file header do nguoi dung dinh nghia
#include <ds1307.c>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=12000000)

byte sec,min,hour;
byte const MAP[10] = {0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90 };//Cathode
byte DIS1,DIS2,DIS3,DIS4,DIS5,DIS6;
byte key,mode;
int1 ampm,blink,blink_sec,blink_min,blink_hour;
int1 on_off;
int16 count;

#bit SW1 = 0x8.0 // D0 - mode
#bit SW2 = 0x8.1 // D1 - set_time
#bit SW3 = 0x8.2 // D2 - Clear_status

void set_blink();
void change_time();
void update_1307();
void keyscan();
void set_sec();
void set_min();
void set_hour();
void clear_status();
void read_time();
void update_time();
void display();

//===============================================


void set_blink()
{

switch (mode)
{
case 1: blink_sec=1; break;
case 2: {blink_min=1;blink_sec=0;} break;
case 3: {blink_hour=1;blink_min=0;} break;
case 4:
{
blink=0;mode = 0;blink_sec=0;
blink_min=0;blink_hour=0;
}
break;
}
}

void change_time(){ //Ham chon che do, giong nhu o dong ho CASIO, nhan 1 lan la phut, 2 lan la gio....

if(mode == 1) {blink_sec=1;set_sec();}
if(mode == 2) {blink_min=1;set_min();}
if(mode == 3) {blink_hour=1;set_hour();}
if(mode == 4)
{
blink=0;mode = 0;
blink_sec=0; blink_min=0; blink_hour=0;
}
}


void update_1307()
{
write_DS1307(0,sec);
write_DS1307(1,min);
bit_set(hour,6);
if (ampm == 0) {bit_clear(hour,5); write_DS1307(2,hour);} // AM
if (ampm == 1) {bit_set (hour,5); write_DS1307(2,hour);} // PM

}
void keyscan() {
RD0=1;RD1=1;RD2=1;RD3=1;
if(SW1 != 1) { key=0;SW1=1;delay_ms(150);}
if(SW2 != 1) { key=1;SW2=1;delay_ms(150);}
if(SW3 != 1) { key=2;SW3=1;delay_ms(150);}
if(key != 5)
{
switch (key)
{
case 0: {mode++;key = 5;blink=1;set_blink();}
break;
case 1: {change_time();key = 5;update_1307();}
break;
case 2: {clear_status();key = 5;}
break;
}
}
}

void set_sec()
{
sec=read_ds1307(0);
if (sec>=0x30) {sec=0; min++; write_ds1307(1,min);}
else sec=0;
write_ds1307(0,sec);
}
void set_min()
{ byte j;

min=read_ds1307(1);
min++;
j=min & 0x0F;
if (j>=0x0A) min=min+0x06;
if (min>=0x60) min=0;
write_ds1307(1,min);
}
void set_hour()
{
hour= hour & 0x1F;
hour++;
if(hour== 0x0a) hour = hour+0x06;
if(hour == 0x13)
{ hour = 0x00;
if (ampm == 0) ampm = 1;
else ampm = 0;
}
}

void clear_status() {

mode=4; set_blink();
}
void read_time()
{
sec = read_DS1307(0);
min = read_DS1307(1);
hour = read_DS1307(2);
update_time();
}

void update_time()
{

ampm = bit_test(hour,5); //test AM PM
if(ampm == 0) {RD4 = 0;RD5=1;} //AM
if(ampm == 1) {RD4 = 1;RD5=0;} // PM
DIS1= sec & 0x0F;
DIS2=(sec & 0xF0)>>4; //convert to BCD SEC
DIS3= min & 0x0F;
DIS4=(min & 0xF0)>>4; //convert to BCD MIN
DIS5= hour & 0x0F;
DIS6=(hour & 0x10)>>4; //convert to BCD HOUR

}
void display() {
TRISB=0x00;TRISA=0x00;
if(blink==0) goto norm;
if(on_off==0) goto led_blink;
norm:
// sec - min - hour
PortB=MAP[DIS1]; RA5=0;//DIS1
delay_ms(1); RA5=1;
PortB=MAP[DIS2]; RA4=0; //DIS2
delay_ms(1); RA4=1;
PortB=MAP[DIS3];output_low(PIN_B7);RA3=0;//DIS3
delay_ms(1); RA3=1;
PortB=MAP[DIS4]; RA2=0;//DIS4
delay_ms(1); RA2=1;
PortB=MAP[DIS5];output_low(PIN_B7); RA1=0;//DIS5
delay_ms(1); RA1=1;
PortB=MAP[DIS6];if (portb==0xC0) RA0=1; else RA0=0;//DIS6
delay_ms(1); RA0=1;//*/

if(count!=0) goto exit;
else
{
count=15;
on_off=0;
}
goto exit;

led_blink:
PortB=MAP[DIS1];
if (blink_sec==1) RA5=1;//DIS1
else RA5=0;
delay_ms(3); RA5=1;
PortB=MAP[DIS2];
if (blink_sec==1) RA4=1;//DIS2
else RA4=0;
delay_ms(3); RA4=1;
PortB=MAP[DIS3];output_low(PIN_B7);
if(blink_min==1) RA3=1;//DIS3
else RA3=0;//DIS3
delay_ms(3); RA3=1;
PortB=MAP[DIS4];
if(blink_min==1) RA2=1;//DIS4
else RA2=0;//DIS4
delay_ms(3); RA2=1;
PortB=MAP[DIS5];output_low(PIN_B7);
if(blink_hour==1) RA1=1;//DIS5
else RA1=0;//DIS5
delay_ms(3); RA1=1;
PortB=MAP[DIS6];
if(blink_hour==1) RA0=1;//DIS6
else {if (portb==0xC0) RA0=1; else RA0=0;}//DIS6
delay_ms(3); RA0=1;//*/
if(count==0) {count=15;on_off=1;}

exit:
count--;
}
void main() {
byte u;
Delay_ms(5);
Trisd = 0x0F;
Trisb = 0x00;//output
Trisa = 0x00;
RD4=1;RD5=1;
init_ds1307();
u=read_ds1307(0);
sec=u & 0x7F;// enable RTC
write_ds1307(0,sec);// set second to 00 and enable clock(bit7=0)

//Xoa tat ca cac co dieu khien
key=5;mode=0;blink=0;
blink_sec=0;blink_min=0;blink_hour=0;
count=15;on_off=1;
ampm = bit_test(hour,5);// test AM_PM
if(ampm==0) {RD4 = 0;RD5=1;} //LED AM
if(ampm==1) {RD4 = 1;RD5=0;} //LED PM
while(true)
{
read_time();
display();
keyscan();
}
}//end of main program

kali
12-11-2007, 11:08 AM
Chào mọi người!
Mình dùng protues mô phỏng con DS1307.
Mình đã nạp vào thanh ghi điều khiển 0x07 của DS1307 giá trị 0x10, tức mình muốn nó phát xung 1Hz ở chân Sout, nhưng trong protues thì nó lại phát xung 0.5Hz.
Bạn nào giải thích hộ mình nguyên nhân được không.
Thanks.

vinhyen1
22-11-2007, 01:26 PM
minh su dung DS 1302,noi voi IC 89S51 các ban co the chi cho minh các buoc để lập trình và cách chuyển du lieu lên LCD.minh cam on moi bat dau hoc mong các ban dung cuoi nhe

hanspkt
22-11-2007, 01:55 PM
bạn dùng ngôn ngữ lập trình gì

rhinoceros
15-11-2008, 01:28 PM
bạn viết chương trình bằng ASM.mình dùng C để viết nên đọc chương trình của bạn minh không hiểu được.mình đang tìm hiểu về con DS1307 này,không biết bắt đầu từ đâu,bạn có thể nói cho mình các bước để đọc,ghi lên con DS1307 này không.mình kết nối trực tiếp với VDK không dùng IC phụ
cảm ơn trước nhá

ketxanh
02-12-2008, 10:26 PM
Muốn tìm hiểu DS1307 thi đọc datasheet la biết hết liền. Trong Datasheet chỉ rõ làm bạn ơi

12a3456789
24-12-2008, 01:29 PM
ai đó giúp với mình đang viết chương trình đồng hồ số hiển thị ngày, tháng, năm trên LED 7 đoạn dùng 98c51 với DS1307 bằng ngôn ngữ Assemble .Mình đang cần chương trình để tham khảo, ai đó có chương trình thì post lên nhen.Nếu được thì gửi cho chương trình luôn, địa chỉ email của mình la caovan_py@yahoo.com

hvhdtk3
14-07-2009, 09:21 AM
Mình đang làm cái đồng hồ số hiển thị LCD 16*2, dùng DS1307. Có 2 điều tui ko giải thích được, mong các bạn giúp đỡ:
1) Mình đọc kỹ Datasheet của DS1307 và cấu hình thanh ghi Control (địa chỉ 07H) là:
write_DS1307(0x07, 0x90); //nghĩa là tại địa chỉ 07H, ghi vào giá trị 90H = (10010000)binary.
Khi đó, bit SQWE = 1 phải tạo xung ra có tần số 1 Hz.
Khi mô phỏng, thời gian hiển thị trên LCD là đúng, nhưng chân tạo xung 1 Hz lại không đúng, nó cứ 2 giây mới thay đổi trạng thái. Thành ra giá trị giây hiển thị là: 1, 3, 5,... chứ không liên tục 1, 2, 3, 4..... Why?????????????????????????????????
2) Mình đặt giá trị ban đầu cho DS1307 là: ngày 07, tháng 08, năm 09. Nhưng trên LCD không hiển thị số 0, mà chỉ là: 7 / 8 / 9 Why?????????????????????????????????
Các bạn giúp mình với !

nguyenhung1811
22-07-2009, 09:58 PM
đây là hai đoạn chương trình con ghi và đọc giữ liệu với ds1307. Các bạn xem mình viết có đúng ko mà sao khi mô phỏng trên protues thì mình chi ghi được một byte thôi. Sau lệnh câu lệnh write đầu tiên thì các câu lệnh read hoặc write khác không có tác dụng.
//////////////////////////////////////////////////////////
void write(int8 value, int8 add)
{
i2c_start();
i2c_write(0xD0);
i2c_write(add);
i2c_write(value);
i2c_stop();
}

int8 read(int8 add)
{
int8 value_re;
i2c_start();
i2c_write(0xD0);
i2c_write(add);
i2c_start();
i2c_write(0xD1);
value_re = i2c_read();
i2c_stop();
i2c_stop();
return(value_re);
}
////////////////////////////////////////////////////////

nguyenhung1811
23-07-2009, 07:06 AM
Mình đang làm cái đồng hồ số hiển thị LCD 16*2, dùng DS1307. Có 2 điều tui ko giải thích được, mong các bạn giúp đỡ:
1) Mình đọc kỹ Datasheet của DS1307 và cấu hình thanh ghi Control (địa chỉ 07H) là:
write_DS1307(0x07, 0x90); //nghĩa là tại địa chỉ 07H, ghi vào giá trị 90H = (10010000)binary.
Khi đó, bit SQWE = 1 phải tạo xung ra có tần số 1 Hz.
Khi mô phỏng, thời gian hiển thị trên LCD là đúng, nhưng chân tạo xung 1 Hz lại không đúng, nó cứ 2 giây mới thay đổi trạng thái. Thành ra giá trị giây hiển thị là: 1, 3, 5,... chứ không liên tục 1, 2, 3, 4..... Why?????????????????????????????????
2) Mình đặt giá trị ban đầu cho DS1307 là: ngày 07, tháng 08, năm 09. Nhưng trên LCD không hiển thị số 0, mà chỉ là: 7 / 8 / 9 Why?????????????????????????????????
Các bạn giúp mình với !

ban cho minh xin doan chuong trinh ma ban viet nhe'. Minh viet mai ma` chi co ghi duoc thoi. ko doc du lieu duoc.

minhsondaklak
22-08-2009, 05:31 PM
Bạn tham khảo link này xem :
http://www.picvietnam.com/forum/showthread.php?t=2644

chuyentinhyeu03
02-09-2009, 08:06 PM
mình đang bắt tay vào làm đồ án này chưa bjt làm như thế nào nên đọc bài viết của anh em thật có ích.cảm ơn anh em nhju

thanhlam1987
11-09-2009, 01:16 AM
Em đang học pic16F877 nhưng chưa biết nhiều. Em có bài tập ai có thể giúp:
Dùng pic16f877Agiao tiếp với REATIME13807 với 6 led 7 đoạn. viết chương trình đồng hồ số dùng ASSEMPLY
AI lam được gửi cho em :samac_love999@yahoo.com

tiendungnd
12-09-2009, 07:25 PM
ai có code của mạch hiẻn thị đồng hồ số dùng led 7 thanh k? cho mìng với.
ai có gửi vào mail :ptdumh_nd@yahoo.com

duyminhnguyen
22-09-2009, 10:40 PM
chương trình của bạn thanhlam1987 , bạn nên đọc datasheet của ds1307 và tìm hiểu cách kết nối phần cứng........vấn đề của bạn mình cũng đang quan tâm ,hy vọng sẽ có người giúp đỡ

....cái này khó ở chỗ khởi tạo ds 1307 và chuản i2c

Mr.Bi
23-09-2009, 11:52 PM
Cái này trên mạng đầy , do mấy u k chịu tìm hiểu và thử nghiệm code

void start(void)
{ SCL=0;SDA=1;SCL=1;SCL=1;
SDA=0;SCL=0;}
void stop(void)
{ SCL=0;SDA=0;SCL=1;SDA=1;}
bit write_data(unsigned char chr)
{ unsigned char temp,ack;
for(temp=0;temp<8;temp++)
{ SDA = (chr& 0x80) ? 1:0;
SCL=1;
SCL=0;
chr=chr<<1;
};
SDA=1;SCL=1;ack=SDA;
SCL=0;
return(ack);
}
unsigned char convertBCD(unsigned char _data)
{ unsigned char temp;
temp=(_data/10<<4)|(_data%10&0x0F);
return temp;
}
unsigned char read_data(void)
{ unsigned char temp1,temp2=0;
for(temp1=0;temp1<8;temp1++)
{ SCL=1;
temp2=temp2<<1;
temp2=temp2|((unsigned char)(SDA));
SCL=0;
};
return(temp2);
}
void write_RTC(unsigned char address, unsigned char _data)
{ bit status;
start();
write_data(0xD0);
write_data(address);
write_data(_data);
stop();
start();
status=write_data(0xD0);
while(status) //status = 1 (NACK)
{ start();
status=write_data(0xd0);
};
}
unsigned char read_RTC(unsigned char address)
{ unsigned char k;
start();
write_data(0xD0);
write_data(address);
start();
write_data(0xD1);
k=read_data();
stop();
return ((k>>4)*10+(k&0x0F));
}
void init_RTC()
{ write_RTC(0x07,0x10);
write_RTC(0x00,0x00); //0s
write_RTC(0x01,0x47); // phut : 47
write_RTC(0x02,0x13); // h : 13
write_RTC(0x04,0x26); // ngay : 26
write_RTC(0x05,0x06); // thang : 6
write_RTC(0x06,0x09); // nam : 2009
}


Đọc bài hướng dẫn chi tiết http://svdanang.com/@pbk/showthread.php?t=29583

const_nos
11-10-2009, 10:38 AM
Cảm ơn các bạn đã quan tâm . hôm nay mình đã làm được rồi . cái con số mình nhập vào DS không qua trọng . là kiểu dữ liệu gi cũng ok , hex hoặc decimal . nhưng quan trọng là lúc đọc ra . mình phải chuyển số đó sang hex , rồi xuất thẳng ra LCD luôn . bây giờ thì ok rồi . nhưng mình còn chưa biết cái vụ AM và PM . lại còn năm nhuận hay không nhuận để mà biết tự cộng thêm ngày cho tháng 2 . nếu các bạn biết , mình mong các bạn chia sẻ nha .

a, mà lúc mình nạp lần đầu , mình nạp thẳng số hex luôn . vd :
năm : $07
tháng : $01
ngày : $28
giờ : $13
phút : $25
giây : $00
tương ứng khi xuất ra LCD là : 28 - 01 - 07 13:25:00

namqn: đây đâu phải là số hex, nó vẫn là dạng BCD đó chứ. Bạn thử nạp $0F vào ô nhớ đếm năm rồi đọc lại xem sẽ được số nào.

Ủa.Mình có thắc mắc: Con DS nó lưu sẵn thời gian bên trong nó .Mình chỉ cần đọc nó ra với địa chỉ thanh ghi tương ứng để có được là có được thới gian thôi chứ.Tại sao lại phải nhậpo vào rồi mới đọc ra?Mình ko hiểu.Bạn có thể giải thích chổ nầy được không?Sắn tiện bạn post luôn chươnmg trình của bạn lên để mọi người cùng tham khảo

hvhdtk3
15-10-2009, 12:35 AM
ban cho minh xin doan chuong trinh ma ban viet nhe'. Minh viet mai ma` chi co ghi duoc thoi. ko doc du lieu duoc.

Giờ mình viết xong rồi đây! Không biết gửi File đính kèm như thế nào cả, đành post cả chương trình trình lên vậy! Anh em thông cảm nha!

Tuy dùng Proteus mô phỏng ngon lành, nhưng mình test trên mạch thật thì gặp vấn đề này không giải thích được! Mong anh em giúp đỡ.
Mình đặt giá trị cho DS1307: setDateDs1307(01, 02, 03, 04, 05, 06, 07);
với mục đích hiển thị trên LCD là: Time: 03:02:01 Date: 05:06:07
Nhưng trên LCD lại hiển thị: Time: 05:03:00 Date: 07:00:00
Hic! Hiển thị sai rồi! Biết làm sao đây???

Code:

////////////////////////////////////////////////////////////////////////////////
#include <16f877a.h>
#include <def_877a.h>
#device *=16 ADC=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#include <lcd_lib_4bit.c>
#use rs232(baud=9600,parity=N,xmit=PIN_B5,rcv=PIN_B2,bi ts=9)
#use i2c(Master,Fast,sda=PIN_A1,scl=PIN_A0)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#define DS1307_SDA PIN_A1
#define DS1307_SCL PIN_A0
//************************************************
int8 val_sec1, val_min1, val_hou1, val_dat1, val_mon1, val_yea1;
int8 val_sec2, val_min2, val_hou2, val_dat2, val_mon2, val_yea2;
//************************************************
void display_lcd();
//************************************************
#int_ext // Khai bao chuong trinh ngat
RB0_isr() {
display_lcd();
return input(PIN_B1);
}
//**********************************************
int8 decToBcd(int8 val) {
return ( (val/10*16) + (val%10) );
}
//***********************************
int8 bcdToDec1(int8 val) { //Tach lay so hang chuc
return (val/16*10);
}
//***********************************
int8 bcdToDec2(int8 val) { //Tach lay so hang don vi
return (val%16);
}
//***********************************
void init_DS1307() {
output_float(DS1307_SCL); //Bus free
output_float(DS1307_SDA); //Bus free
}
//***********************************
void write_DS1307(byte address, byte data) {
short int status;
i2c_start();
i2c_write(0xd0);
i2c_write(address);
i2c_write(data);
i2c_stop();
i2c_start();
status=i2c_write(0xd0);
while(status==1)
{
i2c_start();
status=i2c_write(0xd0);
}
}
//***********************************
BYTE read_DS1307(byte address)
{
BYTE data;
i2c_start();
i2c_write(0xd0);
i2c_write(address);
i2c_start();
i2c_write(0xd1);
data=i2c_read(0);
i2c_stop();
return(data);
}
//***********************************
void setDateDs1307(int8 second, // 0-59
int8 minute, // 0-59
int8 hour, // 1-23
int8 dayOfWeek, // 1-7
int8 dayOfMonth, // 1-28/29/30/31
int8 month, // 1-12
int8 year) // 0-99
{
write_DS1307(0x0, decToBcd(second));
delay_ms(10);
write_DS1307(0x1, decToBcd(minute));
delay_ms(10);
write_DS1307(0x2, decToBcd(hour));
delay_ms(10);
write_DS1307(0x3, decToBcd(dayOfWeek));
delay_ms(10);
write_DS1307(0x4, decToBcd(dayOfMonth));
delay_ms(10);
write_DS1307(0x5, decToBcd(month));
delay_ms(10);
write_DS1307(0x6, decToBcd(year));
}
//***********************************
void display_lcd() {
LCD_putcmd(0x80);
Printf(LCD_putchar,"Time: ");
LCD_putcmd(0xC0);
Printf(LCD_putchar,"Date:");
//*******************************************
val_sec1 = bcdToDec1(read_DS1307(0x00)); //So giay hang chuc
val_sec2 = bcdToDec2(read_DS1307(0x00)); //So giay hang don vi

val_min1 = bcdToDec1(read_DS1307(0x01));
val_min2 = bcdToDec2(read_DS1307(0x01));

val_hou1 = bcdToDec1(read_DS1307(0x02));
val_hou2 = bcdToDec2(read_DS1307(0x02));

val_dat1 = bcdToDec1(read_DS1307(0x04));
val_dat2 = bcdToDec2(read_DS1307(0x04));

val_mon1 = bcdToDec1(read_DS1307(0x05));
val_mon2 = bcdToDec2(read_DS1307(0x05));

val_yea1 = bcdToDec1(read_DS1307(0x06));
val_yea2 = bcdToDec2(read_DS1307(0x06));
//*******************************************
//In lan luot cac so ra LCD
LCD_putcmd(0x8E);
Printf(LCD_putchar,"%u",val_sec1);
LCD_putcmd(0x8F);
Printf(LCD_putchar,"%u",val_sec2);

LCD_putcmd(0x8A);
Printf(LCD_putchar,"%u:",val_min1);
LCD_putcmd(0x8B);
Printf(LCD_putchar,"%u:",val_min2);

LCD_putcmd(0x86);
Printf(LCD_putchar,"%u:",val_hou1);
LCD_putcmd(0x87);
Printf(LCD_putchar,"%u:",val_hou2);

LCD_putcmd(0xC6);
Printf(LCD_putchar,"%u/",val_dat1);
LCD_putcmd(0xC7);
Printf(LCD_putchar,"%u/",val_dat2);

LCD_putcmd(0xCA);
Printf(LCD_putchar,"%u/",val_mon1);
LCD_putcmd(0xCB);
Printf(LCD_putchar,"%u/",val_mon2);

LCD_putcmd(0xCE);
Printf(LCD_putchar,"%u",val_yea1);
LCD_putcmd(0xCF);
Printf(LCD_putchar,"%u",val_yea2);
}
//***********************************

void main()
{
set_tris_b (0x01);
set_tris_d (0x00);
output_b (0x00);
output_c (0x00);
output_d (0x00);
LCD_init(); //Khoi tao LCD
LCD_putcmd(0x80);
Printf(LCD_putchar,"Time: ");
LCD_putcmd(0xC0);
Printf(LCD_putchar,"Date:");
init_DS1307(); //Khoi tao DS1307
write_DS1307(0x07, 0x90); //Cau hinh thanh ghi cua DS1307
setDateDs1307(01, 02, 03, 04, 05, 06, 07); //Vi du Time: 03:02:01 Date: 05:06:07
enable_interrupts(GLOBAL);
enable_interrupts(INT_ext);
while (1)
{
}
}
//************************************************** **
////////////////////////////////////////////////////////////////////////////////
//************************************************** **

notrino1506
19-10-2009, 03:18 PM
Thưa các sư huynh, em đã có tham khảo theo bài của các anh rất kỹ lưỡng và một số bài khác nói về giao tiếp I2C cụ thể là trong trường hợp: gia tiếp với DS1307.
--------------------------------
Kết quả: em có thể ghi dữ liệu vào DS1307, nhưng không thể đọc ra được. Nói chính xác hơn là đọc ra sai! Cụ thể như sau:
--------------------------------
1_Em nạp dữ liệu vào DS1307 từ 0x00 đến 0x07.
http://i681.photobucket.com/albums/vv177/notrino1506/Untitled1.jpg
http://i681.photobucket.com/albums/vv177/notrino1506/Untitled2.jpg
http://i681.photobucket.com/albums/vv177/notrino1506/Untitled3.jpg

2_Kiểm tra bằng KIT developing thì thấy có dao động ở chấn SQW=> nạp dữ liệu vào control byte (địa chỉ 0x07) của IC DS1307 là chính xác.( Cụ thể hơn em nạp giá trị 0x10 vào control byte =>xung 1Hz;...)=>chứng tỏ là ghi dư liệu được và là ghi đúng!


3_Em xuất đúng ngay tại giá trị control byte (tức là bằng 0x10) thì khi đọc thanh ghi SSPBUF sau khi waitMSSP la sai!!
http://i681.photobucket.com/albums/vv177/notrino1506/Untitled4.jpg
http://i681.photobucket.com/albums/vv177/notrino1506/Untitled5.jpg

4_Em cũng đã thử rất nhiều lần với nhiều thanh ghi khác của RTC, nhưng kết quả truy xuất lại đều vô vọng. Em cũng có tra cai flowchart phần ghi và nhận của PIC về I2C master mode trong datasheet 16F887A(trang số 315 và 317). Nhưng em thấy nó đúng!(sau khi thiết lập mọi thứ; chỉ cần SET SREN thôi).

------------------------------------------
Đó là những thăc mắc của em, em cũng đã suy nghĩ rất nhiều về vấn đề đó và em cũng đã thử và rút ra là:
-có thể sau mỗi lần nhận thì ACK phát ra từ PIC đến RTC có ành hưởng j đến SSPBUF ko?
-Có lần thí nghiệm em đã có thể nhận được 4 bit đầu là chính xác!(chạy debug và KT thanh ghi bằng Watch trong MPLAB), nhung 4 bit sau la FFFF trong khi DS1307 chỉ đếm BCD thôi=> có thể xung clk không đồng bộ dẫn đến dữ liệu nhận sai? Thiết lập của em la hoàn toàn bình thường: thạch anh 4Mhz cho PIc; 32768 cho RTC; tao xung clk đồng bộ 100 Khz....
-Em cũng đã kham khảo ý kiến của thầy trong trường nhưng coi bộ khó có giải đáp!
--------------------------------------------
Em biết là đã làm mất thời gian của các anh rất nhiều nhưng mong anh giúp đỡ em. Em rất muốn hiểu rõ hơn nữa về PIC. Cái này là ĐAMH1 của em: nó chỉ chiếm có 1 trình thôi, tuy vậy em cố gắng thực hiện có KQ ko vì điểm số chỉ vì hiểu biết và đam mê.
-----------------------------------------------
Mong anh hồi âm cho em để em có thể giảii quyết được vấn đề trên.
-----------------------------------------
Em có gửi theo cái ASM của em; hơi lung tung 1 tí (có thêm phần xuất LCD nhưng em đã làm chạy rồi). http://www.mediafire.com/download.php?iyhtwro5zrn
------------------------
CHÂN THÀNH CÁM ƠN các ANH!!!

babybaby002
03-12-2010, 05:17 PM
Giờ mình viết xong rồi đây! Không biết gửi File đính kèm như thế nào cả, đành post cả chương trình trình lên vậy! Anh em thông cảm nha!

Tuy dùng Proteus mô phỏng ngon lành, nhưng mình test trên mạch thật thì gặp vấn đề này không giải thích được! Mong anh em giúp đỡ.
Mình đặt giá trị cho DS1307: setDateDs1307(01, 02, 03, 04, 05, 06, 07);
với mục đích hiển thị trên LCD là: Time: 03:02:01 Date: 05:06:07
Nhưng trên LCD lại hiển thị: Time: 05:03:00 Date: 07:00:00
Hic! Hiển thị sai rồi! Biết làm sao đây???

Code:

////////////////////////////////////////////////////////////////////////////////
#include <16f877a.h>
#include <def_877a.h>
#device *=16 ADC=8
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=20000000)
#include <lcd_lib_4bit.c>
#use rs232(baud=9600,parity=N,xmit=PIN_B5,rcv=PIN_B2,bi ts=9)
#use i2c(Master,Fast,sda=PIN_A1,scl=PIN_A0)
#use fast_io(b)
#use fast_io(c)
#use fast_io(d)
#define DS1307_SDA PIN_A1
#define DS1307_SCL PIN_A0
//************************************************
int8 val_sec1, val_min1, val_hou1, val_dat1, val_mon1, val_yea1;
int8 val_sec2, val_min2, val_hou2, val_dat2, val_mon2, val_yea2;
//************************************************
void display_lcd();
//************************************************
#int_ext // Khai bao chuong trinh ngat
RB0_isr() {
display_lcd();
return input(PIN_B1);
}
//**********************************************
int8 decToBcd(int8 val) {
return ( (val/10*16) + (val%10) );
}
//***********************************
int8 bcdToDec1(int8 val) { //Tach lay so hang chuc
return (val/16*10);
}
//***********************************
int8 bcdToDec2(int8 val) { //Tach lay so hang don vi
return (val%16);
}
//***********************************
void init_DS1307() {
output_float(DS1307_SCL); //Bus free
output_float(DS1307_SDA); //Bus free
}
//***********************************
void write_DS1307(byte address, byte data) {
short int status;
i2c_start();
i2c_write(0xd0);
i2c_write(address);
i2c_write(data);
i2c_stop();
i2c_start();
status=i2c_write(0xd0);
while(status==1)
{
i2c_start();
status=i2c_write(0xd0);
}
}
//***********************************
BYTE read_DS1307(byte address)
{
BYTE data;
i2c_start();
i2c_write(0xd0);
i2c_write(address);
i2c_start();
i2c_write(0xd1);
data=i2c_read(0);
i2c_stop();
return(data);
}
//***********************************
void setDateDs1307(int8 second, // 0-59
int8 minute, // 0-59
int8 hour, // 1-23
int8 dayOfWeek, // 1-7
int8 dayOfMonth, // 1-28/29/30/31
int8 month, // 1-12
int8 year) // 0-99
{
write_DS1307(0x0, decToBcd(second));
delay_ms(10);
write_DS1307(0x1, decToBcd(minute));
delay_ms(10);
write_DS1307(0x2, decToBcd(hour));
delay_ms(10);
write_DS1307(0x3, decToBcd(dayOfWeek));
delay_ms(10);
write_DS1307(0x4, decToBcd(dayOfMonth));
delay_ms(10);
write_DS1307(0x5, decToBcd(month));
delay_ms(10);
write_DS1307(0x6, decToBcd(year));
}
//***********************************
void display_lcd() {
LCD_putcmd(0x80);
Printf(LCD_putchar,"Time: ");
LCD_putcmd(0xC0);
Printf(LCD_putchar,"Date:");
//*******************************************
val_sec1 = bcdToDec1(read_DS1307(0x00)); //So giay hang chuc
val_sec2 = bcdToDec2(read_DS1307(0x00)); //So giay hang don vi

val_min1 = bcdToDec1(read_DS1307(0x01));
val_min2 = bcdToDec2(read_DS1307(0x01));

val_hou1 = bcdToDec1(read_DS1307(0x02));
val_hou2 = bcdToDec2(read_DS1307(0x02));

val_dat1 = bcdToDec1(read_DS1307(0x04));
val_dat2 = bcdToDec2(read_DS1307(0x04));

val_mon1 = bcdToDec1(read_DS1307(0x05));
val_mon2 = bcdToDec2(read_DS1307(0x05));

val_yea1 = bcdToDec1(read_DS1307(0x06));
val_yea2 = bcdToDec2(read_DS1307(0x06));
//*******************************************
//In lan luot cac so ra LCD
LCD_putcmd(0x8E);
Printf(LCD_putchar,"%u",val_sec1);
LCD_putcmd(0x8F);
Printf(LCD_putchar,"%u",val_sec2);

LCD_putcmd(0x8A);
Printf(LCD_putchar,"%u:",val_min1);
LCD_putcmd(0x8B);
Printf(LCD_putchar,"%u:",val_min2);

LCD_putcmd(0x86);
Printf(LCD_putchar,"%u:",val_hou1);
LCD_putcmd(0x87);
Printf(LCD_putchar,"%u:",val_hou2);

LCD_putcmd(0xC6);
Printf(LCD_putchar,"%u/",val_dat1);
LCD_putcmd(0xC7);
Printf(LCD_putchar,"%u/",val_dat2);

LCD_putcmd(0xCA);
Printf(LCD_putchar,"%u/",val_mon1);
LCD_putcmd(0xCB);
Printf(LCD_putchar,"%u/",val_mon2);

LCD_putcmd(0xCE);
Printf(LCD_putchar,"%u",val_yea1);
LCD_putcmd(0xCF);
Printf(LCD_putchar,"%u",val_yea2);
}
//***********************************

void main()
{
set_tris_b (0x01);
set_tris_d (0x00);
output_b (0x00);
output_c (0x00);
output_d (0x00);
LCD_init(); //Khoi tao LCD
LCD_putcmd(0x80);
Printf(LCD_putchar,"Time: ");
LCD_putcmd(0xC0);
Printf(LCD_putchar,"Date:");
init_DS1307(); //Khoi tao DS1307
write_DS1307(0x07, 0x90); //Cau hinh thanh ghi cua DS1307
setDateDs1307(01, 02, 03, 04, 05, 06, 07); //Vi du Time: 03:02:01 Date: 05:06:07
enable_interrupts(GLOBAL);
enable_interrupts(INT_ext);
while (1)
{
}
}
//************************************************** **
////////////////////////////////////////////////////////////////////////////////
//************************************************** **

Mình cũng đang làm về cái đồng hồ số này nhưng làm ko chạy, thời gian trên con ds1307 vẫn chạy bình thường nhưng khi hiển thị ra LCD thì nó chạy đc 5s rồi đứng yên, bạn có thể post cái mô phỏng và code cho mình tham khảo với, post cái thư viện #include <lcd_lib_4bit.c> luon nha. hoặc bạn gửi vào mail cho mình bnktunganh@gmail.com, thanks.

babybaby002
05-12-2010, 08:04 PM
mình đang làm về đồng hồ số đo thời gian dùng ds1307 hiển thị lên LCD ,mình viet code hoài mà vẫn chạy sai,mình viết 6 đoạn code và built ra 6 file hex, mà không file hex nào chạy hoàn chỉnh cả, mình có post protues và 6 file code lên, các bạn xem dùm mình và chỉnh sửa dùm mình với nhá, thanks các bạn nhiều lắm.

babybaby002
06-12-2010, 03:48 PM
sau 2 đêm cặm cụi sửa chữa, mình đã sửa 6 code thành còn 2 code gần như hoàn chỉnh nhưng vẫn chưa gọi là hoàn chỉnh đúng nhất, vì thời gian chạy được khoảng mấy phút là đứng không hiển thị tiếp ra LCD nữa, ở đây mình có 2 code dùng 2 thư viện LCD khác nhau và trong mỗi code có 2 cách chuyển dữ liệu sang BCD, các bạn xem và chỉnh sửa code sao cho chạy đúng nhất nhé, các bạn có thể post lên đây hoặc gửi vào mail bnktunganh@gmail.com cho mình, cảm ơn các bạn đã giúp đỡ.

babybaby002
10-12-2010, 12:17 AM
mấy bài trước mình post, mình dùng proteus 7.7 và bị lỗi nên time và day nó nhảy loạn xạ, sau khi mình vẽ lại bằng proteus 7.1 thì time và day ổn nhưng biến giây đếm trên ds1307 chậm mất 3 nhịp, khi giây ở đồng hồ thật bên ngoài nhảy được 3s thì con ds mới nhảy được 1s, mình post code và proteus lên đây, bạn nào xem dùm mình phải chỉnh sửa code như thế nào cho giây của con ds nó chạy đúng nha. thanks.

vimotnguoi_5891
05-07-2012, 07:56 PM
Mình đang làm đề tài về con ds1307 code chạy rồi nhưng khi làm mạch nó cứ hiện ra số gì gì ấy? Ai giúp mình với!!!!!

hatuan296
06-07-2012, 01:22 AM
Mình đang làm đề tài về con ds1307 code chạy rồi nhưng khi làm mạch nó cứ hiện ra số gì gì ấy? Ai giúp mình với!!!!!

Mình mở không được bạn à . Mình đang dùng proteus 7.7 sp2 . Mở file nào cũng không thấy linh kiện hết , trang trống trơn .

vimotnguoi_5891
06-07-2012, 08:41 AM
Mình mở không được bạn à . Mình đang dùng proteus 7.7 sp2 . Mở file nào cũng không thấy linh kiện hết , trang trống trơn .

Test lại rồi. mở được mà.! mô phỏng thì được chỉ có lúc làm mạch thật thí nó chay bị lổi thôi..!! không load được dữ liệu từ khối ds1307..! thử đủ cách rồi mà chịu .!!! dùng proteus thì mở được mà ko cần cùng bản mới mở được đâu !

vanngh
15-04-2013, 11:44 AM
Test lại rồi. mở được mà.! mô phỏng thì được chỉ có lúc làm mạch thật thí nó chay bị lổi thôi..!! không load được dữ liệu từ khối ds1307..! thử đủ cách rồi mà chịu .!!! dùng proteus thì mở được mà ko cần cùng bản mới mở được đâu !

Bạn xem lại mức điện áp tín hiệu giữa Pic và DS1307