Bài tập lớn môn Vi xử lý - Đề tài 3: Mạch đồng hồ giờ, phút, giây dùng 8051 và LED 7 đoạn, cho phép cài đặt thời gian dùng nút nhấn - Ngô Tiến Đạt

CHƯƠNG III

THIẾT KẾ PHẦN CỨNG VÀ MÔ TẢ HOẠT ĐỘNG

I. THIẾT KẾ PHẦN CỨNG

 Linh kiện sử dụng

• 1 IC 89C51

• 1 bộ 6 LED 7 đoạn

• 3 nút nhấn

• 6 cổng NOT

• 3 LED đơn

• 3 trở 100k

• 2 trở 4k7

• Thạch anh 32768 Hz

• 1 nguồn 3V

• 2 tụ 33pF

• 1 IC DS1307

 Sơ đồ phần cứng

• LED 7 đoạn

Chân ABCDEFG nối với P0.0 tới P0.6 của IC 89C51

Chân điều khiển 123456 nối với P2.0 tới P2.6 của IC 89C51 thông qua cổng NOT

• IC DS1307

Chân SDA nối với P1.7

Chân SCL nối với P1.6

Đèn LED báo AM nối với P2.6

Đèn LED báo PM nối với P2.7

 

docx31 trang | Chuyên mục: Vi Xử Lý – Vi Điều Khiển | Chia sẻ: yen2110 | Lượt xem: 1183 | Lượt tải: 0download
Tóm tắt nội dung Bài tập lớn môn Vi xử lý - Đề tài 3: Mạch đồng hồ giờ, phút, giây dùng 8051 và LED 7 đoạn, cho phép cài đặt thời gian dùng nút nhấn - Ngô Tiến Đạt, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
đã được truyền đi, thiết bị nhận sẽ kéo SDA xuống mức thấp tương ứng một bit ACK tại xung clock thứ 9 trên báo hiệu đã nhận đủ 8 bit. Thiết bị truyền khi nhận được bit ACK sẽ tiếp tục thực hiện  quá  trình truyền hoặc kết thúc.
Định dạng địa chỉ thiết bị: 
Mỗi thiết bị ngoại vi tham gia vào bus i2c đều có một địa chỉ duy nhất, có độ dài là 7 bit như vậy trên một bus I2C ta có thể phân biệt tối đa 128 thiết bị. Byte đầu tiên được gửi từ Master sẽ bao gồm 7 bit địa chỉ và bit thứ 8 gọi là bit R/W. 
Bit R/W = 0 : Ghi dữ liệu từ Master vào Slave.
Bit R/W = 1 : Đọc dữ liệu từ Slave .
Phương thức truyền dữ liệu tới Slave:
‐ Master tạo xung START 
‐ Master gửi 7 bit địa chỉ của Slave +  bit  R/W= 0 (8 clock)
‐ Tại thời điểm clock thứ 9, Master đọc xung ACK từ Slave. ACK = 0 khi Slave có 
địa chỉ tương ứng đã nhận dạng,
Master bắt đầu gửi dữ liệu đến Slave theo từng byte một mất 9 clock 
do theo sau mỗi byte (8 clock) được gửi từ Master, Slave phải xác nhận bằng một 
xung ACK=0. 
‐Kết thúc quá trình truyền, Master sau khi truyền byte cuối sẽ tạo xung STOP báo hiệu kết thúc.
Chế độ đọc dữ liệu từ Slave:
‐ Master tạo xung START 
‐ Master gửi 7 bit địa chỉ của Slave  + bit R/W = 1
‐ Sau khi Slave xác nhận địa chỉ và trả về bit ACK=0, Slave sẽ gửi từng byte ra SDA; 
Master sẽ nhận dữ liệu và cũng trả về bit ACK =0 sau mỗi byte. 
‐ Để kết thúc quá trình nhận dữ liệu, Master gửi xung Not‐ACK qua cú pháp i2c_read(1,0) và tạo xung STOP.
Phần mềm
Gồm 
Hàm “main”: thực hiện chương trình chính
Hàm “EXT0_ISR”: Hàm ngắt ngoài 0 để đọc nút nhấn điều chỉnh giừo , phút
Hàm “Timer1_ISR”: ngắt timer1 để hiển thị ra led 7 đoạn bằng phương pháp quét led
Hàm “ISR_INIT”: hàm cài đặt ngắt
Hàm “delay”: tạo trễ
Hàm “dislay”: hiển thị ra led 7 đoạn
Hàm “start”: start I2C
Hàm “stop”: stop I2C
Hàm “send”: ghi 1 byte vào DS1307
Hàm “receive”: nhận 1 byte từ DS1307
Hàm “write”: ghi giá trị vào 1 địa chỉ
Hàm “read”: đọc giá trị từ 1 địa chỉ
Hàm “read_data”: hàm nhận K byte từ DS1307
Hàm “write_data”: truyền k byte DS1307
Hàm “nut_nhan”: điều chỉnh giờ phút
Hàm “chuyển”: Chuyển đổi giữa 2 chế độ 24h và 12h. 
Lưu đồ giải thuật một số hàm quan trọng:
Hàm “NGAT”
ĐẶT LẠI GIÁ TRỊ NGẮT
COUNTER=6
TĂNG COUNTER
START
	NO
 YES
COUNTER = 0
	HIỂN THỊ RA LED 7 ĐOẠN
CHƯƠNG TRÌNH CHỈNH GIỜ VÀ PHÚT
NÚT CHỈNH GIỜ/PHÚT
CHUYỂN ĐỔI 12H/24H
NÚT CHUYỂN
ĐỌC BIẾN PHÚT 
ĐỌC BIẾN GIỜ
ĐỌC BIẾN GIỜ VÀ BIẾN AM/PM
CHẾ ĐỘ
ĐỌC GIÁ TRỊ TỪ DS1307
CÀI ĐẶT GIÁ TRỊ ĐẦU CHO DS1307, NGẮT, GIỜ PHÚT GIÂY
Hàm “main”
	12H	24H
	CHƯA NHẤN	
 NHẤN
 CÓ
Hàm “chuyen”
RET
PM=0;AM=0;T=0
HOUR = HOUR+12; TRẢ GIỜ VỀ DS1307
PM=1
T=2
TRẢ GIỜ VỀ DS1307
HOUR>12
T=1
AM=1;PM=0
HOUR=HOUR-12 AM=0;PM=1
Hàm “nut_nhan”
GIỜ TĂNG LÊN 1 TRẢ GIỜ LẠI DS1307
NHẤN NÚT TĂNG PHÚT
PHÚT TĂNG LÊN 1 TRẢ PHÚT LẠI DS1307
STARTNHẤN NÚT TĂNG PHÚT
RET
NÚT NHẤN CHỈNH
	NO
	YES
	NO
 YES
Hàm “read”
BẮT ĐẦU GIAO TIẾP VỚI DS1307
GỬI ĐỊA CHỈ CẦN ĐỌC
GỬI LỆNH GHI
START
 SEND
GỬI LỆNH ĐỌC
ĐỌC BYTE VỀ
NGỪNG GIAO TIẾP VỚI DS1307
RET
Hàm “write”
RET
 SEND
BẮT ĐẦU GIAO TIẾP VỚI DS1307
NGỪNG GIAO TIẾP VỚI DS1307
GỬI BYTE CẦN GHI
GỬI ĐỊA CHỈ CẦN GHI
GỬI LỆNH GHI
START
CHƯƠNG V
CODE CHƯƠNG TRÌNH
#include 
#define DOUT P0
#define D1 P2_0
#define D2 P2_1
#define D3 P2_2
#define D4 P2_3
#define D5 P2_4 
#define D6 P2_5 
#define chedo P3_2
#define tangphut P3_3
#define tanggio P3_4
#define SDA P1_7
#define SCL P1_6
#define portbit P1_0
sbit AM = P2^6;
sbit PM = P2^7;
unsigned char code_7_segment[10]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90};
unsigned char data_write[3]={0x00,0x25,0x22};
unsigned char data_read[3];
unsigned char counter,mode,t,hour,minute;
void delay(unsigned int t);
void start();
void stop();
void send(unsigned char g);
unsigned char receive();
void write(unsigned char add,unsigned char gt);
unsigned char read(unsigned char add);
void read_data(unsigned char k,char *read);
void write_data(unsigned char k,char *write);
void dislay(void);
void DS1307INIT();
void nut_nhan();
unsigned char bcd_dec(unsigned char bcd);
unsigned char dec_bcd(unsigned char dec);
void chuyen(void);
void ISR_INIT(void);
/////////////////////
//Ham ngat ngoai 0 de doc nut nhan dieu chinh gio phut
 void EXT0_ISR(void) interrupt 0
 {
 delay(100);
 mode++;
 if(mode==2){ mode=0;}
 portbit = !portbit;
 }
 //ham ngat timer 1 de hien thi ra led 7 doan bang phuong phap quet led
void Timer1_ISR(void) interrupt 3
{ 
 TR1 = 0;	 
 TH1 = ((-6000)&0xFF00)>>8;	 //dat lai gia tri cho timer
	 TL1= (-6000)&0x00FF;
	 TR1 = 1;
	 counter++;
	 if(counter == 6){counter = 0;};
 dislay(); 
} 	
void main(void)
{	 DS1307INIT();
 ISR_INIT() ;
 write_data(3,data_write);
	 mode = 0;
	 counter = 0;
	 t=0;
	 AM =0;
	 PM =0;
	 while(1)
	 {	 read_data(3,data_read); //doc 3 byte gio phut giay ve tu DS1307
	 if(t==1){hour = bcd_dec(data_read[2]&0x1F);	 //che do 12h
	 if(data_read[2]&0x20) {AM=0;PM=1;}
	 else {AM =1 ;PM =0;}
	 }
	 if(t==0) { hour = bcd_dec(data_read[2]&0x3F); } //che do 24h
	 minute = bcd_dec(data_read[1]);//chuyen byte phut tu bcd sang ma thap phan cho bien minute do DS1307 tra ve so BCD
	 if(!tangphut){t++;delay(200);chuyen();} //kiem tra xem nut chuyen doi giua 2 che do 24h va 12h co nhan hay khong
	 nut_nhan();
 }
}
// Ham cai dat ngat
void ISR_INIT(void)
{ TMOD = 0x11;
 TH1 = ((-6000)&0xFF00)>>8;
	 TL1 = (-6000)&0x00FF;
	 TR1 = 1;
	 ET1 = 1;
	 EX0 = 1;
	 EA = 1;
	 IT0=1; }
void delay(unsigned int t)
{
 unsigned int i,j;
 for(i=0;i<t;i++)for(j=0;j<125;j++);
}
/*void delay1(unsigned int t)
{
 unsigned int i,j;
 for(i=0;i<t;i++)for(j=0;j<30;j++);
}	*/
//ham hien thi ra led 7 doan	
 void dislay(void)
{	
 if (counter==0){
	 D6=1;
	 	 DOUT=0xff;
	 D1=0;
 DOUT=code_7_segment[hour/10];
	 }
	 if (counter==1){
	 D1=1;
	 DOUT=0xff;
	 D2=0;
 DOUT=code_7_segment[hour%10];
	 }
	 if (counter==2){
	 D2=1;
	 DOUT=0xff; 
	 D3=0;
 DOUT=code_7_segment[minute/10];
	 	}
	 if (counter==3){
	 D3=1;
	 DOUT=0xff; 
	 D4=0;
 DOUT=code_7_segment[minute%10];
	 }
	 if (counter==4){
	 D4=1;
	 DOUT=0xff; 
	 D5=0;
 DOUT=code_7_segment[data_read[0]/16];
	 }
	 if (counter==5){
	 D5=1;
	 DOUT=0xff;
	 D6=0;
 DOUT=code_7_segment[data_read[0]%16];
	 }
}
// Ham start I2C
void start()
{
 SCL=1;
 SDA=1;
 delay(1);
 SDA=0;
 delay(1);
 SCL=0;
 SDA=1;
}
// Ham stop I2C
void stop()
{
 SDA=0;SCL=1;
 delay(1);
 SDA=1;
 delay(1);
}
// Ham ghi 1 byte vao DS1307
void send(unsigned char g)
{
 unsigned char tem,i;
 for(i=0;i<8;i++)
 {
 tem=g&0x80;
	if(tem == 0x80)
	SDA=1;
	else SDA=0;
	SCL=1;
	delay(1);
	SCL=0;
	g=g*2;
 }
 SCL=1;
 delay(1);
 SCL=0;
}
// Ham nhan 1 byte
unsigned char receive()
{
 unsigned char gt=0,i;
 for(i=0;i<8;i++)
 {
 SCL=1;
 gt=gt*2;
 delay(1);
 gt=gt|SDA;
 SCL=0;
 delay(1);
 }
 SCL=1;
 SDA=1;
 delay(1);
 SCL=0;
 return gt;
}
//Ham ghi gia tri vao 1 dia chi 
void write(unsigned char add,unsigned char gt)
{
 start();
 send(0xd0);
 send(add);
 send(gt);
 stop();
}
// Ham doc gia tri tu 1 dia chi
unsigned char read(unsigned char add)
{
 unsigned char value;
 start();
 send(0xd0);
 send(add);
 start();
 send(0xd1);
 value=receive();
 stop();
 return value;
}
void DS1307INIT()
{
 unsigned char check;
 check = read(0x08);
 if(check!='c')
 {
 write(0x08,'c');
 }
}
//Ham nhan k byte tu DS1307
void read_data(unsigned char k,unsigned char *gt)
{ unsigned char add,i;
 add=0x00;
 for (i=0;i< k;i++)
 { 
	 *(gt+i) = read(add);
 add++;
 }
}
//Ham truyen k byte vao DS1307
void write_data(unsigned char k,unsigned char *gt)
{ unsigned char add,i;
 add = 0x00;
 for (i=0;i<k;i++)
 { 
 write(add,*(gt+i));
	add++;
 }
}
//de dieu chinh gio phut
void nut_nhan()
{ 
 while(mode)
	 {
	if(!tangphut) {delay(300);
	 minute++;
	 if(minute>59) {minute = 0;
	 hour++;
	if(t == 0){if(hour>23){hour = 0;}data_read[2] = dec_bcd(hour) & 0x3F;}	 //che do 24h
	 else {if (hour > 12) {hour = 0x01;AM = !AM;PM = !PM;}	 //che do 12h
	 if((AM == 0)&&(PM==1)){data_read[2]= dec_bcd(hour) | 0x60;}
	 if((PM == 0)&&(AM==1)){data_read[2] = dec_bcd(hour) | 0x20;}}
	 }
	 write(0x02,data_read[2]);	 //tra bien gio ve DS1307
	 write(0x01,dec_bcd(minute)); //tra bien phut ve DS1307
	 }
	 	if(!tanggio) {delay(300);
	 hour++;
	 if(t == 0)
	 {if(hour>23){hour = 0;}data_read[2] = dec_bcd(hour) & 0x3F;AM=0;PM=0;}	 //che do 24h
	 if(t==1) {if (hour > 12) {	 //che do 12h
	 hour = 1;AM = !AM;PM = !PM;
	 }
	 if((AM == 0)&&(PM==1)){
	 data_read[2]= dec_bcd(hour) | 0x60;
	 }
	 if((AM == 1)&&(PM==0)) {data_read[2] = dec_bcd(hour) | 0x40;
	 data_read[2] &= 0xDF; }
	 }
	 write(0x02,data_read[2]);	//tra bien gio ve DS1307	 
	 }
 }
}
//Ham chuyen giua 2 che do 24h va 12h
void chuyen(void)
{
 if (t==1){ if(hour>12){ hour -= 12;
	 data_read[2] = dec_bcd(hour) | 0x60;	 //t==1 chuyen tu 24h sang 12h
	 AM = 0;PM =1;
	 }
	else { if( hour ==0){ hour = 12;}
	 data_read[2] = dec_bcd(hour) | 0x40;
	 PM = 0;AM =1;
	 }
	 }
 if (t==2){ if ((PM == 1) && ( AM == 0 )) {hour += 12;	 //t==2 chuyen tu 12h sang 24h sau do cho t ve 0
 data_read[2] = dec_bcd(hour)&0x3F;
	 }
	if ((PM == 0)&&(AM == 1)){ if(hour == 12){hour=0;} 
	 data_read[2] = dec_bcd(hour)&0x3F;
	 }
	 PM =0;
	 AM =0;
	 t=0;
 	}
write(0x02,data_read[2]);
} 
unsigned char bcd_dec(unsigned char bcd)	 //ham chuyen ma bcd sang ma thap phan
 {
	 return((bcd/16)*10+(bcd%16));
	 }	
unsigned char dec_bcd(unsigned char dec) 	 // ham chuyen ma thap phan sang bcd
 {
	 return((dec/10)*16+(dec%10));}
CHƯƠNG VI
CHƯƠNG KẾT LUẬN
ƯU ĐIỂM:
Đầy đủ chức năng của 1 đồng hồ thông thường
Giaỉ quyết được vấn đề chính xác về thời gian
Có nhiều tùy chọn chỉnh giờ
Code nhóm tự viết
KHUYẾT ĐIỂM
Code còn rắc rồi, chưa tưởng mình.
Thiếu chế độ hẹn giờ báo thức.
Tài liệu tham khảo:

File đính kèm:

  • docxbai_tap_lon_mon_vi_xu_ly_de_tai_3_mach_dong_ho_gio_phut_giay.docx