QC

Digital Clock using 8051 Microcontroller

 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)

  1. Sends START condition to slave.
  2. Sends slave address to slave.
  3. Send write bit (0) to slave.
  4. Received ACK bit from slave
  5. Sends words address to slave.
  6. Received ACK bit from slave
  7. Sends data to slave.
  8. Received ACK bit from slave.
  9. And last sends STOP condition to slave.

Steps for data reading from slave to master (slave transmitting mode)

  1. Sends START condition to slave.
  2. Sends slave address to slave.
  3. Send read bit (1) to slave.
  4. Received ACK bit from slave
  5. Received data from slave
  6. Received ACK bit from slave.
  7. Sends  STOP condition to slave.


Circuit Diagram and Description

Trong mạch chúng tôi đã sử dụng hầu hết 3 linh kiện DS1307, AT89S52 và LCD. Ở đây AT89S52 được dùng để đọc thời gian từ DS1307 và hiển thị trên màn hình LCD 16x2. DS1307 gửi ngày / giờ sử dụng 2 dòng tới bộ vi điều khiển.


Các kết nối mạch rất đơn giản để hiểu và được thể hiện trong sơ đồ trên. Chân chip DS1307 SDA và SCL được kết nối với các chân P2.1 và P2.0 của vi điều khiển 89S52 có điện trở kéo lên giữ giá trị mặc định CAO tại các đường dữ liệu và xung nhịp. Và một bộ dao động tinh thể 32,768KHz được kết nối với DS1307chip để tạo ra độ trễ chính xác 1 giây. Và một pin 3 vôn cũng được kết nối với chân thứ 3 (BAT) của DS1307 để giữ thời gian hoạt động sau khi mất điện. LCD 16x2 được kết nối với 8051 ở chế độ 4 bit. Chân điều khiển RS, RW và En được kết nối trực tiếp với 89S52 chân P1.0, GND và P1.1. Và chân dữ liệu D0-D7 được kết nối với P1.4-P1.7 của 89S52.

Ba nút cụ thể là SET, INC / CHANGE và Next được sử dụng để cài đặt thời gian đồng hồ cho chân P2.4, P2.3 và P2.2 của 89S52 (hoạt động ở mức thấp). Khi chúng ta nhấn SET, chế độ đặt thời gian sẽ kích hoạt và bây giờ chúng ta cần đặt thời gian bằng cách sử dụng nút INC / CHANGE và nút Tiếp theo được sử dụng để chuyển sang chữ số. Sau khi cài đặt đồng hồ thời gian chạy liên tục.

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);
 }
}










Nap Code vào PY32F003 dùng Stlink

 Nap Code vào PY32F003 dùng Stlink Bước 1: Cài đặt  KeilC v5.39 theo link sau ( chú ý 5.39 keil c mới nạp ok). https://edge07.111.ir.cdn.ir/...