Đồng hồ thời gian thực DS1307+PIC16 hiển thị dd/mm/yy,temperature,cài đặt giá trị thời gian



Main chính:

//#include <RTC_clock.h>
#include <16f887.h>
#device ADC=8
#use delay(clock=12m)
#define alarm  input(pin_B7)
#define set   input(pin_B3)
#define up    input(pin_B4)
#define down  input(pin_B5)
#define ok    input(pin_B6)
#use i2c(master, sda=pin_B2, scl=pin_B1)
unsigned char so[11]={64,121,36,48,25,18,2,120,0,16,70};
unsigned char i,year,month,date,day,hour,min,sec,b,kt,a;
char t;
char set0,set1,up0,up1,down0,down1;
#include<lunar.h>
#include<ds1307.h>
#include<ktphim.h>
#include<hienthi.h>
#int_timer0
void timer0interrupt()
{
   b++;
   if(b==20)output_high(pin_D2);
   if(b==40){output_low(pin_D2);b=0;}
}
void biip()
{
   unsigned char n;
    for(n=0;n<100;n++)
    {
        output_high(pin_E0); delay_ms(100);
         output_low(pin_E0); delay_ms(100);
    }   
}
#int_EXT //ngat ngoai RB0
void EXT_RB0(void)//cu moi lan co ngat ngoai thi doc du lieu (1s doc 1lan)
{
   a++;
   get_time();
   if(a==5)
   {
      t=read_adc();
      lunar_calculate(date,month,year);
      a=0;
   }
}
void main()
{
   setup_timer_0 (RTCC_DIV_256);
   ENABLE_INTERRUPTS(INT_TIMER0);
   set_timer0(0);
   ext_int_edge(0,H_TO_L);//chon ngat ngoai 0, suon ngat la suon xuong
   enable_interrupts(GLOBAL);//cho phep ngat toan cuc
   setup_adc(ADC_CLOCK_INTERNAL);//ADC lam viec voi nguon xung noi
   setup_adc_ports(sAN0);//chon kenh ADC
   setup_rtc();
   while(1)
   { 
      ktphim();    
      hien_thi();
   }
}

Main phụ hỗ trợ :

Ds1307.h:
 
unsigned char dec2bcd(unsigned char temp)
{
   return((temp/10)*16)+(temp%10);
}
unsigned char bcd2dec(unsigned char temp)
{
   return((temp/16)*10)+(temp%16);
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void write_rtc(char addr,value)
{
   i2c_start();//start i2c
   i2c_write(0xd0);//0xd0 la ID cua DS1307
   i2c_write(addr);
   i2c_write(value);
   i2c_stop();  
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void setup_rtc()
{
   write_rtc(0x07,0x90);//tao xung 1 hz 
}
void get_time()
{
  i2c_start();
  i2c_write(0xD0);//0xD0 la dia chi cua DS1307
  i2c_write(0x00);// Start at REG 0 - Seconds
  i2c_start();
  i2c_write(0xD1);//0xD1 che do doc du lieu
  sec    =bcd2dec(i2c_read()&0x7f); //REG 0
  min    =bcd2dec(i2c_read()&0x7f); //REG 1
  hour   =bcd2dec(i2c_read()&0x3f); //REG 2
  day    =i2c_read()&0x07;          //REG 3
  date   =bcd2dec(i2c_read()&0x3f); //REG 4
  month  =bcd2dec(i2c_read()&0x1f); //REG 5
  year   =bcd2dec(i2c_read(0));     //REG 6
  i2c_stop();
}

ktphim.h:

 void ktphim()
{
   set0=set1;set1=set;
   if((set0==1)&&(set1==0))
   {
      kt++;
      if(kt==7)kt=0;
   }
   if(!ok) kt=0;
   switch(kt)
   {
      case 0: break;
      case 1:
      {
         up0=up1;up1=up;b=1;
         if((up0==1)&&(up1==0))
         {
            hour++;
            if(hour==24)hour=0;
         }
         down0=down1;down1=down;
         if((down0==1)&&(down1==0))
         {
            hour--;
            if(hour==-1)hour=23;
         }
         write_rtc(0x02, dec2bcd(hour));
         break;
      }
      case 2:
      {
         up0=up1;up1=up;b=1;
         if((up0==1)&&(up1==0))
         {
            min++;
            if(min==60)min=0;
         }
         down0=down1;down1=down;
         if((down0==1)&&(down1==0))
         {
            min--;
            if(min==-1)min=59;
         }
         write_rtc(0x01, dec2bcd(min));
         break;
      }
      case 3:
      {
         up0=up1;up1=up;b=1;
         if((up0==1)&&(up1==0))
         {
            date++;
            if((month==4)||(month==6)||(month==9)||(month==11)){if(date==31)date=1;}
            if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12)){if(date==32)date=1;}
            if((month==2)&&(year%4!=0)){if(date==29)date=1;}
            if((month==2)&&(year%4==0)){if(date==30)date=1;}              
               }
         down0=down1;down1=down;
         if((down0==1)&&(down1==0))
         {
            date--;
            if((month==4)||(month==6)||(month==9)||(month==11)){if(date==0)date=30;}
            if((month==1)||(month==3)||(month==5)||(month==7)||(month==8)||(month==10)||(month==12)){if(date==0)date=31;}
            if((month==2)&&(year%4!=0)){if(date==0)date=28;}
            if((month==2)&&(year%4==0)){if(date==0)date=29;}
         }
         write_rtc(0x04, dec2bcd(date));
         break;
      }
      case 4:
      {
         up0=up1;up1=up;b=1;
         if((up0==1)&&(up1==0))
         {
            month++;
            if(month==13)month=1;
         }
         down0=down1;down1=down;
         if((down0==1)&&(down1==0))
         {
            month--;
            if(month==0)month=12;
         }
         write_rtc(0x05, dec2bcd(month));
         break;
      }
      case 5:
      {
         up0=up1;up1=up;b=1;
         if((up0==1)&&(up1==0))
         {
            year++;
            if(year==31)year=13;
         }
         down0=down1;down1=down;
         if((down0==1)&&(down1==0))
         {
            year--;
            if(year==13)year=30;
         }
         write_rtc(0x06, dec2bcd(year));
         break;
      }
      case 6:
      {
         up0=up1;up1=up;b=1;
         if((up0==1)&&(up1==0))
         {
            day++;
            if(day==8)day=1;
         }
         down0=down1;down1=down;
         if((down0==1)&&(down1==0))
         {
            day--;
            if(day==0)day=7;
         }
         write_rtc(0x03, dec2bcd(day));
         break;
      }
   }
}


hienthi.h

void dat(char n)
{
   if(n==0)output_low(pin_D0);
   if(n==1)output_high(pin_D0);
}
void clk(unsigned char n)
{
   while(n--)
   {output_high(pin_D1);output_low(pin_D1);}
}
void hien_thi()
{
   for(i=0;i<2;i++)
   { 
      if(kt==0)
      {
         enable_interrupts(INT_EXT);
         dat(1);clk(1);dat(0);
         clk(1);output_c(so[hour/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[hour%10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[min/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[min%10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[sec/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[sec%10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[date/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[date%10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[month/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[month%10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[year/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[year%10]);delay_ms(1);output_c(0xff);
         clk(1);if(day==1)output_c(so[10]);
         else output_c(so[day]);delay_ms(1);output_c(0xff); 
         clk(1);output_c(so[ldate/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[ldate%10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[lmonth/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[lmonth%10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[t/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[t%10]);delay_ms(1);output_c(0xff);   
         clk(1);
      }
      if(kt==1)
      {
         disable_interrupts(INT_EXT);
         dat(1);clk(1);dat(0);
         clk(1);output_c(so[hour/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[hour%10]);delay_ms(1);output_c(0xff);
         clk(16);
      }
      if(kt==2)
      {
         dat(1);clk(1);dat(0);
         clk(3);output_c(so[min/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[min%10]);delay_ms(1);output_c(0xff);
         clk(12);
      }
      if(kt==3)
      {
         dat(1);clk(1);dat(0);
         clk(7);output_c(so[date/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[date%10]);delay_ms(1);output_c(0xff);
         clk(4);
      }
      if(kt==4)
      {
         dat(1);clk(1);dat(0);
         clk(9);output_c(so[month/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[month%10]);delay_ms(1);output_c(0xff);
      }
      if(kt==5)
      {
         dat(1);clk(1);dat(0);
         clk(11);output_c(so[year/10]);delay_ms(1);output_c(0xff);
         clk(1);output_c(so[year%10]);delay_ms(1);output_c(0xff);
      }
      if(kt==6)
      {
         dat(1);clk(1);dat(0);
         clk(13);if(day==1)output_c(so[10]);
         else output_c(so[day]);delay_ms(1);output_c(0xff);
      }
   }
}

lunar.h:

unsigned char ldate,lmonth,da,db;
const unsigned char ALdauthangDL[18][12] =
{
   {20,21,20,21,22,23,24,25,26,27,28,29},//2013
   { 1, 2, 1, 2, 3, 4, 5, 6, 8, 8, 9,10},//2014
   {11,13,11,13,13,15,16,17,19,19,20,20},//2015
   {22,23,23,24,25,26,27,29, 1, 1, 2, 3},//2016
   { 4, 5, 4, 5, 6, 7, 8,10,11,12,13,14},//2017
   {15,16,14,16,16,18,18,20,22,22,24,25},//2018
   {26,27,25,27,27,28,29, 1, 3, 3, 5, 6},//2019
   { 7, 8, 8, 9, 9,10,11,12,14,15,16,17},//2020

   {19,20,18,20,20,21,22,23,25,25,27,27},//2021
   {29, 1,29, 1, 1, 3, 3, 4, 6, 6, 8, 8},//2022
   {10,11,20,11,12,14,14,15,17,17,18,19},//2023
   {20,22,21,23,23,25,26,27,29,29, 1, 1},//2024
   { 2, 4, 2, 4, 4, 6, 7, 8,10,10,12,12},//2025
   {13,14,13,14,15,16,17,19,20,21,23,23},//2026
   {24,25,24,25,25,27,27,29, 1, 2, 4, 4},//2027  
   { 5, 7, 6, 7, 7, 9, 9,11,13,13,15,16},//2028
   {17,18,17,18,18,20,20,22,23,24,25,26},//2029
   {28,29,28,29,29, 1, 1, 3, 4, 5, 6, 7}//2030
};

const unsigned char thangALdauthangDL[18][12] =
{
   {11,12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10},//2013
   {12, 1, 2, 3, 4, 5, 6, 7, 8, 9, 9,10},//2014
   {11,12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10},//2015
   {11,12, 1, 2, 3, 4, 5, 6, 8, 9,10,11},//2016
   {12, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9,10},//2017
   {11,12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10},//2018
   {11,12, 1, 2, 3, 4, 5, 7, 8, 9,10,11},//2019
   {12, 1, 2, 3, 4, 4, 5, 6, 7, 8, 9,10},//2020

   {11,12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10},//2021
   {11, 1, 1, 3, 4, 5, 6, 7, 8, 9,10,11},//2022
   {12, 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10},//2023
   {11,12, 1, 2, 3, 4, 5, 6, 7, 8,10,11},//2024
   {12, 1, 2, 3, 4, 5, 6, 6, 7, 8, 9,10},//2025
   {11,12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10},//2026
   {11,12, 1, 2, 3, 4, 5, 6, 8, 9,10,11},//2027
   {12, 1, 2, 3, 4, 5, 5, 6, 7, 8, 9,10},//2028
   {11,12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10},//2029
   {11,12, 1, 2, 3, 5, 6, 7, 8, 9,10,11}//2030
};

const unsigned char DLdauthangAL[18][12] =
{
   {12,10,12,10,10, 8, 8, 7, 5, 5, 3, 3},//2013
   {31,31,31,29,29,27,27,25,24,24,22,22},//2014
   {20,19,20,19,18,16,16,14,13,13,12,11},//2015
   {10, 8, 9, 7, 7, 5, 4, 3, 1,31,29,29},//2016
   {28,26,28,26,26,24,23,22,20,20,18,18},//2017
   {17,16,17,16,15,14,13,11,10, 9, 7, 7},//2018
   { 6, 5, 6, 5, 5, 3, 3,30,29,28,26,26},//2019
   {25,23,24,23,23,21,21,19,17,17,15,14},//2020

   {13,12,13,12,12,10,10, 8, 7, 6, 5, 4},//2021
   { 3,29, 3,31,30,29,29,27,26,25,24,23},//2022
   {22,20,22,20,19,18,18,16,15,15,13,13},//2023
   {11,10,10, 9, 8, 6, 6, 4, 3, 3,31,31},//2024
   {29,28,29,28,27,25,25,23,22,21,20,20},//2025
   {19,17,19,17,17,15,14,13,11,10, 9, 9},//2026
   { 8, 6, 8, 7, 6, 5, 4, 1,30,29,28,28},//2027
   {26,25,26,25,24,23,22,20,19,18,16,16},//2028
   {15,23,15,14,13,12,11,10, 8, 8, 6, 5},//2029
   { 4, 2, 4,31, 2,30,30,29,27,27,25,25}//2030
};

const unsigned char thangALdauthangAL[18][12] =
{
   {12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11},//2013
   { 1, 2, 3, 4, 5, 6, 7, 8, 9, 9,10,11},//2014
   {12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11},//2015
   {12, 1, 2, 3, 4, 5, 6, 7, 8,10,11,12},//2016
   { 1, 2, 3, 4, 5, 6, 6, 7, 8, 9,10,11},//2017
   {12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11},//2018
   {12, 1, 2, 3, 4, 5, 6, 8, 9,10,11,12},//2019
   { 1, 2, 3, 4, 4, 5, 6, 7, 8, 9,10,11},//2020

   {12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11},//2021
   {12, 1, 2, 3, 5, 6, 7, 8, 9,10,11,12},//2022
   { 1, 2, 2, 3, 4, 5, 6, 7, 8, 9,10,11},//2023
   {12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,12},//2024
   { 1, 2, 3, 4, 5, 6, 6, 7, 8, 9,10,11},//2025
   {12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11},//2026
   {12, 1, 2, 3, 4, 5, 6, 7, 9,10,11,12},//2027
   {1, 2, 3, 4, 5, 5, 6, 7, 8, 9, 10,11},//2028
   {12, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11},//2029
   {12, 1, 2, 3, 4, 5, 7, 8, 9,10,11,12}//2030
};
void lunar_calculate(date,month,year)
{
   da = ALdauthangDL[year-13][month-1];
   db = DLdauthangAL[year-13][month-1];
   if((db-date)<=0||(db-date)>31)
   {
      ldate = date-db+1;
      lmonth = thangALdauthangAL[year-13][month-1];
   }
   else
   {
      ldate = (date+da-1);
      lmonth = thangALdauthangDL[year-13][month-1];
   }
}  


RTC.h :

BYTE bin2bcd(BYTE binary_value);
BYTE bcd2bin(BYTE bcd_value);

void ds1307_init(void)
{
   BYTE initsec = 0;
   BYTE initmin=0;
   BYTE inithr=0;                 
   BYTE initdow=0;
   BYTE initday=0;                  
   BYTE initmth=0;
   BYTE inityear=0;
   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_start();
   i2c_write(0xD1);      // RD from RTC
   initsec  = bcd2bin(i2c_read() & 0x7f);
   initmin  = bcd2bin(i2c_read() & 0x7f);
   inithr   = bcd2bin(i2c_read() & 0x3f);
   initdow  = bcd2bin(i2c_read() & 0x7f);   // REG 3
   initday  = bcd2bin(i2c_read() & 0x3f);   // REG 4
   initmth  = bcd2bin(i2c_read() & 0x1f);   // REG 5
   inityear = bcd2bin(i2c_read(0));         // REG 6
   i2c_stop();
   delay_us(3);

   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x00);      // REG 0
   i2c_write(bin2bcd(initsec));      // Start oscillator with current "seconds value
   i2c_write(bin2bcd(initmin));      // REG 1
   i2c_write(bin2bcd(inithr));       // REG 2
   i2c_write(bin2bcd(initdow));      // REG 3
   i2c_write(bin2bcd(initday));      // REG 4
   i2c_write(bin2bcd(initmth));      // REG 5
   i2c_write(bin2bcd(inityear));     // REG 6
   i2c_start();
   i2c_write(0xD0);      // WR to RTC
   i2c_write(0x07);      // Control Register
   i2c_write(0x90);      //  squarewave output pin 1Hz
   i2c_stop();

}

void ds1307_set_date_time(BYTE day, BYTE mth, BYTE year, BYTE dow, BYTE hr, BYTE min, BYTE sec)
{
  sec &= 0x7F;
  hr &= 0x3F;

  i2c_start();
  i2c_write(0xD0);              // I2C write address
  i2c_write(0x00);              // Start at REG 0 - Seconds
  i2c_write(bin2bcd(sec));      // REG 0
  i2c_write(bin2bcd(min));      // REG 1
  i2c_write(bin2bcd(hr));       // REG 2
  i2c_write(bin2bcd(dow));      // REG 3
  i2c_write(bin2bcd(day));      // REG 4
  i2c_write(bin2bcd(mth));      // REG 5
  i2c_write(bin2bcd(year));     // REG 6
  i2c_write(0x90);              // REG 7 - 1Hz squarewave output pin
  i2c_stop();
}

void ds1307_get_date(BYTE &day, BYTE &mth, BYTE &year, BYTE &dow)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x03);              // Start at REG 3 - Day of week
  i2c_start();
  i2c_write(0xD1);
  dow  = bcd2bin(i2c_read() & 0x7f);   // REG 3
  day  = bcd2bin(i2c_read() & 0x3f);   // REG 4
  mth  = bcd2bin(i2c_read() & 0x1f);   // REG 5
  year = bcd2bin(i2c_read(0));         // REG 6
  i2c_stop();
}

void ds1307_get_time(BYTE &hr, BYTE &min, BYTE &sec)
{
  i2c_start();
  i2c_write(0xD0);
  i2c_write(0x00);                     // Start at REG 0 - Seconds
  i2c_start();
  i2c_write(0xD1);
  sec = bcd2bin(i2c_read() & 0x7f);
  min = bcd2bin(i2c_read() & 0x7f);
  hr  = bcd2bin(i2c_read(0) & 0x3f);
  i2c_stop();

}

BYTE bin2bcd(BYTE binary_value)
{
  BYTE temp;
  BYTE retval;

  temp = binary_value;
  retval = 0;

  while(TRUE)
  {
    // Get the tens digit by doing multiple subtraction
    // of 10 from the binary value.
    if(temp >= 10)
    {
      temp -= 10;
      retval += 0x10;
    }
    else // Get the ones digit by adding the remainder.
    {
      retval += temp;
      break;
    }
  }

  return(retval);
}


// Input range - 00 to 99.
BYTE bcd2bin(BYTE bcd_value)
{
  BYTE temp;

  temp = bcd_value;
  // Shifting upper digit right by 1 is same as multiplying by 8.
  temp >>= 1;
  // Isolate the bits for the upper digit.
  temp &= 0x78;

  // Now return: (Tens * 8) + (Tens * 2) + Ones

  return(temp + (temp >> 2) + (bcd_value & 0x0f));
}


Link dowload :

Previous
Next Post »