Trong dự án này, chúng tôi sẽ chứng minh việc tạo một Đồng hồ RTC bằng vi điều khiển 8051. Nếu bạn muốn thực hiện dự án này với Arduino, hãy kiểm tra đồng hồ kỹ thuật số này bằng Arduino. Thành phần chính của dự án này là DS1307 là một vi mạch đồng hồ kỹ thuật số thời gian thực. Hãy biết chi tiết về vi mạch này.
RTC DS1307:
Đồng hồ thời gian thực nối tiếp DS1307 (RTC) là đồng hồ / lịch thập phân mã nhị phân (BCD) công suất thấp, đầy đủ cộng với 56 byte NV SRAM. Chip này hoạt động trên giao thức I²C. Đồng hồ / lịch cung cấp thông tin giây, phút, giờ, thứ, ngày, tháng và năm. Ngày cuối tháng được tự động điều chỉnh cho các tháng có ít hơn 31 ngày, bao gồm các điều chỉnh cho năm nhuận. Đồng hồ hoạt động ở định dạng 24 giờ hoặc 12 giờ với chỉ báo AM / PM. DS1307 được tích hợp một mạch cảm biến nguồn giúp phát hiện sự cố mất điện và tự động chuyển sang nguồn dự phòng. Hoạt động chấm công tiếp tục trong khi bộ phận hoạt động từ nguồn dự phòng. Chip DS1307 có thể chạy liên tục đến 10 năm.
Đồng hồ thời gian thực dựa trên 8051 là đồng hồ kỹ thuật số để hiển thị thời gian thực bằng cách sử dụng RTC DS1307, hoạt động trên giao thức I2C. Đồng hồ thời gian thực có nghĩa là nó chạy ngay cả sau khi mất điện. Khi nguồn điện được kết nối lại, nó sẽ hiển thị thời gian thực bất kể thời gian và khoảng thời gian nó ở trạng thái tắt. Trong dự án này, chúng tôi đã sử dụng mô-đun LCD 16x2 để hiển thị thời gian ở định dạng - (giờ, phút, giây, ngày, tháng và năm). Đồng hồ thời gian thực thường được sử dụng trong máy tính, nhà ở, văn phòng và thiết bị điện tử để cập nhật chúng theo thời gian thực.
Giao thức I2C là một phương pháp để kết nối hai hoặc nhiều thiết bị sử dụng hai dây vào một hệ thống duy nhất, và vì vậy giao thức này còn được gọi là giao thức hai dây. Nó có thể được sử dụng để giao tiếp 127 thiết bị với một thiết bị hoặc bộ xử lý. Hầu hết các thiết bị I2C chạy trên tần số 100Khz.
Các bước để ghi dữ liệu từ chủ đến tớ (chế độ nhận tớ)
- Gửi điều kiện START cho nô lệ.
- Gửi địa chỉ nô lệ cho nô lệ.
- Gửi bit ghi (0) tới slave.
- Đã nhận bit ACK từ nô lệ
- Gửi địa chỉ từ cho nô lệ.
- Đã nhận bit ACK từ nô lệ
- Gửi dữ liệu đến nô lệ.
- Đã nhận bit ACK từ nô lệ.
- Và cuối cùng gửi điều kiện STOP cho nô lệ.
Các bước đọc dữ liệu từ phụ đến chủ (chế độ truyền phụ)
- Gửi điều kiện START cho nô lệ.
- Gửi địa chỉ nô lệ cho nô lệ.
- Gửi bit đã đọc (1) tới slave.
- Đã nhận bit ACK từ nô lệ
- Đã nhận dữ liệu từ nô lệ
- Đã nhận bit ACK từ nô lệ.
- Gửi điều kiện STOP đến nô lệ.
Sơ đồ mạch và mô tả
Trong mạch chúng tôi đã sử dụng hầu hết 3 linh kiện DS1307, AT89S52 và LCD. Ở đây AT89S52 dùng để đọc thời gian từ DS1307 và hiển thị trên màn hình LCD 16x2. DS1307 gửi ngày / giờ sử dụng 2 dòng đến bộ vi điều khiển.
Các kết nối mạch rất đơn giản để hiểu và được thể hiện trong sơ đồ trên. Chân chip DS1307 SDA và SCL được kết nối với chân P2.1 và P2.0 của vi điều khiển 89S52 với điện trở kéo lên giữ giá trị mặc định CAO tại các đường dữ liệu và xung nhịp. Và một bộ dao động tinh thể 32,768KHz được kết nối với DS1307chip để tạo ra độ trễ chính xác 1 giây. Và một pin 3 volt cũng được kết nối với pin 3 rd (BAT) của DS1307 để giữ thời gian chạy sau khi mất điện. LCD 16x2 được kết nối với 8051 ở chế độ 4 bit. Chân điều khiển RS, RW và En được kết nối trực tiếp với 89S52 chân P1.0, GND và P1.1. Và chân dữ liệu D0-D7 được kết nối với P1.4-P1.7 của 89S52.
Ba nút là SET, INC / CHANGE và Next được sử dụng để cài đặt thời gian đồng hồ cho chân P2.4, P2.3 và P2.2 của 89S52 (hoạt động ở mức thấp). Khi chúng ta nhấn SET, chế độ đặt thời gian sẽ kích hoạt và bây giờ chúng ta cần đặt thời gian bằng cách sử dụng nút INC / CHANGE và nút Tiếp theo được sử dụng để chuyển sang chữ số. Sau khi cài đặt đồng hồ thời gian chạy liên tục.
Mô tả chương trình
Trong mã, chúng tôi đã bao gồm thư viện họ 8051 và một thư viện đầu ra đầu vào tiêu chuẩn. Và xác định các chân mà chúng tôi đã sử dụng, và lấy một số biến để tính toán.
#include
Và chức năng đã cho được sử dụng cho LCD lái xe.
void daten () {rs = 1; vi = 1; trì hoãn (1); vi = 0; } void lcddata (unsigned char ch) {lcdport = ch & 0xf0; daten (); lcdport = (ch << 4) & 0xf0; daten (); } void cmden (void) {rs = 0; vi = 1; trì hoãn (1); vi = 0; } void lcdcmd (unsigned char ch)
Chức năng này được sử dụng để khởi tạo RTC và đọc thời gian và ngày tháng từ IC RTC.
I2CStart (); I2CSend (0xD0); I2CSend (0x00); I2CStart (); I2CSend (0xD1); sec = BCDToDecimal (I2CRead (1)); min = BCDToDecimal (I2CRead (1)); giờ = BCDToDecimal (I2CRead (1)); day1 = BCDToDecimal (I2CRead (1)); date = BCDToDecimal (I2CRead (1)); mon = BCDToDecimal (I2CRead (1)); năm = BCDToDecimal (I2CRead (1)); I2CStop (); show_time (); // hiển thị time / date / day delay (1);
Các hàm này được sử dụng để chuyển đổi thập phân sang BCD và BCD sang thập phân.
int BCDToDecimal (char bcdByte) {char a, b, dec; a = (((bcdByte & 0xF0) >> 4) * 10); b = (bcdByte & 0x0F); dec = a + b; trả về tháng mười hai; } char DecimalToBCD (int decimalByte) {char a, b, bcd; a = ((decimalByte / 10) << 4); b = (decimalByte% 10); bcd = ab; trả về bcd; }
Các chức năng dưới đây được sử dụng cho Giao tiếp I2C.
void I2CStart () {SDA = 1; SCL = 1, SDA = 0, SCL = 0;} // hàm "start" để giao tiếp với ds1307 RTC void I2CStop () {SDA = 0, SCL = 1, SDA = 1; } // hàm "dừng" để giao tiếp với ds1307 RTC unsigned char I2CSend (unsigned char Data) // gửi dữ liệu đến ds1307 {char i; char ack_bit; for (i = 0; i <8; i ++) {if (Dữ liệu & 0x80) SDA = 1; khác SDA = 0; SCL = 1; Dữ liệu << = 1; SCL = 0; } SDA = 1, SCL = 1; ack_bit = SDA; SCL = 0; trả về ack_bit; } unsigned char I2CRead (char ack) // nhận dữ liệu từ ds1307 {unsigned char i, Data = 0; SDA = 1; for (i = 0; i <8; i ++) {Dữ liệu << = 1; do {SCL = 1;} while (SCL == 0); if (SDA) Dữ liệu- = 1; SCL = 0; } nếu (ack) SDA = 0; khác SDA = 1; SCL = 1; SCL = 0; SDA = 1; trả về dữ liệu; }
Hàm set_time được sử dụng để thiết lập thời gian trong đồng hồ và hàm show_time bên dưới được sử dụng để hiển thị thời gian trên màn hình LCD.
void show_time () // hàm hiển thị giờ / ngày / tháng trên LCD {char var; lcdcmd (0x80); lcdprint ("Ngày:"); sprintf (var, "% d", ngày tháng); lcdprint (var); sprintf (var, "/% d", mon); lcdprint (var); sprintf (var, "/% d", năm + 2000); lcdprint (var); lcdprint (""); lcdcmd (0xc0); lcdprint ("Thời gian:"); sprintf (var, "% d", giờ); lcdprint (var); sprintf (var, ":% d", min); lcdprint (var); sprintf (var, ":% d", sec); lcdprint (var); lcdprint (""); // day (day1); lcdprint (""); }