Trong khuôn khổ đồ án VĐK chúng em xin giới thiệu đồng hồ thời gian thực sử dụng PIC86F877A và IC DS1307 Trong quá trình thực hiện do trình độ hiểu biết còn hạn chế, nên có nhiều sai
Trang 1LỜI MỞ ĐẦU
Vi điều khiển có rất nhiều ứng dụng trong thực tế, từ những ứng dụng đơn giản chỉ
có vài thiết bị ngoại vi cho đến những hệ thống điều khiển phức tạp Trong khuôn khổ đồ
án VĐK chúng em xin giới thiệu đồng hồ thời gian thực sử dụng PIC86F877A và IC
DS1307
Trong quá trình thực hiện do trình độ hiểu biết còn hạn chế, nên có nhiều sai sót mong
thầy và các bạn góp ý bổ sung để có thể hoàn thiện hơn nữa
Chúng em xin chân thành cảm ơn thầy Nguyễn Danh Ngọc đã tận tình hướng dẫn,
đóng gớp ý kiến, kinh nghiệm và tạo điều kiện thuận lợi để hoàn thành tốt đề tài này
SV thực hiện:
Nguyễn Hữu Thọ Đinh Văn Tấn
Trang 22
LỜI MỞ ĐẦU 1
Chương I: TỔNG QUAN VỀ ĐỀ TÀI 3
1.1 Đặt vấn đề: 3
1.2 Giải quyết vấn đề: 3
Chương II: THIẾT KẾ HỆ THỐNG 4
2.1 Sơ đồ khối: 4
2.2 Sơ đồ mạch: 5
2.3 Linh kiện trong mạch: 6
2.4 Lưu đồ thuật toán: 15
Chương III: KẾT LUẬN 16
3.1 Kết quả: 16
3.2 Hướng phát triển đề tài: 17
PHỤ LỤC 18
Trang 3Chương I: TỔNG QUAN VỀ ĐỀ TÀI 1.1 Đặt vấn đề:
Với sự phát triển của xã hội, khoa học kĩ thuật nói chung và vi điều khiển PIC nói riêng ngày càng được ứng dụng ở hầu hết các lĩnh vực Một trong số những biến thể phổ biến của PIC là 16F877A Việc tìm hiểu và ứng dụng hết khả năng của nhiều loại PIC là
cả một quá trình dài lý thú và hữu ích, vì sự thuận tiện, khả năng phát triển cũng như sự
đa dạng các dòng sản phẩm phù hợp nhiều quy mô ứng dụng của nó
Đồng hồ thời gian thực là 1 sản phẩm đơn giản ứng dụng vi điều khiển PIC, giúp sinh viên tìm hiểu, nghiên cứu về lập trình PIC cơ bản và thiết kế, làm mạch thực tế
1.2 Giải quyết vấn đề:
Thiết kế đồng hồ thời gian thực hiển thị trên led 7 đoạn sử dụng
PIC16F877A, với yêu cầu đảm bảo về:
− Tính thực thi cao, có khả năng phát triển
− Chất lượng, độ chính xác cao, làm việc lâu dài, bền bỉ
− Tiết kiệm chi phí, linh kiện dễ kiếm dễ sử dụng và dễ dàng thay thế
khi xảy ra sự cố
− Có thể sử dụng riêng (đồng hồ vạn niên xem giờ, ngày tháng năm) hay
có thể sử dụng chung (lắp vào các hệ thống mẹ)
Từ các yêu cầu trên chúng ta chọn phương án thực hiện như sau:
- Sử dụng LED 7 đoạn để hiển thị vì giá thành rẻ, dễ sử dụng
- Sử dụng IC thời gian thực DS1307 IC này có tác dụng tạo ra thời gian
thực tương đối chính xác, bao gồm giờ, phút, giây, thứ, ngày, tháng, năm
- Sử dụng IC ghi dịch 74HC595 để tăng số lượng chân điều khiển cho
vi điều khiển
Trang 44
2.1 Sơ đồ khối:
Hình 2.1 Sơ đồ khối của hệ thống
- Khối nguồn: Sử dụng IC7805 tạo nguồn 5V cung cấp cho VĐK và các khối khác
- Khối hiển thị: Hiển thị thời gian và nhiệt độ Sử dụng LED 7 đoạn anode chung
- Khối điều khiển: Có chức năng chỉnh sửa thời gian và hẹn giờ
Gồm 4 nút ấn:
Mode: Thay đổi biến điều kiện chỉnh thời gian, hẹn giờ
Up: Tăng giá trị cần điều chỉnh +1
Down: Giảm giá trị cần điều chỉnh –1
Select: Hoàn tất chỉnh sửa hoặc để hẹn giờ
- Khối tạo thời gian thực: Cung cấp thời gian thực, sử dụng IC DS1307 thông qua giao tiếp I2C
- Cảm biến nhiệt độ: Sử dụng LM35 cung cấp giá trị tương tự tương ứng với mức nhiệt độ
Cảm biến nhiệt độ
Khối điều khiển trung tâm
Trang 52.2 Sơ đồ mạch:
Hình 2.2 Sơ đồ toàn mạch
Trang 72.3.2 DS1307
DS1307 là chip đồng hồ thời gian thực (RTC: Real-time clock), có thể đếm thời gian giờ, phút, giây, thứ, ngày, tháng, năm DS1307 được đọc và ghi thông qua giao diện nối tiếp I2C nên cấu tạo bên ngoài rất đơn giản
Hình 2.4 IC DS1307 và sơ đồ chân
Các chân của DS1307 được mô tả như sau:
- X1và X2: là 2 ngõ kết nối với 1 thạch anh 32.768 kHz làm nguồn tạo dao động
- VBAT: cực dương của nguồn pin 3V nuôi chip
- GND: chân mass chung cho cả pin 3V và Vcc
- Vcc: nguồn cho giao diện I2C, thường là 5V dùng chung với vi điều khiển Chú ý
là nếu Vcc không được cấp nguồn nhưng VBAT được cấp thì DS1307 vẫn đang hoạt động (nhưng không ghi và đọc được)
- SQW/OUT: (Square Wave / Output Driver), một ngõ phụ tạo xung vuông, tần số xung có thể được lập trình
- SCL và SDA: là 2 đường tạo xung nhịp và dữ liệu của giao diện I2C
✓ Có thể kết nối DS1307 bằng 1 mạch điện đơn giản
SDA
X1
X2
VBATGND
Trang 88
❖ Cấu tạo bên trong DS1307: mạch nguồn, mạch dao động, mạch điều khiển logic, mạch dao diện I2C, con trỏ địa chỉ và các thanh ghi (RAM)
Sử dụng DS1307 chủ yếu là ghi và đọc các thanh ghi của chip này Do đó cần hiểu rõ
2 vấn đề chính là cấu trúc các thanh ghi và cách truy xuất các thanh ghi này thông qua dao diện I2C
SDA
X1
X2
VBATGND
SQUARE WAVE OUT
POWER CONTROL
SERIAL BUS INTERFACE
CONTROL LOGIC
ADDRESS REGISTER
RTC
RAM (56×8)
Trang 9* Cấu trúc các thanh ghi:
- Có tất cả 64 thanh ghi 8 bit được đánh địa chỉ từ 0 đến 63 (0x00 – 0x3F)
- 7 thanh ghi đầu chứa thông tin thời gian bao gồm: giây (seconds), phút (minutes), giờ (hours), thứ (day), ngày (date), tháng (month), năm (year) Thanh ghi thứ 8 (control) điều khiển xung ngõ ra SQW/OUT Còn lại 56 thanh ghi có thể được dùng như RAM
- Việc ghi giá trị vào 7 thanh ghi đầu tương đương với việc cài đặt thời gian khởi động cho đồng hồ
➢ Tổ chức các thanh ghi thời gian theo từng bit:
- Thời gian lưu trong các thanh ghi theo dạng mã BCD (Binary-Coded Decimal – số thập phân theo mã nhị phân)
Vd: Muốn cài đặt cho thanh ghi MINUTES giá trị 43 thì cần ghi vào thanh ghi 01h giá trị 0x43 = 0100 0011 = 67 Khi hiển thị chỉ cần dùng phương pháp tách bit thông thường
để tách thành 2 nhóm 0100 và 0011 (sử dụng toán tử “>>”) rồi xuất giá trị ra LED để hiển thị
Hình 2.7 Tổ chức các thanh ghi thời gian theo từng bit
Trang 1010
- Thanh ghi giây: bit 7 có tên CH (clock halt - treo đồng hồ), nếu bit được set bằng 1
bộ dao động trong chip bị vô hiệu hóa, đồng hồ không hoạt động, vì vậy phải reset bit này xuống 0 ngay từ đầu
- Thanh ghi giờ:
bit 6 = 0: hệ 24 h, 2 bit 5&4 mã hóa chữ số hàng chục của giờ
bit 6 = 1: hệ 12 h, bit 4 mã hóa chữ số hàng chục (0,1), bit 5 mã hóa buổi trong ngày AM (0) hoặc PM (1)
Ngoài các thanh ghi trong bộ nhớ, DS1307 còn có 1 thanh ghi khác nằm riêng gọi
là con trỏ địa chỉ hay thanh ghi địa chỉ (address register) Giá trị của thanh ghi này là địa chỉ của thanh ghi trong bộ nhớ mà người dùng muốn truy cập, được set bằng lệnh Write thông qua giao diện I2C
* Cách truy xuất dữ liệu:
✓ Tóm tắt cách thực hiện giao tiếp I2C:
Để thực hiện giao tiếp ở chế độ Master, Vđk PIC sẽ gửi điều kiện START, tiếp theo là
7 bit địa chỉ Slave (SLA) + 1 bit Write/Read, kế đến là quá trình đọc hay ghi dữ liệu giữa Master và Slave bằng các byte dữ liệu 8 bit (có thể chỉ 1 byte hoặc 1 dãy byte), cứ sau mỗi byte lại có 1 bit ACK hoặc NOT ACK Giao tiếp kết thúc với việc Master gửi điều
kiện STOP
DS1307 là 1 Slave I2C nên chỉ có 2 hoạt động giao tiếp với chip này là Data Write
và Data Read Địa chỉ Slave address (SLA) của DS1307 cố định trong mạng I2C là
1101000 (0x68)
Write Slave address W/R reg_address(n) data (n) data (n+1)
Read Slave address W/R data (n) data (n+1) data (n+2)
Trang 11là 1 byte chứa địa chỉ của thanh ghi cần truy cập (tạm gọi là Addr_Reg), byte dữ liệu đầu tiên này sẽ được lưu trong thanh ghi địa chỉ của DS1307 Sau đó là 1 dãy các byte dữ liệu được ghi vào bộ nhớ của DS1307, byte dữ liệu đầu được ghi vào thanh ghi có địa chỉ được chỉ định bởi Addr_Reg, sau khi ghi 1 byte, Addr_Reg tự tăng nên các byte tiếp theo
sẽ được ghi liên tiếp vào các thanh ghi kế sau Số lượng byte dữ liệu cần ghi do Master quy định và không được vượt quá dung lượng bộ nhớ của DS1307 Quá trình kết thúc khi Master phát điều kiện STOP
✓ Read:
START, SLA, bit R (1) được gửi kèm theo sau 7bit SLA Sau đó liên tiếp các byte
dữ liệu được truyền từ DS1307 đến PIC Dữ liệu được đọc bắt đầu từ thanh ghi được chỉ định bởi con trỏ địa chỉ có giá trị được lưu trong các lần thao tác trước đó Muốn đọc chính xác dữ liệu từ 1 địa chỉ nào đó, cần thực hiện quá trình ghi giá trị cho con trỏ địa chỉ trước bằng cách gọi chương trình Data Write với chỉ 1byte địa chỉ được ghi sau
SLA+W
2.3.3 74HC595:
74HC595 là IC ghi dịch 8 bits kết hợp chốt dữ liệu, đầu vào nối tiếp, đầu ra
song song Thường dùng trong các mạch điều khiển LED 7 đoạn, quét LED ma
trận,… để tiết kiệm số chân Vđk tối đa (chỉ dùng 3 chân) Có thể mở rộng số ngõ
ra của vđk bao nhiêu tùy thích bằng việc mắc nối tiếp đầu vào dữ liệu các IC với nhau
Trang 12Q0 => Q7 (trên các chân 15,1,2,3,4,5,6,7): Xuất dữ liệu
Chân 13: Chân cho phép tích cực ở mức thấp (0) Khi ở mức cao, tất cả các
đầu ra của 74HC595 trở về trạng thái cao trở, không có đầu ra nào được cho phép
Chân 9: Chân dữ liệu nối tiếp Nếu dùng nhiều 74HC595 mắc nối tiếp nhau thì
chân này đưa vào đầu vào của con tiếp theo khi đã dịch đủ 8bit
Chân 11: Chân vào xung clock Khi có 1 xung clock tích cực ở sườn dương
(từ 0 lên 1) thì 1bit được dịch vào ic
Chân 12: xung clock chốt dữ liệu Khi có 1 xung clock tích cực ở sườn dương
thì cho phép xuất dữ liệu trên các chân output lưu ý có thể xuất dữ liệu bất kỳ lúc nào bạn muốn ,ví dụ đầu vào chân 14 dc 2 bit khi có xung clock ở chân 12 thì dữ liệu sẽ ra ở chân Q0 và Q1 (chú ý chiều dịch dữ liệu từ Q0=>Q7)
Chân 10: khi chân này ở mức thấp (mức 0) thì dữ liệu sẽ bị xóa trên chip
Trang 13Sau đó ta tạo một xung STCP thì 8 bit trong thanh ghi 8-STAGE SHIFT
REGISTER sẽ được sao chép sang thanh ghi 8-BIT STORAGE REGISTER Lúc này nếu chân OE ở mức thấp thì ngõ ra sẽ bằng với giá trị thanh ghi 8-BIT
STORAGE REGISTER, còn nếu chân OE ở mức cao thì ngõ ra ở trạng thái tổng trở cao (Hi-Z)
Chú ý:
Trang 1414
xung STCP thì thanh ghi 8-BIT STORAGE REGISTER sẽ giữ nguyên trạng thái
và ngõ ra cũng giữ nguyên trạng thái
Khi chân MR ở mức 0 thì dữ liệu trên thanh ghi 8-STAGE SHIFT REGISTER
sẽ bị xóa, còn thanh ghi 8-BIT STORAGE REGISTER sẽ giữ nguyên trạng thái và
ngõ ra cũng giữ nguyên trạng thái
2.3.4 LED 7 đoạn:
Sử dụng led 7 đoạn anode chung kết nối với nguồn 5V sử dụng trở 200Ω dể hạn
dòng Kết nối với vi điều khiển thông qua IC 74HC595
Trang 152.4 Lưu đồ thuật toán:
Begin
Khai báo các biến thời gian, mảng giá trị xác định âm lịch,
mã led 7 đoạn Khai báo port xuất, nhập, chế độ giao tiếp I2C
Khởi tạo ngắt port B, chuyển đổi ADC
Cập nhật thời gian (đọc hoặc ghi dữ liệu vào DS1307 qua giao tiếp I2C) Tính ngày âm
Kiểm tra thời gian để bật chuông báo thức
Chuyển đổi ADC, tính nhiệt độ
Quét led 7 đoạn hiển thị thời gian, nhiệt độ
Ngắt port B
Kiểm tra nút bấm, thay đổi biến điều kiện chỉnh thời gian
Return Thay đổi giá trị thời gian tương ứng/hẹn giờ
Trang 1616
3.1 Kết quả:
Hình 3.1 Sản phẩm
Trang 17Đánh giá chất lượng:
- Đồng hồ hoạt động ổn định, sai số rất nhỏ
- Đáp ứng các yêu cầu đặt ra: giá rẻ, nhỏ gọn, dễ sử dụng
3.2 Hướng phát triển đề tài:
- Sử dụng các dòng vi điều khiển khác giá rẻ để tận dụng tối đa khả năng
- Áp dụng vào các mô hình tự động để điều khiển các thiết bị theo thời gian
Trang 18i2c_write(0xd0); // I2C write address
i2c_write(0x00); // Start at REG 0 - Seconds i2c_write(dec_bcd(sec)&0x7f); // REG 0
i2c_write(0xd0); // I2C write address
i2c_write(0x03); // Start at REG 3 - dow
Trang 19dow = bcd_dec(i2c_read()); // REG 3
day = bcd_dec(i2c_read()); // REG 4
Trang 2020
#bit down = 0x06.5
#bit up = 0x06.4
#bit RBIF = 0x0b.0 // co ngat RB
//#bit RBIE = 0x0b.3 // bit cho phep
int sec,min,hour,dow,day,month,year,ngayam,thangam,namam,
temp,hh=6,mm,h1,b,d,t,q,l;
int1 f,ap,aps;
int const k[18]={0x03,0x9f,0x25,0x0d,0x99,0x49,0x41,0x1f,0x01,0x09, 0xff,0x11,0x63,0x91,0x39,0x13,0xfd,0xfe};//0 9, ,a,c,h,o,n,-,
Trang 21if ((hour==0||hour==12)&&min==0&&sec==0) { // cap nhat
ngay,thang,nam luc 00h00 & 12h00
Trang 22for (int i=0;i<6;i++) {
if(f==0) hc(12,10); else if(ap==0)hc(11,10); else
hc(13,10);
output_low(pin_b3); delay_ms(1); output_high(pin_b3);
if(f==0) hc(14,10); else if(ap==0) hc(5,10); else
hc(12,10);
output_low(pin_b2); delay_ms(1); output_high(pin_b2);
hc(temp%10,ngayam/10); output_low(pin_b1); delay_ms(1); output_high(pin_b1);
hc(temp/10,ngayam%10); output_low(pin_b0); delay_ms(1); output_high(pin_b0);
hc(sec%10,thangam/10); output_low(pin_d7); delay_ms(1); output_high(pin_d7);
hc(sec/10,thangam%10); output_low(pin_d6); delay_ms(1); output_high(pin_d6);
hc(min%10,namam/10); output_low(pin_d5); delay_ms(1); output_high(pin_d5);
hc(min/10,namam%10); output_low(pin_d4); delay_ms(1); output_high(pin_d4);
hc(hour%10,month/10); output_low(pin_c7); delay_ms(1); output_high(pin_c7);
hc(hour/10,month%10); output_low(pin_c6); delay_ms(1); output_high(pin_c6);
Trang 23hc(day%10,2); output_low(pin_c5); delay_ms(1); output_high(pin_c5);
hc(day/10,0); output_low(pin_d3); delay_ms(1); output_high(pin_d3);
if (dow==1) hc(15,year/10); else hc(17,year/10);
output_low(pin_d2); delay_ms(1); output_high(pin_d2);
if (dow==1) hc(12,year%10); else hc(dow,year%10);
output_low(pin_d1); delay_ms(1); output_high(pin_d1);
Trang 25hc(day/10,10); output_low(pin_d3); delay_ms(6);
if (f==0) hc(2,10); else hc(1,10); output_low(pin_c6); delay_ms(3); output_high(pin_c6);
if (f==1) { hc(16,10); output_low(pin_b3); delay_ms(3); output_high(pin_b3);
output_low(pin_b2); delay_ms(3); output_high(pin_b2);}
Trang 27else if (hour==0) hour=12; }
else //f==0
if (ap==1) {if (hour<12) hour+=12;}
else if (hour==12) hour=0;