DP
VCC
3V BATTERY
R65 220
DP
F B
RB3
C RA3
RC0
RD7
R65 220
DIG5 RC7
RD2
E U1 PIC16F877A
2 3 4 5 6 7
33 34 35 36 37 38 39 40 15
16 17 18 23 24 25 26
19 20 21 22 27 28 29 30 13
14
32 11 31
12 1
8 9 10 RA0/AN0
RA1/AN1 RA2/AN2/VREF-/CVREF RA3/AN3/VREF+
RA4/T0CKI/C1OUT RA5/AN4/SS*/C2OUT
RB0/INT RB1 RB2 RB3/PGM RB4 RB5 RB6/PGC RB7/PGD RC0/T1OSO/T1CKI
RC1/T1OSI/CCP2 RC2/CCP1 RC3/SCK/SCL RC4/SDI/SDA RC5/SDO RC6/TX/CK RC7/RX/DT
RD0/PSP0 RD1/PSP1 RD2/PSP2 RD3/PSP3 RD4/PSP4 RD5/PSP5 RD6/PSP6 RD7/PSP7 OSC1/CLKIN
OSC2/CLKOUT
VDD VDD VSS
VSS MCLR*/VPP
RE0/RD*/AN5 RE1/WR*/AN6 RE2/CS*/AN7
D RB2
RA2
D
Q6 MMBT3906
2
3
1
RA0
RB0
DP
SW2 DIP_SW6
1 2 3 4 5 6
12 11 10 9 8 7
A
E
R54 10K DIS1 7SEG_DIPS 7
6 4 2 1 9 10 5
3 8
A B C D E F G DP
VCC1 VCC2
R65 220
RD4
R65 220
R65 220 G
RD3 RA4
A
DIG3 SW1 DIP_SW8
1 2 3 4 5 6 7 8
16 15 14 13 12 11 10 9
DIS2 7SEG_DIPS 7
6 4 2 1 9 10 5
3 8
A B C D E F G DP
VCC1 VCC2 ON
RD0
C
U2 DS1307
1 2
3 4 8
7 6 5
X1 X2 Vbat GND Vcc
SQW/OUT SCL SDA
E
B
R19 4.7k R21 1K
RA3
F
RA1 RB1 C7
10uF
F A
RA5 SW15
RESET
R65 220
RD5 RC5
RC2
B RB7
RC3 RC4
DIG6 RB5
Y 1 8MHz
C8 33pF
RB4
R65 220
DIG1 RC1
Y 2 32.768kHz
RD1 RB6
DIG2
RA4 VCC
RE0
G
DIG4
R65 220
ON
DIG2 RD6
C2 33pF RA1
VCC RC6
VCC RA2
C D
RE2
RA0
Q5 MMBT3906
2
3
1
G
R20 4.7k
RE1 RA5
DIG1
R55 10K
Hình 2.17 2. Yêu cầu
• Viết chương trình hiển thị giờ, phút, giây thực lên 6 Led 7 đoạn 3. Hướng dẫn thực hành
Các chương trình con được sử dụng trong chương trình: void quetled7doan(), void i2c_send(int8 addr, int8 _data), void read_i2c(int y).
Lưu dữ liệu DS1307:
void i2c_send(int8 addr, int8 _data) {
i2c_start(); // Start condition
i2c_write(0xd0); // Khai báo tiếp theo là lệnh ghi vào thiết bị có mã địa chỉ “d”
i2c_write(addr); // Ghi địa chỉ sẽ tương tác vào thiết bị I2C
i2c_write(_data); // Ghi nội dung vào địa chỉ vừa xác lập ở trên //sau lệnh này, đại chỉ tương tác tự động tăng 1
i2c_stop(); // Stop condition }
Đọc dữ liệu DS1307:
doc_i2c(int y,int8 addr)
i2c_start(); //Khởi động I2C
i2c_write(0xD0); // Khai báo tiếp theo là lệnh ghi vào thiết bị I2C có mã địa chỉ //“d”
i2c_write(addr); //thiet lap lai con tro, địa chỉ tương tác tiếp theo là “addr”
//được ghi vào thiết bị I2C
// Bộ ba lệnh này đi chung với nhau.
i2c_stop();
I2C_start();
I2C_write(0xD1); // Khai báo sau lệnh này là lệnh đọc dữ liệu từ địa chỉ ô //nhớ đang
// xác lập trước đó trong chip I2C
//Lưu ý rằng trước khi thực hiện đọc phải có đoạn xác lập địa chỉ tương tác y=i2c_read(0);// Khong duoc bo so "0"
i2c_stop();
return y;
}
Chương trình mẫu:
#include <16f877a.h>
#fuses nowdt,noprotect,nolvp,xt,put
#use delay(clock=4000000)
#use I2C(master, sda=PIN_C4, scl=PIN_C3, slow)
#use fast_io(b)
#use fast_io(c)
#use fast_io(e)
#byte portc=0x07
#byte portb=0x06
#byte porte=0x09
#khai báo tín hiệu cho led 7 đoạn int8 giay,phut,gio;
doc_i2c(int y,int8 addr);
void i2c_send(int8 addr, int8 _data);
void hien_thi(int x, int y, int z);
void main( ) {
set_tris_c(0b00011000);
set_tris_b(0);
set_tris_e(0);
i2c_send(0x00,0);// ghi giay hien hanh i2c_send(0x01,45);//ghi phut hien hanh i2c_send(0x02,8);//ghi gio hien hanh while (1)
{
giay=doc_i2c(giay,0);
phut=doc_i2c(phut,1);
gio=doc_i2c(gio,2);
hien_thi(giay,phut,gio);
} }
//DOC I2C
doc_i2c(int y,int8 addr) {
i2c_start();
i2c_write(0xD0); //Gui dia chi cua slave
i2c_write(addr); //thiet lap lai con tro. can doc du lieu o byte co dia chi nao?
i2c_stop();
I2C_start();
I2C_write(0xD1); // Gui lenh doc du lieu y=i2c_read(0);// Khong duoc bo so "0"
i2c_stop();
return y;
}
//HIEN THI LEN 2 LED 7 DOAN void hien_thi(int x, int y, int z)
//khi doc du lieu tu DS1307 la so BCD can lay lan luot 4 bit cao va 4 bit // thap de xuat ra
int chuc_giay,donvi_giay, chuc_phut,donvi_phut, chuc_gio,donvi_gio, i;
chuc_giay=x&0b11110000;//lay 4 bit cao
chuc_giay =swap(chuc_giay);// dao 4 bit cao thanh 4 bit thap de hien thi.
donvi_giay=x&0b00001111;// lay 4 bit thap chuc_phut=y&0b11110000;//lay 4 bit cao
chuc_phut =swap(chuc_phut);// dao 4 bit cao thanh 4 bit thap de hien thi.
donvi_phut=y&0b00001111;// lay 4 bit thap chuc_gio=z&0b11110000;//lay 4 bit cao
chuc_gio =swap(chuc_gio);// dao 4 bit cao thanh 4 bit thap de hien thi.
donvi_gio=z&0b00001111;// lay 4 bit thap for (i=0; i<=10; i++ )
{
quetled7doan();
} }
void i2c_send(int8 addr, int8 _data) {
i2c_start(); // Start condition i2c_write(0xd0);
i2c_write(addr); // Device address i2c_write(_data); // Write Command i2c_stop(); // Stop condition }
4. Các bước thực hiện
Bước 1: Nhập nội dung chương trình trên vào máy (lắp đầy các nội dung còn trống cho phù hợp), biên dịch, kiểm tra lỗi và sửa lỗi bằng phần mềm PIC C Compiler.
Bước 2: Chạy mô phỏng chương trình trên phần mềm protuers khi chương trình biên dịch thành công.
Bước 3: Nạp chương trình vào kit (chú ý gạt các DIP_SW đúng vị trí) theo dõi sự hiển thị trên 6 led 7 đoạn để kiểm tra kết quả .
5. Các yêu cầu mở rộng
• Viết thêm phần hiển thị thêm các thông tin khác: ngày trong tuần, ngày trong tháng, tháng, năm tuần tự lên 2 led còn lại trên KIT ?
Gợi ý: Chọn địa chỉ phù hợp.
• Thêm phần cài đặt thời gian cho đồng hồ ?
Gợi ý: Viết thêm chương trình con void hieuchinh() có nhiệm vụ nhận tín hiệu từ nút nhấn và xử lý theo đúng yêu cầu hiệu chỉnh.