- Vật liệu thiết yếu:
- Mô-đun RTC:
- Kết nối DS3231 RTC với Vi điều khiển PIC:
- Lập trình PIC cho Mô-đun RTC:
- Giải thích ngắn gọn về tệp tiêu đề PIC16F877a_DS3231.h:
- Mô phỏng:
- Hiển thị ngày và giờ trên màn hình LCD:
Hầu hết tất cả các thiết bị nhúng đều được thiết kế để tương tác với thế giới thực. Chúng đóng vai trò là cầu nối giao tiếp giữa thế giới số và thế giới thực. Để làm cho quá trình này dễ dàng và hiệu quả hơn, thế giới kỹ thuật số đôi khi cần theo dõi ngày giờ của thế giới thực. Bằng cách này, thế giới kỹ thuật số sẽ biết được thời gian / ngày trong thế giới thực và thậm chí có thể phân biệt giữa thời gian ban ngày hay ban đêm. Nó cũng có thể hoạt động như một nguồn thời gian để thực hiện các nhiệm vụ nhất định vào một thời điểm hoặc ngày cụ thể. Vì vậy, ở đây chúng tôi đang giao tiếp mô-đun RTC với Vi điều khiển PIC và hiển thị ngày và giờ trên màn hình LCD 16x2. Dự án này cũng có thể được sử dụng làm Đồng hồ kỹ thuật số.
Vật liệu thiết yếu:
- Nguồn cung cấp 5V quy định
- PIC16F877A
- Bộ dao động tinh thể 20Mhz
- Tụ 33pf - 2Nos
- Điện trở 10K, 5.1K, 1K
- Mô-đun RTC DS3231
- POT -10k
- Mô-đun LCD 16 * 2
- Kết nối dây
Mô-đun RTC:
Cách phổ biến nhất để bộ vi điều khiển theo dõi ngày hoặc giờ trong thế giới thực là sử dụng IC RTC. Thuật ngữ RTC là viết tắt của Real Time Clock; IC này theo dõi ngày và giờ trong thế giới thực và sẽ chia sẻ thông tin này với bộ vi điều khiển bất cứ khi nào được yêu cầu. IC RTC mà chúng tôi đang sử dụng ở đây là DS3231 phổ biến và chính xác nhất. IC này chỉ trôi đi vài giây mỗi năm và do đó có độ tin cậy cao. Vì lợi ích của hướng dẫn này, chúng tôi đang sử dụng mô-đun DS3231 RTC có thể dễ dàng mua trực tuyến hoặc từ cửa hàng phần cứng địa phương. Mô-đun đi kèm với một ô đồng xu 3V luôn cung cấp năng lượng cho mô-đun RTC và do đó khi ngày giờ được thiết lập, nó sẽ được cập nhật miễn là ô đồng xu còn sống.
Mô-đun DS3231 giao tiếp với sự trợ giúp của giao thức I2C, vì vậy nếu bạn không biết nó là gì và nó được sử dụng như thế nào với PIC, hãy đọc hướng dẫn I2C với PIC trước khi tiếp tục. Cũng trong hướng dẫn này, chúng tôi sẽ tạo một tệp tiêu đề có thể được sử dụng để giao tiếp với mô-đun RTC của chúng tôi và cũng kiểm tra tương tự trên phần cứng bằng cách hiển thị ngày và giờ trên màn hình LCD, vì vậy điều quan trọng là phải tìm hiểu cách giao diện LCD hiển thị bằng vi điều khiển PIC. Tệp tiêu đề được tạo trong hướng dẫn này cho DS3231 sau đó có thể được sử dụng / sửa đổi cho phù hợp với các ứng dụng của bạn.
Trước đây chúng tôi đã sử dụng DS3231 RTC với Arduino trong các dự án dưới đây:
- Bộ nạp vật nuôi tự động sử dụng Arduino
- Bộ ghi dữ liệu Arduino
Kết nối DS3231 RTC với Vi điều khiển PIC:
Sơ đồ mạch cho Đồng hồ kỹ thuật số dựa trên vi điều khiển PIC được đưa ra dưới đây. Như đã nói trước đó, DS3231 hoạt động với sự trợ giúp của giao tiếp I2C vì vậy nó sẽ có Đồng hồ nối tiếp (SCL) và chân Dữ liệu nối tiếp (SDA) phải được kết nối với các chân I2C trên PIC của chúng tôi, đó là chân 18 (SCL) và chân 23 (SDA). Một điện trở kéo lên có giá trị 4,7k được sử dụng để giữ cho bus ở trạng thái cao khi không tải.
Màn hình LCD cũng được kết nối với các chân trên Cổng D để hiển thị ngày và giờ hiện tại. Sơ đồ mạch hoàn chỉnh được thiết kế trên proteus và được hiển thị bên dưới. Chúng tôi sẽ sử dụng cùng một để mô phỏng hoặc lập trình ở phần sau của hướng dẫn này.
Thực hiện theo sơ đồ mạch và thực hiện các kết nối cho phù hợp, hộp I2C hiển thị ở trên được sử dụng để gỡ lỗi I2C nên chúng tôi sẽ không đưa nó vào các kết nối của mình. Ngoài ra, nó không cho thấy rằng mô-đun RTC phải được cấp nguồn bằng nguồn + 5V bằng cách sử dụng các chân Vcc và Nối đất trên mô-đun. Tôi đã sử dụng breadboard của mình để tạo kết nối và sau khi thực hiện các kết nối cần thiết, thiết lập của tôi trông giống như sau.
Nếu bạn chưa quen với Vi điều khiển PIC thì hãy bắt đầu với Bắt đầu với Vi điều khiển PIC.
Lập trình PIC cho Mô-đun RTC:
Các chương trình hoàn chỉnh cho đồng hồ kỹ thuật số này có thể được tải về từ các tập tin ZIP đây. Chương trình bao gồm ba tệp tiêu đề hoàn toàn. Chúng là tệp lcd.h để làm việc với màn hình LCD, tệp PIC16F877a_I2C.h để làm việc với giao tiếp I2C với PIC và cuối cùng là PIC16F877a_DS3231.h tệp để làm việc với các mô-đun RTC. Tất cả ba tệp tiêu đề là bắt buộc cho chương trình này và có sẵn trong tệp ZIP ở trên. Dưới đây, tôi sẽ giải thích chương trình chính sử dụng tất cả các tệp tiêu đề này để đọc ngày và giờ từ mô-đun RTC và hiển thị nó trên màn hình LCD. Sau đó, tôi sẽ giải thích những gì thực sự đang xảy ra bên trong tệp tiêu đề RTC. Như mọi khi, hãy bắt đầu chương trình bằng cách thiết lập các bit cấu hình và đặt tần số xung nhịp là 20MHz vì đó là những gì chúng tôi đã sử dụng trong phần cứng của mình.
#pragma config FOSC = HS // Các bit chọn bộ tạo dao động (bộ tạo dao động HS) #pragma config WDTE = OFF // Bit Enable Watchdog Timer (WDT đã bị vô hiệu hóa) #pragma config PWRTE = ON // Bit Bật bộ hẹn giờ bật nguồn (PWRT đã bật) # pragma config BOREN = ON // Brown-out Reset bit Enable bit (BOR enable) #pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming bit (RB3 là I / O kỹ thuật số, HV bật MCLR phải được sử dụng để lập trình) #pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off) #pragma config WRT = OFF // Flash Program Memory Write Enable bits (Ghi bảo vệ tắt; tất cả bộ nhớ chương trình có thể được ghi bởi EECON control) #pragma config CP = OFF // Bit bảo vệ mã bộ nhớ chương trình Flash (Tắt bảo vệ mã) #define _XTAL_FREQ 20000000
Bước tiếp theo sẽ là xác định các chân LCD, nếu bạn nhìn vào phần cứng, bạn có thể nhận thấy rằng chúng tôi đã kết nối các chân của LCD với PORT D từ RD2 đến RD7, vì vậy chúng tôi xác định giống như hình dưới đây.
#define RS RD2 #define EN RD3 #define D4 RD4 #define D5 RD5 #define D6 RD6 #define D7 RD7
Theo mặc định khi bạn mua mô-đun RTC, ngày và giờ chính xác sẽ không được đặt trong đó, vì vậy chúng tôi phải đặt nó thông qua chương trình của mình. Vì vậy, chúng tôi khai báo biến cho từng dữ liệu và nguồn cấp dữ liệu trong thời gian và ngày trong thế giới thực như hình dưới đây. Tại thời điểm tải lên chương trình ngày giờ của tôi là 10:55 sáng ngày 6-5-2018 nên tôi đã thiết lập các biến như bên dưới. Bạn có thể đặt ngày giờ chính xác theo ứng dụng thực tế của mình
/ * Đặt giá trị hiện tại của ngày và giờ bên dưới * / int sec = 00; int min = 55; int giờ = 10; int ngày = 06; int tháng = 05; int năm = 18; / * Thời gian và Ngày đặt * /
Tiếp theo, chúng tôi thêm tất cả các tệp tiêu đề mà chúng tôi đã thảo luận. Nếu bạn đã tải xuống và mở chương trình từ tệp ZIP thì sẽ không có vấn đề gì ngoài việc đảm bảo tất cả các tệp tiêu đề được thêm vào tệp nguồn hoặc thư mục dự án của bạn.
#include
Vì chúng ta đã sử dụng PORT D làm các chân đầu ra để giao tiếp với màn hình LCD, chúng tôi phải khai báo chúng là các chân đầu ra trong chương trình của chúng tôi và khởi tạo màn hình LCD như hình dưới đây
TRISD = 0x00; // Tạo các chân Port D làm outptu cho giao diện LCD Lcd_Start (); // Khởi tạo mô-đun LCD
Mô-đun RTC giao tiếp với sự trợ giúp của giao thức I2C vì vậy chúng ta phải kích hoạt giao tiếp I2C với bộ vi điều khiển PIC của chúng ta. Hầu hết các thiết bị bao gồm các mô-đun DS3231 của chúng tôi có tần số hoạt động I2C là 100KHz, vì vậy chúng tôi bắt đầu giao tiếp I2C với tần số 100KHz như hình dưới đây
I2C_Initialize (100); // Khởi tạo I2C Master với xung nhịp 100KHz
Ngay sau khi chúng tôi thiết lập giao tiếp I2C với mô-đun RTC, điều đầu tiên chúng tôi làm là đặt ngày giờ hiện tại mà chúng tôi đã nhập vào chương trình của mình. Điều này có thể được thực hiện bằng cách gọi hàm set_Time_Date như hình dưới đây. Khi ngày và giờ được đặt, mô-đun sẽ tự động theo dõi và tăng chúng giống như đồng hồ kỹ thuật số.
Set_Time_Date (); // đặt ngày giờ trên mô-đun RTC
Để chỉ ra rằng chương trình đã bắt đầu, chúng tôi sẽ hiển thị một thông báo giới thiệu nhỏ sẽ ở trên màn hình trong 2 giây. Thông báo này sẽ hiển thị RTC với PIC –Circuit Digest trên màn hình. Chương trình tương tự được hiển thị bên dưới
Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String ("RTC với PIC"); Lcd_Set_Cursor (2,1); Lcd_Print_String ("Thông báo mạch điện"); __delay_ms (1500);
Bên trong vòng lặp while vô hạn của chúng tôi, chúng tôi nên đọc ngày và giờ hiện tại và sau đó hiển thị các giá trị trên màn hình LCD của chúng tôi. Để đọc Thời gian và Ngày từ mô-đun RTC, có thể sử dụng hàm Update_Current_Time_Date như hình dưới đây. Hàm này sẽ đọc giá trị của mô-đun RTC và cập nhật các biến sec, min, giờ, ngày, tháng và năm với các giá trị hiện tại. Sau đó, chúng ta có thể sử dụng chúng cho mục đích của mình.
Update_Current_Date_Time (); // Đọc ngày và giờ hiện tại từ mô-đun RTC
Các biến có kiểu dữ liệu số nguyên, chúng ta phải chuyển đổi chúng thành các ký tự riêng lẻ để có thể hiển thị trên màn hình LCD. Vì vậy, chúng ta sử dụng toán tử môđun để lấy chữ số một lần và chia biến cho 10 để có chữ số hàng chục. Điều tương tự cũng được thực hiện cho tất cả các biến.
// Tách thành các char để hiển thị trên lcd char sec_0 = sec% 10; char sec_1 = (giây / 10); char min_0 = min% 10; char min_1 = min / 10; char giờ_0 = giờ% 10; char giờ_1 = giờ / 10; char date_0 = date% 10; char date_1 = date / 10; char tháng_0 = tháng% 10; char tháng_1 = tháng / 10; char year_0 = year% 10; char year_1 = year / 10;
Tất cả những gì còn lại cần làm là hiển thị thông tin mà chúng tôi có được trên màn hình LCD. Điều này có thể dễ dàng thực hiện với các chức năng của LCD mà chúng ta đã thảo luận trước đây trong hướng dẫn về LCD của chúng tôi. Vì vậy, mã hiển thị thời gian được đưa ra bên dưới, phương pháp tương tự cũng được sử dụng để hiển thị ngày. Độ trễ 500 ms được đưa ra sau khi hiển thị dữ liệu để nó hoạt động như một khoảng thời gian cập nhật.
Lcd_Clear (); Lcd_Set_Cursor (1,1); Lcd_Print_String ("TIME:"); Lcd_Print_Char (giờ_1 + '0'); Lcd_Print_Char (giờ_0 + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (min_1 + '0'); Lcd_Print_Char (min_0 + '0'); Lcd_Print_Char (':'); Lcd_Print_Char (giây_1 + '0'); Lcd_Print_Char (sec_0 + '0');
Giải thích ngắn gọn về tệp tiêu đề PIC16F877a_DS3231.h:
Mọi thứ được giải thích cho đến nay là đủ để sử dụng mô-đun DS3231 với PIC cho các dự án của riêng bạn, nhưng đối với những bộ óc tò mò ngoài kia muốn biết điều gì thực sự xảy ra bên trong tệp tiêu đề và dữ liệu thực sự được PIC nhận từ mô-đun RTC, chỉ đọc thêm.
Cách tốt nhất để giải quyết vấn đề này là đọc toàn bộ datasheet của DS3231. Để trình bày ngắn gọn những gì cần thiết, mô-đun hoạt động như một nô lệ cho PIC và địa chỉ của tất cả mô-đun DS3231 là D0. Vì vậy, ghi dữ liệu vào mô-đun, chúng ta phải chuyển địa chỉ D0 và để Đọc dữ liệu từ RTC, chúng ta phải chuyển địa chỉ D1. Nếu chúng ta chuyển địa chỉ ghi vào mô-đun RTC, chúng tôi chuẩn bị sẵn sàng để lấy dữ liệu từ PIC, do đó dữ liệu do PIC ghi sẽ được nhận và lưu trong mô-đun RTC. Tương tự, nếu chúng tôi gửi địa chỉ cho Readthì PIC sẽ sẵn sàng để đọc các giá trị từ RTC vì mô-đun RTC sẽ bắt đầu gửi tất cả dữ liệu mà nó có. Chuỗi bit cho cả D0 và D1 được hiển thị bên dưới từ biểu dữ liệu. Lưu ý địa chỉ 0b11010000 là viết tắt của D0 (Viết) và 0b11010001 là viết tắt của D01 (Đọc)
Khi PIC gửi địa chỉ D0 hoặc D1 để ghi hoặc đọc, dữ liệu sau sẽ được đọc hoặc ghi theo thứ tự. Thứ tự này được hiển thị trong bảng dưới đây. Vì vậy, dữ liệu đầu tiên sẽ là giây (00h) sau đó là phút (01h) sau đó là giờ (02h) tiếp theo là ngày (03h) và tối đa là MSB của nhiệt độ.
Mô-đun RTC không hiểu các giá trị Thập phân, nó chỉ giao tiếp thông qua các giá trị BCD. Vì vậy, trước khi ghi bất kỳ giá trị nào vào mô-đun RTC, nó nên được chuyển đổi sang BCD và các giá trị nhận được từ mô-đun RTC cũng sẽ ở định dạng BCD và nó phải được chuyển đổi thành Decimal để có ý nghĩa đối với chúng tôi. Với điều này, hãy tạo tất cả các chức năng cần thiết cho việc sử dụng mô-đun RTC.
Các hàm BCD_2_DEC và DEC_2_BCD:
Hai hàm đầu tiên sẽ được sử dụng để chuyển đổi dữ liệu BCD sang Decimal và dữ liệu Decimal sang BCD vì mô-đun RTC chỉ hiểu BCD. Các công thức để chuyển đổi BCD sang Decimal và BCD sang Decimal là
Decimal = (BCD >> 4) * 10 + (BCD & 0x0F) BCD = ((Decimal / 10) << 4) + (Decimal% 10)
Chúng ta chỉ cần sử dụng hai công thức này để tạo một hàm lấy đơn vị đối diện làm tham số và chuyển nó sang định dạng bắt buộc và trả về nó, hàm để làm tương tự được hiển thị bên dưới
int BCD_2_DEC (int to_convert) { return (to_convert >> 4) * 10 + (to_convert & 0x0F); } int DEC_2_BCD (int to_convert) { return ((to_convert / 10) << 4) + (to_convert% 10); }
Hàm Set_Time_Date ():
Hàm này sẽ ghi giá trị của thời gian và ngày tháng từ mô-đun PIC sang RTC. Các giá trị của ngày và giờ thực phải được người dùng cập nhật trong các biến sec, min, giờ, ngày, tháng và năm. Các giá trị này sau đó sẽ được chuyển đổi thành BCD và được ghi vào mô-đun RTC.
Như chúng ta đã thảo luận, để ghi một giá trị vào mô-đun RTC, chúng ta phải chuyển địa chỉ D0 và viết một bit tăng 0 để bắt đầu quá trình ghi. Sau đó, chúng ta có thể gửi dữ liệu theo thứ tự như trong bảng trên.
void Set_Time_Date () { I2C_Begin (); I2C_Write (0xD0); I2C_Write (0); I2C_Write (DEC_2_BCD (giây)); // cập nhật sec I2C_Write (DEC_2_BCD (min)); // cập nhật min I2C_Write (DEC_2_BCD (giờ)); // cập nhật giờ I2C_Write (1); // bỏ qua cập nhật ngày I2C_Write (DEC_2_BCD (date)); // cập nhật ngày I2C_Write (DEC_2_BCD (tháng)); // cập nhật tháng I2C_Write (DEC_2_BCD (năm)); // cập nhật năm I2C_End (); }
Hàm Update_Current_Date_Time ():
Chức năng cuối cùng trong thư viện là chức năng được sử dụng để đọc ngày và giờ từ mô-đun RTC và chuyển nó đến bộ vi điều khiển PIC. Hàm này được chia thành ba phân đoạn, một để bắt đầu quá trình đọc thứ hai để đọc các giá trị và lưu nó vào các biến toàn cục như sec, min, giờ, ngày, tháng và năm. Và thứ ba là công nhận rằng bài đọc đã thành công.
Lưu ý rằng đối với mỗi hành động, giao tiếp I2C phải được bắt đầu và kết thúc.
Để đọc các giá trị từ RTC, chúng ta phải gửi địa chỉ D0 theo sau là 0. Điều này sẽ làm cho mô-đun RTC gửi tất cả các giá trị mà nó có theo thứ tự được hiển thị trong bảng trên. Chúng ta chỉ có thể đọc chúng để chuyển đổi chúng thành Decimal và lưu nó vào các biến theo cùng thứ tự.
Cuối cùng, sau khi đọc xong, mô-đun RTC sẽ gửi một bit báo nhận, bit này cũng sẽ được đọc và nhận.
void Update_Current_Date_Time () { // BẮT ĐẦU đọc I2C_Begin (); I2C_Write (0xD0); I2C_Write (0); I2C_End (); // ĐỌC I2C_Begin (); I2C_Write (0xD1); // Khởi tạo đọc dữ liệu sec = BCD_2_DEC (I2C_Read (1)); min = BCD_2_DEC (I2C_Read (1)); giờ = BCD_2_DEC (I2C_Read (1)); I2C_Read (1); ngày = BCD_2_DEC (I2C_Read (1)); tháng = BCD_2_DEC (I2C_Read (1)); năm = BCD_2_DEC (I2C_Read (1)); I2C_End (); // KẾT THÚC Đọc I2C_Begin (); I2C_Write (0xD1); // Khởi tạo dữ liệu đọc I2C_Read (1); I2C_End (); }
Mô phỏng:
Dự án có thể được mô phỏng bằng phần mềm mô phỏng Proteus. Thực hiện các kết nối như được hiển thị trong sơ đồ mạch và tải tệp hex vào bộ điều khiển PIC. Khi bạn mô phỏng nó, bạn sẽ tìm thấy hai hộp bật lên và ngày và giờ hiển thị trên màn hình LCD như hình dưới đây.
Cửa sổ nhỏ ở trên cùng hiển thị thời gian và ngày tháng hiện tại bên trong mô-đun RTC và cửa sổ bật lên thứ hai là trình gỡ lỗi I2C. Nó là một công cụ tuyệt vời để kiểm tra dữ liệu nào đang thực sự được chuyển vào và gửi ra lỗi I2C.
Hiển thị ngày và giờ trên màn hình LCD:
Khi phần cứng của bạn đã sẵn sàng và mã được tải xuống dưới dạng tệp ZIP thông qua liên kết được cung cấp, hãy mở chương trình bằng MPLABX IDE. Trước tiên, bạn phải khởi chạy IDE và sử dụng tùy chọn dự án đang mở và duyệt nội dung bên trong tệp ZIP và mở thư mục.X.
Chỉ cần kiểm tra xem chương trình có đang biên dịch hay không và tải mã lên phần cứng của bạn bằng cách sử dụng PicKit3. Ngay sau khi chương trình được tải lên, bạn sẽ thấy thông báo giới thiệu và sau đó ngày và giờ sẽ được hiển thị như hình dưới đây.
Nếu không có gì trên màn hình LCD, hãy kiểm tra các kết nối của bạn và đảm bảo rằng mức độ tương phản được đặt chính xác bằng cách thay đổi chiết áp. Đó là cách bạn có thể hiển thị thời gian và ngày tháng cho tất cả các dự án vi điều khiển PIC của mình và có thể sử dụng nó làm Đồng hồ kỹ thuật số. Hy vọng bạn đã học được điều gì đó mới và thích học hướng dẫn này. Nếu bạn gặp phải bất kỳ vấn đề nào, hãy gửi chúng vào phần bình luận bên dưới hoặc trên diễn đàn để được trợ giúp kỹ thuật.
Tải xuống chương trình PIC hoàn chỉnh cho dự án này với các tệp tiêu đề từ đây và kiểm tra thêm tất cả các Hướng dẫn PIC của chúng tôi tại đây.