Digital Clock using 8051 Microcontroller
Trong dự án này, chúng tôi sẽ chứng minh việc tạo Đồng hồ RTC bằng vi điều khiển 8051. Nếu bạn muốn thực hiện dự án này với Arduino, hãy kiểm tra đồng hồ kỹ thuật số này bằng Arduino. Thành phần chính của dự án này là DS1307 là một vi mạch đồng hồ kỹ thuật số thời gian thực. Cho phép biết về vi mạch này một cách chi tiết.
RTC DS1307:
Đồng hồ thời gian thực nối tiếp DS1307 (RTC) là đồng hồ / lịch thập phân được mã hóa nhị phân (BCD) công suất thấp cộng với 56 byte NV SRAM. Chip này hoạt động trên giao thức I²C. Đồng hồ / lịch cung cấp thông tin giây, phút, giờ, thứ, ngày, tháng và năm. Ngày cuối tháng được tự động điều chỉnh cho các tháng có ít hơn 31 ngày, bao gồm cả các điều chỉnh cho năm nhuận. Đồng hồ hoạt động ở định dạng 24 giờ hoặc 12 giờ với chỉ báo AM / PM. DS1307 được tích hợp mạch cảm biến nguồn giúp phát hiện sự cố mất điện và tự động chuyển sang nguồn dự phòng. Hoạt động chấm công vẫn tiếp tục trong khi bộ phận hoạt động từ nguồn cung cấp dự phòng. Chip DS1307 có thể chạy liên tục đến 10 năm.
Đồng hồ thời gian thực dựa trên 8051 là đồng hồ kỹ thuật số để hiển thị thời gian thực bằng cách sử dụng RTC DS1307, hoạt động trên giao thức I2C. Đồng hồ thời gian thực có nghĩa là nó chạy ngay cả sau khi mất điện. Khi nguồn điện được kết nối lại, nó sẽ hiển thị thời gian thực bất kể thời gian và khoảng thời gian nó ở trạng thái tắt. Trong dự án này, chúng tôi đã sử dụng mô-đun LCD 16x2 để hiển thị thời gian ở định dạng - (giờ, phút, giây, ngày, tháng và năm). Đồng hồ thời gian thực thường được sử dụng trong máy tính, nhà ở, văn phòng và thiết bị điện tử của chúng tôi để cập nhật chúng theo thời gian thực.
Giao thức I2C là một phương pháp để kết nối hai hoặc nhiều thiết bị sử dụng hai dây vào một hệ thống duy nhất, và vì vậy giao thức này còn được gọi là giao thức hai dây. Nó có thể được sử dụng để giao tiếp 127 thiết bị với một thiết bị hoặc bộ xử lý duy nhất. Hầu hết các thiết bị I2C đều chạy trên tần số 100Khz.
Steps for data write master to slave (slave receiving mode)
- Sends START condition to slave.
- Sends slave address to slave.
- Send write bit (0) to slave.
- Received ACK bit from slave
- Sends words address to slave.
- Received ACK bit from slave
- Sends data to slave.
- Received ACK bit from slave.
- And last sends STOP condition to slave.
Steps for data reading from slave to master (slave transmitting mode)
- Sends START condition to slave.
- Sends slave address to slave.
- Send read bit (1) to slave.
- Received ACK bit from slave
- Received data from slave
- Received ACK bit from slave.
- Sends STOP condition to slave.
Circuit Diagram and Description
Program Description
Trong mã, chúng tôi đã bao gồm thư viện họ 8051 và một thư viện đầu ra đầu vào tiêu chuẩn. Và xác định các chân mà chúng tôi đã sử dụng, và lấy một số biến để tính toán.
#include<reg51.h> #include<stdio.h> #define lcdport P1 sbit rs=P1^0; sbit en=P1^1; sbit SDA=P2^1; sbit SCL=P2^0; sbit next=P2^2; //increment digit sbit inc=P2^3; //increment value sbit set=P2^4; //set time char ack; unsigned char day1=1; unsigned char k,x; unsigned int date=1, mon=1, hour=0, min=0, sec=0; int year=0; void delay(int itime) { int i,j; for(i=0;i<itime;i++) for(j=0;j<1275;j++); }
Và chức năng đã cho được sử dụng cho màn hình LCD lái xe.
void daten() { rs=1; en=1; delay(1); en=0; } void lcddata(unsigned char ch) { lcdport=ch & 0xf0; daten(); lcdport=(ch<<4) & 0xf0; daten(); } void cmden(void) { rs=0; en=1; delay(1); en=0; } void lcdcmd(unsigned char ch)
Chức năng này được sử dụng để khởi tạo RTC và đọc thời gian và ngày tháng từ biểu mẫu IC RTC.
I2CStart(); I2CSend(0xD0); I2CSend(0x00); I2CStart(); I2CSend(0xD1); sec=BCDToDecimal(I2CRead(1)); min=BCDToDecimal(I2CRead(1)); hour=BCDToDecimal(I2CRead(1)); day1=BCDToDecimal(I2CRead(1)); date=BCDToDecimal(I2CRead(1)); mon=BCDToDecimal(I2CRead(1)); year=BCDToDecimal(I2CRead(1)); I2CStop(); show_time(); //display time/date/day delay(1);
Các hàm này được sử dụng để chuyển đổi thập phân sang BCD và BCD sang thập phân.
int BCDToDecimal(char bcdByte) { char a,b,dec; a=(((bcdByte & 0xF0) >> 4) * 10); b=(bcdByte & 0x0F); dec=a+b; return dec; } char DecimalToBCD (int decimalByte) { char a,b,bcd; a=((decimalByte / 10) << 4); b= (decimalByte % 10); bcd=a|b; return bcd; }
Các chức năng dưới đây được sử dụng cho Giao tiếp I2C.
void I2CStart(){SDA=1;SCL=1,SDA=0,SCL=0;} //"start" function for communicate with ds1307 RTC void I2CStop(){SDA=0,SCL=1,SDA=1;} //"stop" function for communicate wit ds1307 RTC unsigned char I2CSend(unsigned char Data) //send data to ds1307 { char i; char ack_bit; for(i=0;i<8;i++) { if(Data & 0x80) SDA=1; else SDA=0; SCL=1; Data<<=1; SCL=0; } SDA=1,SCL=1; ack_bit=SDA; SCL=0; return ack_bit; } unsigned char I2CRead(char ack) //receive data from ds1307 { unsigned char i, Data=0; SDA=1; for(i=0;i<8;i++) { Data<<=1; do{SCL=1;} while(SCL==0); if(SDA) Data|=1; SCL=0; } if(ack)SDA=0; else SDA=1; SCL=1; SCL=0; SDA=1; return Data; }
Hàm set_time được sử dụng để đặt thời gian trong đồng hồ và hàm show_time bên dưới được sử dụng để hiển thị thời gian trên màn hình LCD.
void show_time() //function to display time/date/day on LCD { char var[5]; lcdcmd(0x80); lcdprint("Date:"); sprintf(var,"%d",date); lcdprint(var); sprintf(var,"/%d",mon); lcdprint(var); sprintf(var,"/%d",year+2000); lcdprint(var); lcdprint(" "); lcdcmd(0xc0); lcdprint("Time:"); sprintf(var,"%d",hour); lcdprint(var); sprintf(var,":%d",min); lcdprint(var); sprintf(var,":%d",sec); lcdprint(var); lcdprint(" "); // day(day1); lcdprint(" "); }
ALL CODE.
#include<reg51.h>
#include<stdio.h>
#define lcdport P1
sbit rs=P1^0;
sbit en=P1^1;
sbit SDA=P2^1;
sbit SCL=P2^0;
sbit next=P2^2; //increment digit
sbit inc=P2^3; //increment value
sbit set=P2^4; //set time
char ack;
unsigned char day1=1;
unsigned char k,x;
unsigned int date=1, mon=1, hour=0, min=0, sec=0;
int year=0;
void delay(int itime)
{
int i,j;
for(i=0;i<itime;i++)
for(j=0;j<1275;j++);
}
void daten()
{
rs=1;
en=1;
delay(1);
en=0;
}
void lcddata(unsigned char ch)
{
lcdport=ch & 0xf0;
daten();
lcdport=(ch<<4) & 0xf0;
daten();
}
void cmden(void)
{
rs=0;
en=1;
delay(1);
en=0;
}
void lcdcmd(unsigned char ch)
{
lcdport=ch & 0xf0;
cmden();
lcdport=(ch<<4) & 0xf0;
cmden();
}
void lcdprint(char *str)
{
while(*str)
{
lcddata(*str);
str++;
}
}
void lcd_init(void)
{
lcdcmd(0x02);
lcdcmd(0x28);
lcdcmd(0x0c);
lcdcmd(0x01);
}
void I2CStart(){SDA=1;SCL=1,SDA=0,SCL=0;} //"start" function for communicate with ds1307 RTC
void I2CStop(){SDA=0,SCL=1,SDA=1;} //"stop" function for communicate wit ds1307 RTC
unsigned char I2CSend(unsigned char Data) //send data to ds1307
{
char i;
char ack_bit;
for(i=0;i<8;i++)
{
if(Data & 0x80) SDA=1;
else SDA=0;
SCL=1;
Data<<=1;
SCL=0;
}
SDA=1,SCL=1;
ack_bit=SDA;
SCL=0;
return ack_bit;
}
unsigned char I2CRead(char ack) //receive data from ds1307
{
unsigned char i, Data=0;
SDA=1;
for(i=0;i<8;i++)
{
Data<<=1;
do{SCL=1;}
while(SCL==0);
if(SDA) Data|=1;
SCL=0;
}
if(ack)SDA=0;
else SDA=1;
SCL=1;
SCL=0;
SDA=1;
return Data;
}
/*void day(char d) // Function for display day on LCD
{
switch(d)
{
case 0:
lcdprint("DAY");
break;
case 1:
lcdprint("SUN");
break;
case 2:
lcdprint("MON");
break;
case 3:
lcdprint("TUE");
break;
case 4:
lcdprint("WED");
break;
case 5:
lcdprint("THU");
break;
case 6:
lcdprint("FRI");
break;
case 7:
lcdprint("SAT");
break;
}
} */
int BCDToDecimal(char bcdByte)
{
char a,b,dec;
a=(((bcdByte & 0xF0) >> 4) * 10);
b=(bcdByte & 0x0F);
dec=a+b;
return dec;
}
char DecimalToBCD (int decimalByte)
{
char a,b,bcd;
a=((decimalByte / 10) << 4);
b= (decimalByte % 10);
bcd=a|b;
return bcd;
}
void show_time() //function to display time/date/day on LCD
{
char var[5];
lcdcmd(0x80);
lcdprint("Date:");
sprintf(var,"%d",date);
lcdprint(var);
sprintf(var,"/%d",mon);
lcdprint(var);
sprintf(var,"/%d",year+2000);
lcdprint(var);
lcdprint(" ");
lcdcmd(0xc0);
lcdprint("Time:");
sprintf(var,"%d",hour);
lcdprint(var);
sprintf(var,":%d",min);
lcdprint(var);
sprintf(var,":%d",sec);
lcdprint(var);
lcdprint(" ");
// day(day1);
lcdprint(" ");
}
void set_time() //time set function
{
lcdcmd(0x0e);
while(k<7)
{
while(k==3) //set date
{
x=year%4;
if(inc==0)
{date++;while(inc==0);
if(x==1 && mon==2 && date==28){date=1;} //check for 28 day febuary
if(x==0 && mon==2 && date==29){date=1;} //check for 29 day febuary
if((date==31) && (mon==4) || (mon==6) || (mon==9) || (mon==17)){date=1;} // check for 30 day month
if(date==32){date=1;} // check for 31 day month
show_time();}
if(next==0)
{
k=5;
while(next==0);
} //check for next digit
lcdcmd(0x85);
}
while(k==2) //set month
{
if(inc==0)
{mon++;while(inc==0);
if(mon==13){mon=1;} //check for end of year
show_time(); }
if(next==0){k=3;
while(next==0);
}
lcdcmd(0x88);
}
while(k==1) //set year
{
if(inc==0)
{year++;while(inc==0);
if(year==30){year=0;}
show_time(); }
if(next==0){k=2;
while(next==0);}
lcdcmd(0x8d);
}
while(k==5) //set hour
{
if(inc==0)
{hour++;while(inc==0);
if(hour==24){hour=0;}
show_time();}
if(next==0){k=6;
while(next==0);}
lcdcmd(0xc5);
}
while(k==6) //set min
{
if(inc==0)
{min++;while(inc==0);
if(min==60){min=0;}
show_time();}
if(next==0){k=10;
while(next==0);}
lcdcmd(0xc8);
}
}
}
void main()
{
lcd_init();
lcdprint("Digital Clock");
lcdcmd(0xc0);
lcdprint(" Using 8051 ");
delay(400);
lcdcmd(1);
lcdprint("Circuit Digest");
lcdcmd(192);
lcdprint("Saddam Khan");
delay(400);
while(1)
{
if(set==0) // check time set button press
{
I2CStart();
I2CSend(0xD0);
I2CSend(0x00);
I2CSend(0x00);
I2CSend(0x00);
I2CSend(0x00);
I2CSend(0x01);
I2CSend(0x01);
I2CSend(0x01);
I2CSend(0x00);
I2CSend(0x80);
I2CStop();
k=1;
set_time(); // call time set function
min=DecimalToBCD(min);
sec=DecimalToBCD(0);
hour=DecimalToBCD(hour);
year=DecimalToBCD(year);
mon=DecimalToBCD(mon);
date=DecimalToBCD(date);
I2CStart();
I2CSend(0xD0);
I2CSend(0x00);
I2CSend(0x00);
I2CSend(min);
I2CSend(hour);
I2CSend(day1);
I2CSend(date);
I2CSend(mon);
I2CSend(year);
I2CSend(0x80);
I2CStop();
lcdcmd(1);
lcdcmd(0x0c);
}
I2CStart();
I2CSend(0xD0);
I2CSend(0x00);
I2CStart();
I2CSend(0xD1);
sec=BCDToDecimal(I2CRead(1));
min=BCDToDecimal(I2CRead(1));
hour=BCDToDecimal(I2CRead(1));
day1=BCDToDecimal(I2CRead(1));
date=BCDToDecimal(I2CRead(1));
mon=BCDToDecimal(I2CRead(1));
year=BCDToDecimal(I2CRead(1));
I2CStop();
show_time(); //display time/date/day
delay(1);
}
}