Bài 25: DS1307 - Thời gian thực RTC

Để có thể tương tác truyền nhận tín hiệu với arduino, không chỉ bằng input digital hoặc analog. Chúng ta còn nhiều dạng giao tiếp cho các mạch như thời gian thực, cảm biến góc nghiêng, LCD… Hôm nay, chúng ta thử nghiệm thực hành giao tiếp I2C với mạch thời gian thực DS1307 để hiểu rõ hơn về loại giao tiếp này.


Giao tiếp I2C

I²C (viết tắt của từ tiếng Anh "Inter-Integrated Circuit") là một loại bus nối tiếp được phát triển bởi hãng sản xuất linh kiện điện tử Philips.

I²C sử dụng hai đường truyền tín hiệu: một đường xung nhịp đồng hồ (SCL) và một đường dữ liệu (SDA). SCL và SDA luôn được kéo lên nguồn bằng một điện trở kéo lên có giá trị xấp xỉ 4,7 KOhm. Các chế độ hoạt động của I²C bao gồm:

•             Chế độ chuẩn (standard mode) hoạt động ở tốc độ 100 Kbit/s.

•             Chế độ tốc độ thấp (low-speed mode) hoạt động ở tốc độ 10 Kbit/s.

Tần số xung nhịp đồng hồ có thể xuống 0 Hz. I²C sử dụng 7 bit để định địa chỉ, do đó trên một bus có thể định địa chỉ tới 112 nút, 16 địa chỉ còn lại được sử dụng vào mục đích riêng. Điểm mạnh của I²C chính là hiệu suất và sự đơn giản của nó: một khối điều khiển trung tâm có thể điều khiển cả một mạng thiết bị mà chỉ cần hai lối ra điều khiển. Ban đầu, loại bus này chỉ được dùng trong các linh kiện điện tử của Philips. Sau đó, do tính ưu việt và đơn giản của nó, I²C đã được chuẩn hóa và được dùng rộng rãi trong các module truyền thông nối tiếp của vi mạch tích hợp ngày nay. Vì Arduino đã có hỗ trợ sẵn điện trở kéo lên nên các bạn chỉ cần kết nối vào cách chân SDA và SCL

Có thể bắt gặp những module sử dụng giao tiếp I2C như LCD, DS1307, MPU6050… Như các bạn có thể thấy thì trong hình Arduino có SDA SCL tại chân A4/A5 và kế AREF cũng có 2 chân.

I2C scanner code

I2C scanner là một đoạn code của Arduino IDE để quét các địa chỉ của module dùng I2C đang được kết nối với Arduino. Vì I2C có thể sử dụng được cho nhiều module nên chúng ta cần gọi đúng địa chỉ để có thể đọc và ghi cho module đó. Dưới đây là code của I2C Scanner:

Sau khi mình lắp mạch gồm LCD1206, DS1307 thì Serial monitor sẽ hiển thị địa chỉ như sau:

 

Real-time Clock (RTC)

Trong các loại mainboard thường sẽ có mạch RTC hay còn gọi là mạch thời gian thực dùng để lưu trữ thời gian. Mạch sử dụng 1 viên pin CMOS có thể sử dụng đến 10 năm để chạy thời gian khi máy đã tắt nguồn. (Mình chưa test vụ 10 năm nha :> chỉ là trên lí thuyết). Trong bài này, chúng ta sử dụng mạch DS1307 để đọc và ghi thời gian lên Serial.

Hình ảnh DS1307

Chuẩn bị

  • Arduino Uno
  • RTC DS1307
  • Breadboard
  • Dây cắm breadboard

Lắp mạch

Vì DS1307 sử dụng giao tiếp I2C nên chúng ta sẽ lắp mạch như sau:

Thư viện

Để có thể sử dụng giao tiếp I2C, chúng ta dùng thư viện Wire.h và không cần cài đặt vì đã có sẵn trong Arduino IDE

Lập trình

Để thay đổi thời gian các bạn vào Serial monitor lần lượt gõ theo thứ tự là Giờ/ phút/ giây/ ngày trong tuần/ ngày/ tháng/ năm các nhau bởi dấu cách

Ví dụ: "15 24 30 2 6 7 18" có nghĩa là 15:24:30 thứ 2 ngày 6 tháng 7 năm 2018

Kết quả

Giải thích

  • String.indexOf(char)

Để lấy vị trí của kí tự char trong một String

  • String.substring(start,end)

Lấy giá trị của chuỗi con trong string từ start đến end

  • String.toInt()

Biến đổi từ String sang Int

  • bcd2dec và dec2bcd

Vì giao tiếp với I2C chúng ta cần đúng kiểu dữ liệu nên cần phải chuyển đổi giữa các cơ số, trong code đã chú thích rõ.

  • Wire.begin()

Khai báo giao tiếp cho I2C, với một số thư viện đã có tích hợp sẵn thì có thể khỏi cần khai báo

  • Wire.beginTransmission(address)

Mở giao tiếp tới địa chỉ address I2C

  • Wire.endTransmission(address)

Tương tự với mở thì mình sẽ có ngắt giao tiếp tới địa chỉ address

  • Wire.write(byte)

Dùng để ghi vào thanh ghi của module

  • Wire.read()

Dùng để đọc giá trị từ thanh ghi

  • Wire.requestFrom(address, number of byte request)

Yêu cần số byte (number of byte request) từ địa chỉ address của module

Chúc các bạn may mắn và thành công !!!

Có thể bạn quan tâm ???