BÀI 11 : I2C VỚI IC DS1307 .
- CƠ SỞ LÝ THUYẾT.
- Có 2 tốc độ là 100Khz và 400khz.
- Có 2 mode sử dụng là mode master và mode slave.
- Có các cờ báo trạng thái và cờ báo lỗi.
- Có 3 chế độ ngắt là ngắt giao tiếp, ngắt khi có lỗi xảy ra, ngắt từ chế độ ngủ/nghỉ.
- Có các thanh ghi chứa giờ, phút, giây, thứ, ngày, tháng, năm và năm thừa.
- 56 byte, có thể lưu dữ data trong RAM nên không sợ bị mất data khi mất nguồn(chân Vbat phải được gắn pin).
- Giao tiếp I2C, có chế độ tự kiểm tra nguồn vào.
- Dòng tiêu thụ thấp.
- Sơ đồ kết nối.
- Chân VCC của DS1307 nối chân +5V của vi điều khiển.
- Chân GND của DS1307 nối chân GND của vi điều khiển.
- Chân SDA của DS1307 nối chân PB5 của vi điều khiển.
- Chân SCL của DS1307 nối chân PB4 của vi điều khiển.
- Cần có thạch anh ngoài và pin ở chân VBAT(chắc chắn là còn sử dụng được).
- Khi thiết kế cần có điện trở kéo nguồn ở 3 chân : SCL, SDA,OUT(nếu chân này sử dụng) nếu không sẽ không giao tiếp được - tham khảo thêm trong Datasheet.
- Địa chỉ của IC này là 0xD0. Khi cấp nguồn thì VCC > 1.25xVbat thì IC mới hoạt động VD : pin ở chân VBAT = 3v thì VCC > 3.75V.
- Kết nối trược tiếp SCL(PB4-VĐK) nối SCL(DS1307), SDA(PB5-VĐK) nối SDA(DS1307) – giao tiếp UART thì cần đấu chéo.
- Cấu hình dùng thư viện chuẩn của ST.
- Cấu hình chương trình con I2C với tốc độ chuẩn – nằm trong file ds1307.c.
- Cấu hình chương trình để set thời gian cho IC DS1307 – nằm trong file ds1307.c
- Chuyển đổi tất cả các data cần ghi sang số BCD vì thời gian được lưu trên các thanh ghi của DS1307 là giá trị số BCD.
- Chờ cho giao thức I2C trên IC được sẵn sang. MCU sẽ gửi tín hiệu để bắt đầu giao tiếp.
- MCU gửi địa chỉ để giao tiếp với IC DS1307 ở đây là 0xD0, và chờ các cờ thông báo, cờ trạng thái báo là đã truyền xong và không có lỗi xảy ra.
- MCU gửi địa chỉ bắt đầu để ghi giá trị: bắt đầu từ địa chỉ của thanh ghi giây(seconds = 0x00) và chờ cờ báo là đã ghi xong.
- MCU gửi giá trị giây cần set và chờ cờ báo đã gửi xong.
- Tiếp theo tương tự cho các giá trị set phút, giờ… cho đến hết giá trị cần ghi.
- MCU sẽ gửi tín hiệu thông báo là sẽ kết thúc ghi dữ liệu và xóa các cờ báo rỗi.
- Cấu hình chương trình con để đọc thời gian về – nằm trong file ds1307.c.
- Chờ cho giao thức I2C trên IC được sẵn sàng. MCU sẽ gửi tín hiệu để bắt đầu giao tiếp.
- MCU gửi địa chỉ để giao tiếp với IC DS1307 ở đây là 0xD0, và chờ các cờ thông báo, cờ trạng thái báo là đã truyền xong và không có lỗi xảy ra.
- MCU gửi địa chỉ của thanh ghi cần đọc giá trị và chờ chờ báo là đã xong.
- Bộ I2C của MCU restart và gửi tín hiệu bắt đầu mới và gửi địa chỉ của DS1307 = 0xD0 để bắt đầu quá trình đọc. Lúc này SDA sẽ là dữ liệu được trả về từ DS1307. Chương trình sẽ lưu lại giá trị thanh ghi giây.
- Các cờ sẽ được thiết lập lại để chuẩn bị cho lần đọc tiếp theo.
- Sau khi đọc được data trả về, thì ta data sẽ chuyển đổi từ BCD về nhị phân để hiển thị.
I2C – Inter- Intergrated Circuit là chuẩn truyền thông 2 dây gồm 1 dây Clock và 1 dây Data dùng chung cho quá trình truyền nhận được phát minh bởi Philips. Chuẩn I2C cũng trở nên thông dụng với nhiều module, IC sử dụng như :IC nhớ(24LCxxx), cảm biến góc nghiêng(MPU6050), module giao tiếp LCD(dùng IC PCF8574), IC thời gian thực(DS1307)… So với UART tốc độ của I2C có vẻ nhỉnh hơn 1 chút, ở mức thông thường là 100Khz. Ở các mode còn lại thì tốc độ cao hơn. Khi giao tiếp I2C với 1 IC nào đó cần chú ý : địa chỉ của Ic đó để giao tiếp, giao tiếp với tốc độ bao nhiêu, bao nhiêu bit.
Trên STM8S003F3P6 thì có 1 bộ giao tiếp I2C ở chân PB4,PB5. 2 chân này cũng được thiết kế đặc biệt chuyên dụng cho I2C nên khi output ở mức cao, Điện áp trên chân này đo được là =0V. Các tính năng chính của I2C trên STM8S003F3P6:
STM8S003F3P6 không có bộ thời gian thực(STM32 có bộ thời gian thực) nên chúng ta phải dùng thêm IC DS1307 để có được bộ thời gian thực. Một vài chức năng của DS1307:
SƠ ĐỒ KẾT NỐI:
LƯU Ý PHẦN CỨNG:
Thư viện này mình sưu tầm được trên mạng, đã test và chạy ổn đinh. Tóm tắt quá trình set thời gian cho IC DS1307 như sau:
Tóm tắt quá trình đọc dữ liệu trả về như sau:
Ở đây, mình dùng UART để hiển thị giá trị thời gian nên cần phải chuyển đổi về giá trị nhị phân. Bạn nào sử dụng LED 7 đoạn để hiển thị thời gian thì không cần chuyển đổi về số nhị phân, để nguyên số BCD. Các bạn cần include file ds1307.h vào file main để chương trình có thể gọi được các hàm thực thi trong file ds1307.c. Ví dụ mẫu mình đã để link ở dưới, các bạn có thể chỉnh sửa để hiểu thêm về I2C.
Chúc các bạn thành công.
một trong những blog việt hay nhất về STM8 và STM32. Rất bổ ích, anh có thể làm thêm một bài nữa về HC-06 (05) với STM8S003 thì quá tuyệt vì đây là chủ đề chưa ai làm.
ReplyDeleteCám ơn bạn, mình sẽ thu xếp thời gian và bổ sung thêm kiến thức để có nhiều vài viết mới có ích hơn. Hy vọng sẽ nhận được nhiều phản hổi của các bạn.
DeleteĐã làm thành công! Cảm ơn Anh(chị).
ReplyDeletecho em xin project đc ko ạ. thanhphongphan1997@gmail.com. thank a!!
Deleteanh ơi anh làm được mạch khống chế thời gian hiển thị led 7 thanh chưa cho em nguyên lí với dophucdat555@gmail.com
ReplyDeletecái file interup vecter e chạy nó lỗi ở trong đó là sao ạ
ReplyDeletechưng trình fchir chạy đến hàm DS1307_init(); là nó chết
ReplyDeleteChào bạn, bạn có thể kiểm tra lại xem phần cứng của mình xem còn bị thiếu ở chỗ nào k? Bạn có thể dùng chế độ debug để biết code bị stuck ở chỗ nào.
Deletechào a,e đang làm mà bị mắc 1 vài chỗ a có thể cho e xin mail e hỏi a 1 số vấn đề đc k a,e cảm ơn
Deletemail e.thaonv@beetinnovators.com
while(I2C_GetFlagStatus( I2C_FLAG_BUSBUSY)==SET);
ReplyDeletee làm nó cứ chết ở đây
Chào bạn, nếu chương trình bị đứng ở đây tức là phần cứng kết nối của bạn chưa hoạt động. Chương trình sẽ loop cho đến khi cờ BUSY được remove. Bạn kiểm tra phần cứng của mình xem còn gì thiếu sót(Pin ngoài cho IC, thạch anh, trở kéo lên của 2 chân I2C, địa chỉ giao tiếp I2C, chân SDA hoặc SCL đã nối đúng chiều..)
Deletemình không dùng 2 trở kéo ở 2 chân SCL và SDA đc k
ReplyDeleteChào bạn,
DeleteThông thường mình sẽ cần 2 chân điện trở kéo lên để xác định rõ mức logic khi không điều khiển, nếu phần cứng của bạn không hỗ trợ điện trở kéo lên thì bạn có thể cấu hình trên stm32 để sử dụng nội trở.