Tải bản đầy đủ (.docx) (21 trang)

BÀI TẬP LỚN KỸ THUẬT VI XỬ LÝ ĐỀ TÀI: HIỂN THỊ THỜI GIAN THỰC DS1307 LÊN LCD SỬ DỤNG 16F877A

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (669.25 KB, 21 trang )

TRƯỜNG ĐẠI HỌC GIAO THÔNG VẬN TẢI
PHÂN HIỆU TẠI TP. HỒ CHÍ MINH
BỘ MƠN ĐIỆN – ĐIỆN TỬ
----------o0o----------

BÀI TẬP LỚN
KỸ THUẬT VI XỬ LÝ
ĐỀ TÀI: HIỂN THỊ THỜI GIAN THỰC DS1307 LÊN LCD
SỬ DỤNG 16F877A
GVHD

: Th.S VÕ THIỆN LĨNH

LỚP

: ĐIỆN TỬ VÀ TIN HỌC CÔNG NGHIỆP K60
ĐIỆN TỬ VIỄN THÔNG K60

SVTH

:

TRƯƠNG VIỆT DŨNG - 6051020012
TRƯƠNG QUỐC ĐẠT - 6051020017
TRẦN MINH CÔNG - 6051020007
NGUYỄN KHANG ĐIỀN - 6051020018
LÊ CÔNG HUY – 6051020035
BÙI VĂN QUANG ANH - 605102003
TP. Hồ Chí Minh - 2021
1



LỜI NÓI ĐẦU
Với đà tăng trưởng mạnh mẽ, Việt Nam đang bước vào giai đoạn quan trọng của q
trình cơng nghiệp hóa hiện đại hóa đất nước. Yêu cầu về mặt nhân lực chất lượng cao là
hết sức cấp thiết. Chính vì thế việt làm bài tập lớn, cho phép sinh viên rằng luyện được
các kỹ năng cần thiết để chuẩn bị cho tương lai sau này.
Trong cuộc sống hiện đại thời gian là một phần tử vô cùng quan trọng. Để có thể cập
nhật thời gian một cách chính xác, người ta sử dụng DS1307 với khả năng lưu trữ và giúp
thời gian hiển thị luôn đúng ở mọi thời điểm. Vì thế nhóm em chọn đề tài này và xem đây
là một đề vô cùng hay và cần thiết. Với độ khó khơng q cao, giúp nhóm em có thể dễ
dàng tiếp thu kiến thức mới. Xây dựng tư duy trong nghề.
DS1307 có thể sử dụng trong hầu hết các mạch yêu cầu thời gian chuẩn xác. Ví dụ các
thiết bị máy tính hay đồng hồ điện tử … Quá trình thiết kế diễn ra theo phương án. Sơ đồ
mạch sau đó mới đến lập trình cho vi sử lý 16f877a. Việc nay gây một chút khó khăn
trong q trình lập trình nhưng nó đúng với thực tế làm việc bên ngồi.
Về nhiệm vụ, nhóm em đưa ra các yêu cầu cho mạch phải đảm bảo về mặt thẩm mỹ,
quan trọng nhất là mạch phải hoạt động ổn định trong thời gian dài. Tránh được nhiễu là
một yêu tất yếu.
Nhóm em xin gửi lời cảm ơn đến các giảng viên trong bộ mơn đã tận tâm hướng dẫn,
Nhóm tụi em. Tuy nhiên lần đầu tiên bắt tay vào làm đồ án cũng như thời gian và kiến
thức của em có hạn nên khơng tránh khỏi những sai sót trong đồ án của mình, mọi ý kiến
phê bình, nhận xét của thầy, cô em xin ghi nhận và tiếp thu để bài báo cáo được hồn
thiện hơn.
Nhóm em xin chân thành cảm ơn !

2


MỤC LỤC


3


Phần I: Tổng quan về Proteus, Pic16F877A, DS1307
1. Proteus:
1.1. Khái niệm:
• Phần mềm Proteus cho phép mơ phỏng hoạt động của mạch điện tử bao gồm phần
thiết kế mạch và viết chương trình điều khiển cho các họ vi điều khiển như MCS51, PIC, AVR, … Proteus là phần mềm mô phỏng mạch điện tử của Labcenter
Electronics, mô phỏng cho hầu hết các linh kiện điện tử thông dụng, đặc biệt hỗ
trợ cho cả các MCU như PIC, 8051, AVR, Motorola.
• Phần mềm bao gồm 2 chương trình: ISIS (Intelligent Schematic Input System) cho
phép mô phỏng mạch và ARES (Advanced Routing and Editing Software) dùng để
vẽ mạch in.
1.2.

Giao diện chính

1.3. Ưu và nhược điểm Proteus
• Ưu điểm: Dễ dạng tạo ra một sơ đồ nguyên lý từ đơn giản đến phức tạp.
Dễ dàng chỉnh sữa các đặc tính của linh kiện trên sơ đồ nguyên lý.
Hỗ trợ kiểm tra lỗi thiết kế trên sơ đồ nguyên lý. Có thể xem và lưu lại phần báo
lỗi.
Phần mềm chạy mô phỏng và phân tích các tính chất của một mạch điện một cách
chính xác.
Proteus cung cấp cho người sử dụng cơng cụ biên dịch cho các họ vi xử lý như
MSC51, AVR, HC11, …qua đó tạo ra các tập tin .hex dùng để nạp cho vi xử lý và
4


tạp tin .dsi dùng để xem và chạy kiểm tra từng bước trong q trình mơ phỏng.

Phần mềm cung cấp rất nhiều mơ hình linh kiện có chức năng mơ phỏng, từ các vi
điều khiển thông dụng đến các link kiện ngoại vi như LED, LCD, Keypad, cổng
RS232… cho phép người sử dụng mô phỏng từ một hệ vi điều khiển hoàn chỉnh
đến việc xây dựng phần mềm cho hệ thống đáp ứng các giao thức vật lý. Ngoài ra,
Proteus còn cho phép bạn tự tạo link kiện tương tác động do đó bạn có thể thực
hiện các mơ phỏng có tương tác giống như hoạt động của một mạch thật.
• Nhược điểm: Phần vẽ mạch có giao diện khơng được đẹp và hấp dẫn.
2. Pic 16F877A
2.1. Khái niệm:
PIC16F877A là một Vi điều khiển PIC 33 chân và được sử dụng hầu hết trong các
dự án và ứng dụng nhúng. Nó có năm cổng bắt đầu từ cổng A đến cổng E. Nó có
ba bộ định thời trong đó có 2 bộ định thời 8 bit và 1 bộ định thời là 16 Bit. Nó hỗ
trợ nhiều giao thức giao tiếp như giao thức nối tiếp, giao thức song song, giao thức
I2C. PIC16F877A hỗ trợ cả ngắt chân phần cứng và ngắt bộ định thời.
2.2.

Sơ đồ chân:

3. DS1307:
3.1. Khái niệm:
DS1307 là chip đồng hồ thời gian thực (RTC : Real-time clock), khái niệm thời
gian

thực ở đây được dùng với ý nghĩa thời gian tuyệt đối mà con người đang sử

dụng, tình bằng giây, phút, giờ…DS1307 là một sản phẩm của Dallas Semiconductor
5


(một cơng ty thuộc Maxim Integrated Products). Chip này có 7 thanh ghi 8-bit chứa thời

gian là: giây, phút, giờ, thứ (trong tuần), ngày, tháng, năm. Ngồi ra DS1307 cịn có 1
thanh ghi điều khiển ngõ ra phụ và 56 thanh ghi trống có thể dùng như RAM. DS1307
được đọc và ghi thông qua giao diện nối tiếp I2C (TWI của AVR) nên cấu tạo bên ngoài
rất đơn giản. DS1307 xuất hiện ở 2 gói SOIC và DIP có 8 chân.
3.2.

Sơ đồ chân:

Các chân của DS1307 được mô tả như sau:
- X1 và X2: là 2 ngõ kết nối với 1 thạch anh 32.768KHz làm nguồn tạo dao động cho
chip.
- VBAT: cực dương của một 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 và 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: một ngõ phụ tạo xung vuông (Square Wave / Output Driver), tần số của
xung được tạo có thể được lập trình. Như vậy chân này hầu như khơng liên quan đến
chức năng của DS1307 là đồng hồ thời gian thực, chúng ta sẽ bỏ trống chân này khi nối
mạch.
- SCL và SDA là 2 đường giao xung nhịp và dữ liệu của giao diện I2C mà chúng ta
đã tìm hiểu trong bài TWI của AVR.

6


Phần II: Sơ đồ mạch thí nghiệm trong Proteus
1. Tởng quan:

2. PIC 16F877A:


7


3. DS1307 và LCD16x2:

8


Phần III: Code chương trình
1. Hàm ds1307.c
#ifndef RTC_SDA
#define RTC_SDA PIN_C4
#define RTC_SCL PIN_C3
#endif
#use i2c(master, sda=RTC_SDA, scl=RTC_SCL)
#define DS1307_ALL_DISABLED
0b00000000 // All disabled
#define DS1307_OUT_ON_DISABLED_HIHG 0b10000000 // Out to Hight on Disable
Out
#define DS1307_OUT_ENABLED
0b00010000 // Out Enabled
#define DS1307_OUT_1_HZ
0b00000000 // Freq. Out to 1 Hz
#define DS1307_OUT_4_KHZ
0b00000001 // Freq. Out to 4.096 Khz
#define DS1307_OUT_8_KHZ
0b00000010 // Freq. Out to 8.192 Khz
#define DS1307_OUT_32_KHZ
0b00000011 // Freq. Out to 32.768 Khz

#define Start_user_address_nvram 0x08
#define End_user_address_nvram 0x3f
9


char
days_of_week[7]
[11]={"Lunes\0","Martes\0","Miércoles\0","Jueves\0","Viernes\0","Sábado\0","Domingo
\0"};
byte ds1307_bin2bcd(byte binary_value);
byte ds1307_bcd2bin(byte bcd_value);
void ds1307_init(int val){
byte seconds = 0;
#ifndef USE_INTERRUPTS
disable_interrupts(global);
#endif
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
i2c_start();
i2c_write(0xD1);
seconds = ds1307_bcd2bin(i2c_read(0));
i2c_stop();
seconds &= 0x7F;
delay_us(3);
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
i2c_write(ds1307_bin2bcd(seconds));
i2c_start();

i2c_write(0xD0);
i2c_write(0x07);
i2c_write(val);
i2c_stop();
#ifndef USE_INTERRUPTS
enable_interrupts(global);
#endif
}

10


void ds1307_set_date_time(byte day, byte mth, byte year, byte dow, byte hr, byte min,
byte sec){
#ifndef USE_INTERRUPTS
disable_interrupts(global);
#endif
sec &= 0x7F;
hr &= 0x3F;
i2c_start();
i2c_write(0xD0);
i2c_write(0x00);
i2c_write(ds1307_bin2bcd(sec));
i2c_write(ds1307_bin2bcd(min));
i2c_write(ds1307_bin2bcd(hr));
i2c_write(ds1307_bin2bcd(dow));
i2c_write(ds1307_bin2bcd(day));
i2c_write(ds1307_bin2bcd(mth));
i2c_write(ds1307_bin2bcd(year));
i2c_stop();

#ifndef USE_INTERRUPTS
enable_interrupts(global);
#endif
}
void ds1307_get_date(byte &day, byte &mth, byte &year, byte &dow){
#ifndef USE_INTERRUPTS
disable_interrupts(global);
#endif
i2c_start();
i2c_write(0xD0);
i2c_write(0x03);
i2c_start();
i2c_write(0xD1);
dow = ds1307_bcd2bin(i2c_read() & 0x7f);
day = ds1307_bcd2bin(i2c_read() & 0x3f);
mth = ds1307_bcd2bin(i2c_read() & 0x1f);
year = ds1307_bcd2bin(i2c_read(0));
11


i2c_stop();
#ifndef USE_INTERRUPTS
enable_interrupts(global);
#endif
}
void ds1307_get_time(byte &hr, byte &min, byte &sec){
#ifndef USE_INTERRUPTS
disable_interrupts(global);
#endif
i2c_start();

i2c_write(0xD0);
i2c_write(0x00);
i2c_start();
i2c_write(0xD1);
sec = ds1307_bcd2bin(i2c_read() & 0x7f);
min = ds1307_bcd2bin(i2c_read() & 0x7f);
hr = ds1307_bcd2bin(i2c_read(0) & 0x3f);
i2c_stop();
#ifndef USE_INTERRUPTS
enable_interrupts(global);
#endif
}
char ds1307_read_nvram_byte(char addr){
char retval;
#ifndef USE_INTERRUPTS
disable_interrupts(global);
#endif
i2c_start();
i2c_write(0xD0);
i2c_write(addr);
12


i2c_start();
i2c_write(0xD1);
retval = i2c_read(0);
i2c_stop();
return(retval);
#ifndef USE_INTERRUPTS
enable_interrupts(global);

#endif
}
void ds1307_write_nvram_byte(char addr, char value){
#ifndef USE_INTERRUPTS
disable_interrupts(global);
#endif
i2c_start();
i2c_write(0xD0);
i2c_write(addr);
i2c_write(value);
i2c_stop();
#ifndef USE_INTERRUPTS
enable_interrupts(global);
#endif
}
void ds1307_get_day_of_week(char* ptr){
byte lday;
byte lmonth;
byte lyr;
byte ldow;
ds1307_get_date(lday,lmonth,lyr,ldow);
sprintf(ptr,"%s",days_of_week[ldow]);
}
///////////////////////////////////////////////////////////////////////////////
13


byte ds1307_bin2bcd(byte binary_value){
byte temp;
byte retval;

temp = binary_value;
retval = 0;
while(1){
if(temp >= 10){
temp -= 10;
retval += 0x10;
}else{
retval += temp;
break;
}
}
return(retval);
}
byte ds1307_bcd2bin(byte bcd_value){
byte temp;
temp = bcd_value;
temp >>= 1;
temp &= 0x78;
return(temp + (temp >> 2) + (bcd_value & 0x0f));
}
2. Hàm LCD_4BIT.c
#include <stddef.h>
#define LCD_RS
PIN_D0
#define LCD_EN
PIN_D1
#define LCD_D4
PIN_D4
#define LCD_D5
PIN_D5

#define LCD_D6
PIN_D6
#define LCD_D7
PIN_D7
// misc display defines#define Line_1
0x80
#define Line_2
0xC0
//#define Clear_Scr
0x01
// prototype statements
void LCD_Init(void);
//Ham khoi tao LCD
void LCD_SetPosition(unsigned int cX);//Thiet lap vi tri con tro
14


//Ham viet 1ky tu hoac 1 chuoi len LCD
void LCD_PutChar(unsigned int cX);
void LCD_PutCmd(unsigned int cX) ; //Ham gui lenh len LCD
void LCD_PulseEnable(void);
//Xung kich hoat
void LCD_SetData(unsigned int cX); //Dat du lieu len chan Data
void WriteNum(unsigned char num); // Hien thi so ra LCD
void HTsothapphan(Int32 num); //Hien thi so thap phan
// Dinh nghia Cong
//#use standard_io(B)
//#use standard_io(A)
//Khoi tao LCD
void LCD_Init (void)

{
LCD_SetData (0x00);
Delay_ms(20);
// Cho cho LCD khoi tao >> 15ms
output_low(LCD_RS); // Che do gui lenh
LCD_SetData(0x03); // Khoi tao che do 4 bit
LCD_PulseEnable();
LCD_SetData(0x02); // Tao giao dien 4 bit
LCD_PulseEnable(); // send dual nibbles hereafter, MSN first
LCD_PutCmd(0x2C); // function set (all lines, 5x7 characters)
LCD_PutCmd(0x0C); // display ON, cursor off, no blink
LCD_PutCmd(0x06); // entry mode set, increment & scroll left
LCD_PutCmd(0x01); // clear display
}
void LCD_SetPosition(unsigned int cX)
{
/* this subroutine works specifically for 4-bit Port D*/
LCD_SetData(swap(cX)|0x08);
LCD_PulseEnable();
LCD_SetData(swap(cX));
LCD_PulseEnable();
}
void LCD_PutChar(unsigned int cX)
{
/* this subroutine works specifically for 4-bit Port D */
output_high(LCD_RS);
LCD_PutCmd(cX);
output_low(LCD_RS);
}
void LCD_PutCmd(unsigned int cX)

{
/* this subroutine works specifically for 4-bit Port D */
15


LCD_SetData(swap(cX));
LCD_PulseEnable();
LCD_SetData(swap(cX));
LCD_PulseEnable();

/* send high nibble */
/* send low nibble */

}
void LCD_PulseEnable(void)
{
output_high(LCD_EN);
delay_us(5);
output_low(LCD_EN);
delay_ms(5);
}
void LCD_SetData(unsigned int cX)
{
output_bit(LCD_D4, cX & 0x01);
output_bit(LCD_D5, cX & 0x02);
output_bit(LCD_D6, cX & 0x04);
output_bit(LCD_D7, cX & 0x08);
}
void WriteNum(unsigned char num)
{

unsigned char digit;
digit = num/100;
LCD_PutChar(digit + '0');
//write tram+ma ASCII cua '0'
digit = num/10;
digit = digit % 10;
LCD_PutChar(digit + '0');
//write chuc
digit = num % 100;
digit = digit % 10;
LCD_PutChar(digit + '0');
//write dvi
}
void HTsothapphan(Int32 num)
{
Int8 Integer, First, Second, Third;
Integer = num/1000 + 0x30; // Tach phan nguyen
num= num%1000;
First = num/100 + 0x30;
// Tach phan le thu 1
num = num%100;
Second = num/10 + 0x30;
// Tach phan le thu 2
Third = num%10 + 0x30;
// Tach phan le thu 3
Lcd_putcmd(0xCA);
Lcd_putchar(Integer);
Lcd_putchar(".");
16



Lcd_putchar(First);
Lcd_putchar(Second);
Lcd_putchar(Third);
}
3. Hàm main
#include "16f877a.h"
#include "def_877a.h"
#device *=16 ADC=10
#use delay(clock=20000000)
#FUSES NOWDT, HS, NOPUT, NOPROTECT, NODEBUG, NOBROWNOUT,
NOLVP, NOCPD, NOWRT
#include "ds1307.c"
#use i2c(Master, sda = PIN_C4, scl=PIN_C3)
#include "LCD_4BIT.c"
#define Slave_add 0x08
#define Read 1
#define Write 0
void send(int8 a);
int8 sec,min,hrs,day,month,yr,dow;
//char* ptr;
void main()
{
LCD_init();
delay_ms(10);
while(1)
{
ds1307_get_date(day,month,yr,dow);
ds1307_get_time(hrs,min,sec);
//Truyen len LCD

LCD_PutCmd(0xC0);
LCD_PutChar(hrs/10+48);
LCD_PutChar(hrs%10+48);
LCD_PutChar(45);
LCD_PutChar(min/10+48);
LCD_PutChar(min%10+48);
17


LCD_PutChar(45);
LCD_PutChar(sec/10+48);
LCD_PutChar(sec%10+48);
delay_ms(5);
Lcd_putcmd(0x80);
switch(dow){
case 1:
LCD_PutChar("CN: ");
break;
case 2:
LCD_PutChar("Thu2: ");
break;
case 3:
LCD_PutChar("Thu3: ");
break;
case 4:
LCD_PutChar("Thu4: ");
break;
case 5:
LCD_PutChar("Thu5: ");
break;

case 6:
LCD_PutChar("Thu6: ");
break;
case 7:
LCD_PutChar("Thu7: ");
break;
}
LCD_PutChar(day/10+48);
LCD_PutChar(day%10+48);
LCD_PutChar(45);
LCD_PutChar(month/10+48);
LCD_PutChar(month%10+48);
LCD_PutChar(45);
LCD_PutChar(yr/10+48);
LCD_PutChar(yr%10+48);
delay_ms(5);
}
}

18


4. Chạy chương trình:

KẾT LUẬN
Thơng qua việc làm bài tập lớn nhóm em đã tiếp thu thêm được nhiều kiến thức cũng
như củng cố lại kiến thức đã được học. Nhưng vẫn cịn nhiều hạn chế vì hiện tại đang
trong q trình học online khơng thể thực hành trên mạch thật. Đó là một thiệt thịi vơ
cùng lớn.
Em xin gửi lời cảm ơn đến các giảng viên trong bộ môn đã tận tâm hướng dẫn, Nhóm

tụi em. Tuy nhiên lần đầu tiên bắt tay vào làm đồ án cũng như thời gian và kiến thức của
em có hạn nên khơng tránh khỏi những sai sót trong đồ án của mình, mọi ý kiến phê bình,
nhận xét của thầy, cơ em xin ghi nhận và tiếp thu để bài báo cáo được hoàn thiện hơn.
Em xin chân thành cảm ơn !

19


PHỤ LỤC:
DANH MỤC TÀI LIỆU THAM KHẢO:
-

Bài giảng Vi Xử Lý GV: ThS.Võ Thiện Lĩnh

20


21



×