[Share] Mạch đồng hồ Giờ phút giây - Ngày tháng năm 2 IN 1

Hi all,

Chip lượn lờ nhặt được Mạch đồng hồ Giờ : Phút : Giây Ngày - Tháng - Năm kết hợp hẹn giờ bật tắt thiết bị điện rất tiện lợi. Bạn nào cần lấy về Tham khảo phát triển thêm nhé. Code C dễ hiểu.


I.Sơ đồ  mô phỏng bằng Protues




II. Code C biên dịch bằng phần mềm Keil C 4

// Dong ho thoi gian thuc có Gio Phut Giay, Ngay Thang Nam, gio bat, gio tat thiet bi ngoai vi, test ok
// khi su dung de nap code thì sua lai hai lenh sau cua chuong trinh delay va
//   menu o cuoi file code c:
// while(i-->0){   for(j=0;j<40;j++){}}} // j < 40 la chuan
//  if (x>=10) { x=0;// x >= 10 la hop ly
//  Danghuunho@gmail.com
#include<reg51.h>
void _nop_(void);
#define delay_us _nop_(); //generates 1 microsecond
sbit SCK=P3^0;       //serial clock pin
sbit SDA=P3^1;       //serial data pin
sbit dau_cham=P0^7;      // thanh h
#define  LED_  P0 // led 7 doan
sbit ledc0=P2^0;     // s1
sbit ledc1=P2^1;     // s2
sbit ledc2=P2^2;     // m1
sbit ledc3=P2^3;     // m2
sbit ledc4=P2^4;     // h1
sbit ledc5=P2^5;     // h2
sbit menu_key=P3^2;
sbit up_key=P3^3;
sbit down_key=P3^4;
sbit role=P2^6;
#define SCKHIGH  SCK=1;
#define SCKLOW   SCK=0;
#define SDAHIGH  SDA=1;
#define SDALOW   SDA=0;
void delay_ms(unsigned int);
void start(void);
void stop(void);
void send_byte(unsigned char);
unsigned char receive_byte(unsigned char);
void write_i2c(unsigned char,unsigned char,unsigned char);
unsigned char read_i2c(unsigned char,unsigned char);
unsigned char slave_ack,add=0,k,z;
void menu (void);// quyet phim
char mode,press,statu,x,m,h,s,d,mon,y,h1,h0,m1,m0,dot=2;
int t;
//==========================================================================================
void hienthi(char so, cham)  // hien thi 1 so tren led 7 doan
{      if ((cham ==2)|(cham ==4) |(cham ==dot)) switch(so){ // bat dau cham
      case 0: LED_ = 0x40;
                        break;
                case 1: LED_ = 0x79;
                        break;
                case 2: LED_ = 0x24;
                        break;
                case 3: LED_ = 0x30;
                        break;
                case 4: LED_ = 0x19;
                        break;
                case 5: LED_ = 0x12;
                        break;
                case 6: LED_ = 0x02;
                        break;
                case 7: LED_ = 0x78;
                        break;
                case 8: LED_ = 0x0;
                        break;
                case 9: LED_ = 0x10;
break;
case 10: LED_ = 0xff;// khong hien thi
break;
}
else switch(so){   // tat dau cham
case 0: LED_ = 0x40+ 0x80;
                        break;
                case 1: LED_ = 0x79+ 0x80;
                        break;
                case 2: LED_ = 0x24+ 0x80;
                        break;
                case 3: LED_ = 0x30+ 0x80;
                        break;
                case 4: LED_ = 0x19+ 0x80;
                        break;
                case 5: LED_ = 0x12+ 0x80;
                        break;
                case 6: LED_ = 0x02+ 0x80;
                        break;
                case 7: LED_ = 0x78+ 0x80;
                        break;
                case 8: LED_ =       0x80;
                        break;
                case 9: LED_ = 0x10+ 0x80;
break;
case 10: LED_ = 0xff;// khong hien thi
break;
};
}
//=======================================================================

void bat_led(char z)
{ ledc0 = 1;
ledc1 = 1;
ledc2 = 1;
ledc3 = 1;
ledc4 = 1;
ledc5 = 1;
       switch(z)
        {       case 0: ledc0 = 0;break;    //s1
                case 1: ledc1 = 0;break;    //s2
                case 2: ledc2 = 0;break;    //m1
                case 3: ledc3 = 0;break;    //m2
                case 4: ledc4 = 0;break;    //h1
                case 5: ledc5 = 0;break;    //h2
        }}
//=======================================================================
void get_date(void)
  {d=read_i2c(0xd0,0x04);//read date register
mon=read_i2c(0xd0,0x05);//read month register
y=read_i2c(0xd0,0x06);//read year register

h1=read_i2c(0xd0,0x08);//read 08 register
m1=read_i2c(0xd0,0x09);//read 09 register
h0=read_i2c(0xd0,0x0a);//read 0a register
m0=read_i2c(0xd0,0x0b);//read 0b register
   
}
//=======================================================================
void get_time(void)
  {h=read_i2c(0xd0,0x02);//read hours register
m=read_i2c(0xd0,0x01);//read minutes register
s=read_i2c(0xd0,0x00);//read seconds register
if ( h==0& m ==0 & s ==0 ) get_date();  
}
//=======================================================================
void out_led(char h,m,s)  // quet led
{       char temp[6],i;
temp[0]= s & 0xf;
        temp[1]= s >> 4;
        temp[2]= m & 0xf;
        temp[3]= m >> 4;
        temp[4]= h & 0xf;
        temp[5]= h >> 4;
        for(i=0;i<6;i++)
        { bat_led(i);
                hienthi(temp[i],i);
delay_ms(1);
hienthi(0xa,1);
        }}

//=======================================================================
void write_time (char a)
 {
 if (a ==1){
  write_i2c(0xd0,0x00,s);// luu giay
  write_i2c(0xd0,0x01,m);// luu phut
  write_i2c(0xd0,0x02,h);// luu gio
    };
  if (a ==2){
  write_i2c(0xd0,0x04,d);// luu ngay
  write_i2c(0xd0,0x05,mon);// luu thang
  write_i2c(0xd0,0x06,y);// luu nam
};
  if (a ==3){
  write_i2c(0xd0,0x08,h1);// luu gio bat
  write_i2c(0xd0,0x09,m1);// luu phut bat
  };
  if (a ==4){
  write_i2c(0xd0,0x0a,h0);// luu gio tat
  write_i2c(0xd0,0x0b,m0);// luu phut tat
  };

 }
//=======================================================================
void role_on(void){
char  a,b,c;
if(h1>0x23| h0>0x23| m1>0x59| m0>0x59)
{
m0=0;
m1=0;
h1=0;
h0=0;
write_time(3);
write_time(4);
}

a =((h > h1)|((m >= m1)&(h ==h1)));
b=((h > h0)|((m >= m0)&(h ==h0)));
c =((h1 > h0)|((m1 >= m0)&(h1 ==h0)));

   if(   (((a==1) & (b==1)) & (c==1)) | (((a==0) & (b==0))& (c==1)) | (((a==1) & (b==0))& (c==0))   )
{role =1; // bat role khi den hen
      statu = 1;
dot =0;}
else {role =0; // tat role khi den hen
statu = 0;
dot =2;}
}
//=======================================================================
void key (void)
 {
  if (mode > 0){ // khi dang hien ngay,tu dong hien thi gio sau 3 giay
t++;
if (t>=900) { // t = 900
mode =0;
get_date();
t=0;}}
    if ((menu_key == 1)&(up_key == 1)&(down_key == 1)) x=0;

if       (h==h1 & m==m1 & statu ==0 & mode == 0 ) {role =1; // bat role khi h1 = h
statu = 1;dot = 0;}
else if (h==h0& m==m0 & statu ==1 & mode == 0 ) { role =0; // tat role khi h0 = h
statu = 0;dot =2;};


if ((press == 1) & (menu_key == 1) ) {// nut menu
press = 0;
mode++;
if ((mode==4))      // gio
{
write_time(1);
}
else if ((mode==7)) // ngay
{
write_time(2);
}
else if ((mode==9)) // gio bat
{
write_time(3);
role_on();
}
else if ((mode>=11)) // gio tat
{mode = 0;
write_time(4);
role_on();
};
}
if (press == 2 & up_key == 1) { // nut up
press = 0;
if (mode ==0) mode =11;


else if (mode ==11) mode =12;
else if (mode ==12) mode =13;
else if (mode ==13) mode =0;
else if ((mode == 1)) {// chinh gio
  h++;
if((h & 0xf) ==0xa)
h= (h & 0xf0)+ 0x10;
else if(h  ==0x24) h= 0;
}
else if ((mode ==  2)) {// chinh phut
  m++;
if((m & 0xf) ==0xa)
m= (m & 0xf0)+ 0x10;
   if(m  == 0x60) m = 0;
}
else if ((mode ==  3)) {// chinh giay
  s=0x30;
}
else if ((mode == 4)) {// chinh ngay
  d++;
if((d & 0xf) ==0xa)
d= (d & 0xf0)+ 0x10;
   if(d  == 0x32) d = 1;
}
else if ((mode == 5)) {// chinh thang
  mon++;
if((mon & 0xf) ==0xa)
mon= (mon & 0xf0)+ 0x10;
   if(mon  == 0x13) mon = 1;
}
else if ((mode == 6)) {// chinh nam
  y++;
if((y & 0xf) ==0xa)
y= (y & 0xf0)+ 0x10;
   if(y  == 0x40) y = 0;
}
else if ((mode == 7)) {// chinh gio bat
  h1++;
if((h1 & 0xf) ==0xa)
h1= (h1 & 0xf0)+ 0x10;
   if(h1  == 0x24) h1 = 0;
}
else if ((mode == 8)) {// chinh phut bat
  m1++;
if((m1 & 0xf) ==0xa)
m1= (m1 & 0xf0)+ 0x10;
   if(m1  == 0x60) m1 = 0;
}
else if ((mode == 9)) {// chinh gio tat
  h0++;
if((h0 & 0xf) ==0xa)
h0= (h0 & 0xf0)+ 0x10;
   if(h0  == 0x24) h0 = 0;
}
else if ((mode == 10)) {// chinh phut tat
  m0++;
if((m0 & 0xf) ==0xa)
m0= (m0 & 0xf0)+ 0x10;
   if(m0  == 0x60) m0 = 0;
};
}

if (press == 3 & down_key == 1) { // nut down
press = 0;

if (mode ==0) {
if (role == 1){
  role =0;
dot =2;
}
else    {
  role =1;
dot =0;
}}
else if ((mode == 1)) // chinh gio
if(((h & 0xf) ==0x0)&(h>=0x10)) h= h - 0x10 + 0x9;
else if(h  ==0x0) h= 0x23;
else h-- ;

else if ((mode == 2)) // chinh phut
  if(((m & 0xf) ==0x0)&(m>=0x10)) m= m - 0x7 ;
else if(m  ==0x0) m= 0x59;
else m-- ;

else if ((mode == 3)) // chinh giay
  s = 0;

else if ((mode == 4)) // chinh ngay
  if(((d & 0xf) ==0x0)&(d>=0x10)) d= d - 0x7 ;
else if(d  ==0x1) d= 0x31;
else d-- ;
else if ((mode == 5)) // chinh thang
  if(((mon & 0xf) ==0x0)&(mon>=0x10)) mon= mon - 0x7 ;
else if(mon  ==0x1) mon= 0x12;
else mon-- ;
else if ((mode == 6)) // chinh nam
  if(((y & 0xf) ==0x0)&(y>=0x10)) y= y - 0x7 ;
else if(y  ==0x0) y= 0x39;
else y-- ;
else if ((mode == 7)) // chinh gio bat
if(((h1 & 0xf) ==0x0)&(h1>=0x10)) h1= h1 - 0x10 + 0x9;
else if(h1  ==0x0) h1= 0x23;
else h1-- ;

else if ((mode == 8)) // chinh phut bat
  if(((m1 & 0xf) ==0x0)&(m1>=0x10)) m1= m1 - 0x7 ;
else if(m1  ==0x0) m1= 0x59;
else m1-- ;
else if ((mode == 9)) // chinh gio tat
if(((h0 & 0xf) ==0x0)&(h0>=0x10)) h0= h0 - 0x10 + 0x9;
else if(h0  ==0x0) h0= 0x23;
else h0-- ;

else if ((mode == 10)) // chinh phut tat
  if(((m0 & 0xf) ==0x0)&(m0>=0x10)) m0= m0 - 0x7 ;
else if(m0  ==0x0) m0= 0x59;
else m0-- ;
};}

//=======================================================================
void main(void)
{
s=(read_i2c(0xd0,0x00));
if(s & 0x80) write_i2c(0xd0,0x00,0); // kiem tra xem ds1307 co chay khong
get_date();
get_time();
role_on();
while(1)
{ // 400 tuong duong 2 s
if (mode == 0) {
t++;
if (t>=10) {t=0; // t>= 250 la ok
get_time();
}}
if ((menu_key == 0)|(up_key == 0)|(down_key == 0)) menu();
key(); // xu ly nut an
if (mode <=3) out_led(h,m,s); // hien thi gio
else if (((mode <=6)& mode>=4)|mode==11)
out_led(d,mon,y); // hien thi ngay
else if ((mode ==7)|(mode ==8)|mode==12)
out_led(h1,m1,0xa1); // hien thi gio bat
else if ((mode == 9)|(mode ==10)|mode==13)
out_led(h0,m0,0xa0); // hien thi gio tat
else if (mode==14)
out_led((0xaa),0xaa,0xa0 | role);
}
}
//=======================================================================
//starts i2c, if both SCK & SDA are idle
void start(void)
{
if(SCK==0) //check SCK. if SCK busy, return else SCK idle
return;
if(SDA==0) //check SDA. if SDA busy, return else SDA idle
return;
SDALOW //data low
delay_us
SCKLOW  //clock low  
}        

//stops i2c, releasing the bus
//=======================================================================
void stop(void)
{      
SDALOW //data low
SCKHIGH //clock high
delay_us
SDAHIGH //data high
//delay_us
}
//transmits one byte of data to i2c bus
//=======================================================================
void send_byte(unsigned char c)
{
unsigned mask=0x80;
do  //transmits 8 bits
{
if(c&mask) //set data line accordingly(0 or 1)
SDAHIGH //data high
else
SDALOW //data low
SCKHIGH   //clock high
delay_us
SCKLOW   //clock low
delay_us
mask/=2;  //shift mask
}while(mask>0);
SDAHIGH  //release data line for acknowledge
SCKHIGH  //send clock for acknowledge
delay_us
slave_ack=SDA; //read data pin for acknowledge
SCKLOW  //clock low
delay_us
}    
//receives one byte of data from i2c bus
unsigned char receive_byte(unsigned char master_ack)
{
unsigned char c=0,mask=0x80;
do  //receive 8 bits
{
SCKHIGH //clock high
delay_us
if(SDA==1) //read data
c|=mask;  //store data
SCKLOW  //clock low
delay_us
mask/=2; //shift mask
}while(mask>0);
if(master_ack==1)
SDAHIGH //don't acknowledge
else
SDALOW //acknowledge
SCKHIGH //clock high
delay_us
SCKLOW //clock low
delay_us
SDAHIGH //data high
return c;
}
//writes one byte of data(c) to slave device(device_id) at given address(location)
void write_i2c(unsigned char device_id,unsigned char location,unsigned char c)
{
do
{
start();      //starts i2c bus
send_byte(device_id); //select slave device
if(slave_ack==1)  //if acknowledge not received, stop i2c bus
stop();
}while(slave_ack==1); //loop until acknowledge is received
send_byte(location); //send address location
send_byte(c); //send data to i2c bus
stop(); //stop i2c bus
delay_ms(4);
}    

//reads one byte of data(c) from slave device(device_id) at given address(location)
unsigned char read_i2c(unsigned char device_id,unsigned char location)
{
unsigned char c;
do
{
start();   //starts i2c bus
send_byte(device_id); //select slave device
if(slave_ack==1) //if acknowledge not received, stop i2c bus
stop();
}while(slave_ack==1); //loop until acknowledge is received
send_byte(location);  //send address location    
stop(); //stop i2c bus
start(); //starts i2c bus
send_byte(device_id+1); //select slave device in read mode
c=receive_byte(1); //receive data from i2c bus
stop(); //stop i2c bus
return c;
}    
//generates delay in milli seconds
//==================================================================================
void delay_ms(unsigned int i)
{unsigned int j;
while(i-->0){   for(j=0;j<400;j++){}}} // j < 40 la chuan
//=======================================================================
void menu (void)// quyet phim
 {  t=0; // xoa bien hoi phuc hien thi gio
  x++;
if (x>=5) { x=0;// x >= 10 la hop ly
if (menu_key == 0 ) press = 1;
else if (up_key == 0)   press = 2;
else if (down_key == 0) press = 3;}}          
III. Video Mô phỏng



IV. Nhận Thiết kế Nguyên lý - Layout - Mạch in Trên:
- Altium Designer
- Orcad 9.2
- Protues
- Eagle
Liên hệ; echipkool.com@gmail.com hoặc Hotline:  01666.661.219

Tác giả:danghuunho@gmail.com

Điện Tử | Tin Học - echipkool.com - Chia sẻ kiến thức - Kết nối đam mê điện tử

0 Response to "[Share] Mạch đồng hồ Giờ phút giây - Ngày tháng năm 2 IN 1"

Đăng nhận xét