BMS- Building Management System - Hệ thống CHILLER điều khiển tự động cho nhà máy

Xin chào, lâu rồi mình mới viết Blog lại do công việc bận quá chưa sắp xếp được. Hôm nay mình gửi đến các bạn một phần trong dự án mà mình thực hiện trong năm 2018.
Hệ thống BMS, hệ thống quản lí tòa nhà đang là một xu hướng phát triển mạnh, yêu cầu tiên quyết để một tòa nhà, một nhà máy hoạt động và đưcọ cấp tiêu chuẩn quốc tế là địa điểm đó phải có các hệ thống hoạt động đảm bảo an toàn, đảm bảo các yêu câu theo tiêu chuẩn về điện, nước, lạnh, báo cháy... Vì thế việc xây dựn một hệ thống quản lí toàn diện các thiết bị hệ thống : điện, nước, báo cháy, thang máy, camera, lạnh. HVAC, ... là điều cần thiết và đảm bảo hoạt động không dư thừa về điện, nước,... Nếu các bạn vẫn đãng hoang mang không biết nó là hệ thống gì, các bạn có thể tìm hiểu nó thông qua .... key word : BMS, building management system.
Hệ thống CHILLER ( một phần trong hệ thống BMS ) trong nhà máy sản xuất bao bì :

GIỚI THIỆU :
    Hệ thống CHILLER : được hiểu đơn giản là một hệ thống máy lạnh công suất lớn, cung cấp lạnh cho hệ thống tòa nhà, hệ thống nhà máy.
    Hệ thống CHILLER bao gồm :
              + Tháp giải nhiệt : bể chứa nước, cung cấp và giải nhiệt cho nước
              + Bơm giải nhiệt : bơm giải nhiệt cho máy làm lạnh Chiller
              + Bơm nước lạnh : bơm nước lạnh cho máy làm lạnh Chiller
              + Máy làm lạnh Chiller : Máy làm lạnh công suất lớn ( 800 tons, 1200 tons,...)
       Và một có thiết bị trường cho việc điều khiển hệ thống : cảm biến nhiệt độ trên đường ống, cảm biến chênh áp, cảm biến đo lưu lượng nước, công tắc báo nước,...

Việc điều khiển hoạt động của hệ thống làm lạnh công suất lớn như thế này là cực kì khó và phải đảm bảo yêu cầu hoạt động, các tiêu chuẩn về điện, về nước cho nhà máy hoặc tòa nhà.

Việc điều khiển hoạt động của hệ thống sẽ hoạt động theo một chu trình sau :

CHU TRÌNH HOẠT ĐỘNG :

VALVE THÁP GIẢI NHIỆT ---->>>--- THÁP GIẢI NHIỆT  --->>>---- VALVE GIẢI NHIỆT ---->>>---- BƠM GIẢI NHIỆT ---->>>----VALVE NƯỚC LẠNH ---->>>---- BƠM NƯỚC LẠNH ---->>>---- CHILLER.

CHU TRÌNH DỪNG :

CHILER ---->>>---- BƠM NƯỚC LẠNH ---->>>---- VALVE NƯỚC LẠNH ---->>>---- BƠM GIẢI NHIỆT ---->>>---- VALVE GIẢI NHIỆT ---->>>---- THÁP GIẢI NHIỆT ---->>>----VALVE THÁP GIẢI NHIỆT.

Nếu các bạn chưa hiểu hệ thống chiller hoạt động có thể đọc các tài liệu liên quan .

Một số hình ảnh của hệ thống hoạt động.

Hình ảnh HMI điều khiển :







Hình ảnh thực tế về hệ thống chiller :











Các hình ảnh từ lúc bắt đầu đến lúc hoàn thiện và đi vào hoạt động.
Các bạn có thắc mắc hoặc có vấn đề có thể trao đổi qua email : phanhoangthinhhg@gmail.com

Hướng dẫn cài đặt các phần mềm dùng cho lập trình Scada

Hướng dẫn cài đặt các phần mềm dùng cho lập trình Scada

Đầu tiên các bạn Download về những phần mềm sau :

Những bản sofware này dùng cho PC win7 64-bit .Đã test thành công nhé.

Link download phần mềm TIA V13 SP1 : TIAV13 SP1
Link download phần mềm mô phỏng :  PLCSIM V13 SP1
Link download WinCC Advance V13 SP1: D1 và D2
Link download WinCC Pro V13 SP1 : Dis0  và  Dis1 (Có thể tải hoặc không)
WinCC 7.4 : WinCC7.4
 (Riêng WinCC 7.4 pass : congdongdien.com )
Link Crack full all version : Download in there  
Các bạn download về xong cho mỗi software vào riêng một thư mục của nó và giải nén ra.

B1: Run Tia V13 SP1 . Khi chạy xong rồi các bạn Restart lại PC .
B2: Run PLCSIM V13 SP1 và Restart lại PC.
B3: Run WinCC Adance V13 SP1 và Restart lại PC.
B4: Run WinCC 7.4( tắt các phần mềm diệt virut) : phần này để chọn cài đặt các bạn chỉ chọn bản WinCC installion..)
B5: Nếu bạn có tải WinCC Pro V13 SP1 thì giờ có thể cài vào rồi, bởi vì bản Advance V13 SP1 cũng chạy không kém gì Pro nên WinCC Pro này dành cho PC có cấu hình cao nhé.

Đồ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 :

Matrix hiển thị trái tim 3 màu di chuyển từ dưới lên trên





// PIC16F887 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF        // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)

// CONFIG2
#pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.





#include <xc.h>
#define _XTAL_FREQ 4000000
const unsigned char chonhang[]={0xFE,0xFD,0xFB,0xF7,0xEF,0xDF,0xBF,0x7F};


const unsigned char maled_do[]={  
                         
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,
0x00,0x00,0x00,0x00,0x00,0x00,0x66,0xFF,
0x00,0x00,0x00,0x00,0x00,0x66,0xFF,0xFF,
0x00,0x00,0x00,0x00,0x66,0xFF,0xFF,0xFF,
0x00,0x00,0x00,0x66,0xFF,0xFF,0xFF,0x7E,
0x00,0x00,0x00,0xFF,0xFF,0xFF,0x7E,0x3C,
0x00,0x00,0x00,0xFF,0xFF,0x7E,0x3C,0x18,
0x00,0x00,0x00,0xFF,0x7E,0x3C,0x18,0x00,
0x00,0x00,0x00,0x7E,0x3C,0x18,0x00,0x00,
0x00,0x00,0x00,0x3C,0x18,0x00,0x00,0x00,
0x00,0x00,0x00,0x18,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x40,0x20,0x10,0x00,0x00,0x00,0x00,0x00,
0xC0,0x60,0x30,0x18,0x00,0x00,0x00,0x00,
0xC0,0xE0,0x70,0x38,0x18,0x00,0x00,0x00,
0xC0,0xE0,0xF0,0x78,0x3C,0x18,0x00,0x00,
0x40,0xE0,0xF0,0xF8,0x7C,0x3C,0x18,0x00,
0x00,0x60,0xF0,0xF8,0xFC,0x7E,0x3C,0x18,
0x00,0x00,0x60,0xF8,0xFC,0xFE,0x7E,0x3C,
0x00,0x00,0x00,0x60,0xFC,0xFE,0xFF,0x7E,
0x00,0x00,0x00,0x00,0x64,0xFE,0xFF,0xFF,
0x00,0x00,0x00,0x00,0x00,0x66,0xFF,0xFF,
0x00,0x00,0x00,0x00,0x00,0x00,0x66,0xFF,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x66,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};

const unsigned char maled_xanh[]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x66,0x00,0x00,0x00,
0x00,0x00,0x00,0x66,0xFF,0x00,0x00,0x00,
0x00,0x00,0x66,0xFF,0xFF,0x00,0x00,0x00,  
0x00,0x66,0xFF,0xFF,0xFF,0x00,0x00,0x00,
0x66,0xFF,0xFF,0xFF,0x7E,0x00,0x00,0x00,
0xFF,0xFF,0xFF,0x7E,0x3C,0x00,0x00,0x00,
0xFF,0xFF,0x7E,0x3C,0x18,0x00,0x00,0x00,
0xFF,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,
0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,
0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,

0x18,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x3C,0x18,0x00,0x00,0x00,0x00,0x00,0x00,
0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,0x00,
0xFF,0x7E,0x3C,0x18,0x00,0x00,0x00,0x00,
0xFF,0xFF,0x7E,0x3C,0x18,0x00,0x00,0x00,
0xFF,0xFF,0x7F,0x3E,0x1C,0x08,0x00,0x00,
0x66,0xFF,0x7F,0x3F,0x1E,0x0C,0x00,0x00,
0x00,0x66,0x7F,0x3F,0x1F,0x0E,0x04,0x00,
0x00,0x00,0x66,0x3F,0x1F,0x0F,0x06,0x00,
0x00,0x00,0x00,0x26,0x1F,0x0F,0x07,0x02,
0x00,0x00,0x00,0x00,0x06,0x0F,0x07,0x03,
0x00,0x00,0x00,0x00,0x00,0x06,0x07,0x03,
0x00,0x00,0x00,0x00,0x00,0x00,0x06,0x03,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x02,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,


0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};









int i=0;
int j=0;
int dat=0;
void main(void)
{
    ANSEL=0x00;
    ANSELH=0x00;
    TRISB=0;
    TRISC=0;
    TRISD=0;
    dat=0;

    while(1)
    {

        if(dat>=240)
        {
            dat=0;
        }
        for(j=0;j<=50;j++)
        {
            for(i=0;i<=7;i++)
            {
                PORTB=chonhang[i];
                PORTC=maled_do[dat+i];
                PORTD=maled_xanh[dat+i];
                __delay_ms(10);
            //}
            }
        }
            dat=dat+8;
       
    }
}

LED Matrix hiển thị trái tim dịch từ dưới lên trên





// PIC16F887 Configuration Bit Settings

// 'C' source line config statements

// CONFIG1
#pragma config FOSC = HS        // Oscillator Selection bits (HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF         // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF        // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = OFF      // Brown Out Reset Selection bits (BOR disabled)
#pragma config IESO = OFF       // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF        // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)

// CONFIG2
#pragma config BOR4V = BOR40V   // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF        // Flash Program Memory Self Write Enable bits (Write protection off)

// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.

#include <xc.h>


#define _XTAL_FREQ 4000000
const unsigned char choncot[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
const unsigned char maled[]={0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                        0xFF,0x7F,0x7F,0xFF,0xFF,0x7F,0x7F,0xFF,
                        0x7F,0x3F,0x3F,0x7F,0x7F,0x3F,0x3F,0x7F,
                        0x3F,0x1F,0x1F,0x3F,0x3F,0x1F,0x1F,0x3F,
                        0x1F,0x0F,0x0F,0x1F,0x1F,0x0F,0x0F,0x1F,
                        0x8F,0x07,0x07,0x0F,0x0F,0x07,0x07,0x8F,
                        0xC7,0x83,0x03,0x07,0x07,0x03,0x83,0xC7,
                        0xE3,0xC1,0x81,0x03,0x3,0x81,0xC1,0xE3,
                        0xF1,0xE0,0xC0,0x81,0x81,0xC0,0xE0,0xF1,
                        0xF8,0xF0,0xE0,0xC0,0xC0,0xE0,0xF0,0xF8,
                        0xFC,0xF8,0xF0,0xE0,0xE0,0xF0,0xF8,0xFC,
                        0xFE,0xFC,0xF8,0xF0,0xF0,0xF8,0xFC,0xFE,
                        0xFF,0xFE,0xFC,0xF8,0xF8,0xFC,0xFE,0xFF,
                        0xFF,0xFF,0xFE,0xFC,0xFC,0xFE,0xFF,0xFF,
                        0xFF,0xFF,0xFF,0xFE,0xFE,0xFF,0xFF,0xFF,
                        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
                        0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
};
const unsigned char maled1[]={
    0xFF,0x7F,0x7F,0xFF,0xFF,0x7F,0x7F,0xFF,
    0xFF,0x7F,0x7F,0xFF,0xFF,0x7F,0x7F,0xFF,
    0xFF,0x7F,0x7F,0xFF,0xFF,0x7F,0x7F,0xFF,
    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
    0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,
    0xFF,0x7F,0x7F,0xFF,0xFF,0x7F,0x7F,0xFF,
    0xFF,0x7F,0x7F,0xFF,0xFF,0x7F,0x7F,0xFF,
    0xFF,0x7F,0x7F,0xFF,0xFF,0x7F,0x7F,0xFF,
};
int i=0;
int j=0;
int dat=0;
void delay(void)
{
    __delay_ms(5);
}
void main(void)
{
    ANSEL=0x00;
    ANSELH=0x00;
    TRISB=0;
    TRISC=0;
//    TRISD=0;
    dat=0;
    while(1)
    {

        if(dat>=136)
        {
            dat=0;
        }
        for(j=0;j<=10;j++)
        {
            for(i=0;i<=7;i++)
            {
                PORTC=choncot[i];
//                PORTD=choncot[i];
                PORTB=maled[dat+i];
//                PORTB=maled1[dat+i];
                RB3=RB4=0;
                TRISD=0;
                PORTD=choncot[i];
                delay();                    
            }
            //}
           
        }
            dat=dat+8;
       
    }
}