tình hình là mình làm cái mạch chuông báo tiếc học nhưng khi khai báo viết code bằng keil c vesion 3 thì nó không hiểu mấy cái này có ai giúp mình với không và đây là lỗi của e nó mấy a giúp e với
#include <REGX51.H>
#include <ports.h>
#include <lcd.h>
#include <rtc.h>
extern bit aon,aoff;
unsigned char *rtc[]={"0","1","2","3","4","5","6","7","8","9"};
unsigned char *day[]={"C.Nhat: ","Thu 2: ","Thu 3: ","Thu 4: ","Thu 5: ","Thu 6: ","Thu 7: "};
unsigned char rtc_ini_val[9];
bit_8; code *intro[]={"MINH PHUNG - THI NHUNG"}
bit flag=0,aon=0,a0ff=0;
void busy()
{
D7=1;
rs=0;
rw=1;
while(D7!=0)
{
en=0;
en=1;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Ghi mot lenh cho LCD ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void wrt_cmd(bit_8 lcd)
{
busy();
rs=0; // chon thanh ghi lenh
rw=0; // ghi len lcd
lcd_port=lcd; // gia tri LCD
en=1; // cho phep muc cao
en=0; //xung cao xuong thap
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** hien thi 1 xau ki tu string ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void wrt_data(bit_8 *string)
{
bit_8 i;
for(i=0;string[i]!='\0';i++)
wrt_byte(string[i]);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** hien thi 1 byte du lieu len LCD ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void wrt_byte(bit_8 value)
{
busy();
rs=1;
rw=0;
lcd_port=value;
en=1;
en=0;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Khoi tao cho LCD****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void LCD_INI(void)
{
wrt_cmd(0X38); //khoi tao LCD o che do 2 dong &ma tran 5x7
wrt_cmd(0X0C); //bat hien thi tat con tro
wrt_cmd(0X01);//xoa man hinh hien thi
wrt_cmd(0X06);//dich contro sang phai
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** hien thi phan user mún gioi thieu len LCD **
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void disp_intro()
{
bit_8 i;
bit_16 j;
wrt_cmd(0x80);//dua con tro ve dau dong thu 2
wrt_data(intro[0]);
wrt_cmd(0xc0);
wrt_data(intro[1]);
for(i=0x5;i>0;i--)
for(j=0xffff;j>0;j--); //tre de nhin thay chuong trinh hien thi
}
void disp_data_rtc(unsigned char x)
{
unsigned char temp;
temp = x/0x10;
wrt_data(rtc[temp]);
temp = x%0x10;
wrt_data(rtc[temp]);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** RTC start condition ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void start_rtc(void) //dk start: 1 su cdoi tthai tu cao xuong thap tren duong sda trong khi
{ //duong scl dang o muc cao
scl=1;
sda=1;
_nop_();
_nop_();
sda=0;
scl=0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void stop_rtc(void) //dk stop: 1 su cdoi trang thai tu muc thap len cao tren duong sda trong khi duong
{ // slc dang o muc cao
sda=0;
scl=1;
_nop_();
_nop_();
sda=1;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** gui 1 dia chi co do dai 8 bit ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void send_adr(unsigned char x)
{
unsigned char i;
for(i=0;i<8;i++)
{
sda=(x&0x80)? 1:0; //dua bit du lieu ra chan SDA
scl=1;
_nop_();
_nop_();
scl=0;
x<<=1; //bit co trong so lon hon dc truyen truoc
}
scl=1; //nhan bit ACK tu SLAVER
_nop_();
_nop_();
scl=0;
}
unsigned char recv_rtc(void)
{
unsigned char Data,i;
for(i=0;i<8;i++) // nhan vao 8 bit
{
scl=1;
Data<<=1;
Data=Data|sda;
scl=0;
}
sda=1; //
scl=1; //master nhan/gui bit du lieu(sda) khi scl o muc cao
_nop_();
scl=0;
_nop_();//du lieu(sda) thay doi khi scl muc thap/
return Data;//tra gia tri cho ham
}
char recv_data(bit_8 x)
{ unsigned char Data;
start_rtc();
send_adr(0xd0);//
send_adr(x); //bat dau doc du lieu tu thanh ghi co dia chi 0x00
start_rtc();
send_adr(0xd1); //0xd0 + 0xd1 la dia chi cua ds1307 va che do doc du lieu
Data=recv_rtc();//con tro dang tro toi dia chi 0x0 chua du lieu second
stop_rtc();//Stop I2C
return Data;}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** khoi tao time cho RTC ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void RTC_INI(void)
{
unsigned char t;
for(t=0;t<9;t++)
{
start_rtc(); //DK start RTC
send_adr(0xd0); // gui dia chi ghi
send_adr(t); //gui dia chi thanh ghi can khoi tao
send_adr(rtc_ini_val[t]);//send data to write cho rtc
stop_rtc(); //dk stop
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Hien thi du lieu cua RTC len LCD ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void disp_rtc(void)
{
wrt_cmd(0xca); // ep con tro den vi tri thu 11 dong thu 2
disp_data_rtc(recv_data(0)); //hien thi giay , du lieu doc ra la ma bcd nhung ham hienthi_dulieu_rtc da chuyen sang dec roi
wrt_cmd(0xc7); // ep con tro den vi tri thu 8 dong thu 2
disp_data_rtc(recv_data(1)); // hien thi phut
wrt_byte(':');
wrt_cmd(0xc4); // ep con tro den vi tri thu 5 dong thu 2
disp_data_rtc(recv_data(2)); //hien thi gio
wrt_byte(':');
wrt_cmd(0xcd);
wrt_cmd(0x80); //ep con tro den dau dong thu 1
wrt_data(day[recv_data(3)-1]);//hien thi thu
wrt_cmd(0x88); //ep con tro den vi tri thu 8 dong thu 1
disp_data_rtc(recv_data(4)); //hien thi ngay
wrt_byte('/');
disp_data_rtc(recv_data(5)); //hien thi thang
wrt_byte('/');
disp_data_rtc(recv_data(6)); //nam
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
****cài dat time cho RTC ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void rtc_set()
{
bit_8 mins,hours,days,date,month,year;
mins = hex_dec(recv_data(1));
hours = hex_dec(recv_data(2));
days = hex_dec(recv_data(3));
date = hex_dec(recv_data(4));
month = hex_dec(recv_data(5));
year = hex_dec(recv_data(6));
wrt_cmd(1);
wrt_data("Chinh");
wrt_cmd(0x8C);
wrt_data("Gio");
wrt_cmd(0x0e);
wrt_cmd(0xc4);
data_in(hours);
wrt_byte(':');
data_in(mins);
wrt_cmd(0xC8);
while(TIME_KEY==0);
up: while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0); //neu co tac dong den phim bam thji kiem tra
if(INC_KEY==0) //neu INC_KEY dc nhan
{
mins++; //tang phut
if(mins==60) //neu phut=60
mins=0; //thi phut ve gtri 0
wrt_cmd(0xC7); //ghi gia tri phut tai vi tri dong 1 cot 7
data_in(mins); //hien thi phut
wrt_cmd(0x10); //dich tro sang trai
delay();
goto up; //tre
}
if(DEC_KEY==0)
{
mins--;
if(mins==0xff)
mins=59;
wrt_cmd(0xC7);
data_in(mins);
wrt_cmd(0x10);
delay();
goto up;
}
while(TIME_KEY==0);//ko lam gi ca
wrt_cmd(0xC5);//tro o vi tri 1,5
up1:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
hours++;
if(hours==24)
hours=0;
wrt_cmd(0xC4);
data_in(hours);
wrt_cmd(0xC5);
delay();
goto up1;
}
if(DEC_KEY==0)
{
hours--;
if(hours==0)
{
hours=23;
}
wrt_cmd(0xC4);
data_in(hours);
wrt_cmd(0xC5);
delay();
goto up1;
}
while(TIME_KEY==0);
wrt_cmd(1);
wrt_cmd(0x80);
wrt_data("Chinh");
wrt_cmd(0x8c);
wrt_data("Ngay");
wrt_cmd(0xc4);
data_in(date);
wrt_byte('/');
data_in(month);
wrt_byte('/');
data_in(year);
wrt_cmd(0xc5);
up2:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
date++;
if(date==32)
date=1;
wrt_cmd(0xC4);
data_in(date);
wrt_cmd(0x10);
delay();
goto up2;
}
if(DEC_KEY==0)
{
date--;
if(date==0)
date=31;
wrt_cmd(0xC4);
data_in(date);
wrt_cmd(0x10);
delay();
goto up2;
}
while(TIME_KEY==0);
wrt_cmd(0xC8);
up3:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
month++;
if(month==13)
month=1;
wrt_cmd(0xC7);
data_in(month);
wrt_cmd(0x10);
delay();
goto up3;
}
if(DEC_KEY==0)
{
month--;
if(month==0)
month=12;
wrt_cmd(0xC7);
data_in(month);
wrt_cmd(0x10);
delay();
goto up3;
}
while(TIME_KEY==0);
wrt_cmd(0xCB);
up4:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
year++;
if(year==100)
year=0;
wrt_cmd(0xCA);
data_in(year);
wrt_cmd(0x10);
delay();
goto up4;
}
if(DEC_KEY==0)
{
year--;
if(year==0xff)
year=99;
wrt_cmd(0xCA);
data_in(year);
wrt_cmd(0x10);
delay();
goto up4;
}
while(TIME_KEY==0);
wrt_cmd(1);
wrt_cmd(0x80);
wrt_data("Chinh");
wrt_cmd(0x8c);
wrt_data("Thu");
wrt_cmd(0xc4);
wrt_data(day[days-1]);
up6:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
days++;
if(days==8)
days=1;
wrt_cmd(0xC4);
wrt_data(day[days-1]);
delay();
goto up6;
}
if(DEC_KEY==0)
{
days--;
if(days==0)
days=7;
wrt_cmd(0xC4);
wrt_data(day[days-1]);
delay();
goto up6;
}
while(TIME_KEY==0);
wrt_cmd(1);
wrt_cmd(0xC);
rtc_ini_val[0] = 0x00;
rtc_ini_val[1] = dec_hex(mins);
rtc_ini_val[2] = dec_hex(hours);
rtc_ini_val[3] = dec_hex(days);
rtc_ini_val[4] = dec_hex(date);
rtc_ini_val[5] = dec_hex(month);
rtc_ini_val[6] = dec_hex(year);
rtc_ini_val[7] = 0x00;
rtc_ini_val[8] = '~';
RTC_INI();
wrt_cmd(1);
wrt_cmd(0x82);
wrt_data("DA CHINH");
wrt_cmd(0xC3);
wrt_data("XONG ROI");
delay();
delay();
delay();
delay();
delay();
wrt_cmd(1);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** kiem tra xem RTC có duoc cai dat chua ?
neu chua dung time thi no se khoi tao
nhu ben duoi ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void rtc_check(void)
{
bit_8 temp;
start_rtc();
send_adr(0xd0);
send_adr(0x08);//gui dia chi thanh ghi dieu khien 08H
start_rtc();
send_adr(0xd1); //dia chi doc RTC
temp=recv_rtc();// temp luu gia tri doc dc tu RTC tai dia chi thanh ghi dieu khien
stop_rtc();//dk dung RTC
if(temp!='~') //neu nó chua dc khoi tao tuc gia tri thanh ghi dk khac '~' thi thuc hien khoitao cho RTC
{
rtc_ini_val[0]=0x00;//secs=0
rtc_ini_val[1]=0x00;//mins=0
rtc_ini_val[2]=0x09;//khi tao 12h o che do 24h(xoa bit D7=0,D6=0)
rtc_ini_val[3]=0x01; //chu nhat
rtc_ini_val[4]=0x29;// ngay 16
rtc_ini_val[5]=0x05;// Thang 10
rtc_ini_val[6]=0x11;//nam 2010
rtc_ini_val[7]=0x0;//ko dung den nen gan cho no gtri 00
rtc_ini_val[8]='~';//dia chi
RTC_INI();
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Data Convert HEX-DEC and DEC-HEX ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
bit_8 hex_dec(bit_8 hex)
{
return((hex/0x10)*0xA+(hex%0x10));
}
/*====================================*/
bit_8 dec_hex(bit_8 dec)
{
return((dec/0xA)*0x10+(dec%0xA));
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** DELAY ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void delay(void)
{
bit_8 i,j;
TMOD=0x11;
for(i=0;i<2;i++)
{
TH1=0;
TH0=1;
TL1=0;
TL0=0;
TR1=1;
while(TF1!=1)
{
for(j=0;j<20;j++);
}
TF1=0;
TR0=1;
TR1=0;
while(TF0!=1)
{}
TF0=0;
TR0=0;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~
**** hien thi thang , neu <9 thi them 0 phia trc ***
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void data_in(bit_8 a)
{
bit_8 j;
j=a/10;
wrt_data(rtc[j]);
j=a%10;
wrt_data(rtc[j]);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~
****Chuong trình kiem tra hen gio bao chuong ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~*/
/*================================================= ==================*/
/*STT hour_ST min_ST hour_FN min_FN */
/*1 07------00------07------45 */
/*2 07------50------08------35 */
/*3 08------45------09------30 */
/*4 09------35------10------20 */
/*5 10------25------11------10 */
/*6 xx------xx------xx------xx */
/*7 xx------xx------xx------xx */
/*8 13------30------14------15 */
/*9 14------20------15------05 */
/*10 15------15------16------00 */
/*11 16------05------16------50 */
/*12 xx------xx------xx------xx */
/*================================================= ==================*/
void check_alarm()
{
bit_8 ah[]={7 ,9 ,10 ,14 ,16};
bit_8 am[]={45 ,30 ,20 ,15 ,0};
unsigned char i;//khai bao bien chay cho mang h hen
// kiem tra cac truong hop dac biet time khi bat dau va ket thuc
if(((hex_dec(recv_data(2))==7)&&((hex_dec(recv_dat a(1)))==0))||((hex_dec(recv_data(2))==8)&&((hex_de c(recv_data(1)))==35))||((hex_dec(recv_data(2))==8 )&&((hex_dec(recv_data(1)))==45))||((hex_dec(recv_ data(2))==11)&&((hex_dec(recv_data(1)))==10))||((h ex_dec(recv_data(2))==13)&&((hex_dec(recv_data(1)) ==30)))||((hex_dec(recv_data(2))==15)&&((hex_dec(r ecv_data(1)))==5))||((hex_dec(recv_data(2))==15)&& ((hex_dec(recv_data(1)))==15))||((hex_dec(recv_dat a(2))==16)&&((hex_dec(recv_data(1)))==50)))
{
if(hex_dec(recv_data(0))<10)
{
aoff=1;
aon =0;
}
}
else//ngoai ra neu ko phai cac gia tri tren thi kiem tra xem cso thoa man diu kien duoi day ko?
{
for (i=0;i<11;i++)
{
if((hex_dec(recv_data(2))==ah[i])&&(((hex_dec(recv_data(1)))==am[i])||((hex_dec(recv_data(1)))==am[i]+5)))
{
if(hex_dec(recv_data(0))<5)
{
aoff=1;
aon =0;
}
}
}
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** chuong trình chuông báo ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void ring_alarm()
{
alarm_port=~alarm_port;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
alarm_port=~alarm_port;
alarm_port=~alarm_port;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
alarm_port=~alarm_port;
DELAY ;
alarm_port=~alarm_port;
alarm_port=~alarm_port;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
alarm_port=~alarm_port;
alarm_port=0;
aoff=0;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** THE ++++END ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void disp_data_rtc(unsigned char x)
{
unsigned char temp;
temp = x/0x10;
wrt_data(rtc[temp]);
temp = x%0x10;
wrt_data(rtc[temp]);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** RTC start condition ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void start_rtc(void) //dk start: 1 su cdoi tthai tu cao xuong thap tren duong sda trong khi
{ //duong scl dang o muc cao
scl=1;
sda=1;
_nop_();
_nop_();
sda=0;
scl=0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void stop_rtc(void) //dk stop: 1 su cdoi trang thai tu muc thap len cao tren duong sda trong khi duong
{ // slc dang o muc cao
sda=0;
scl=1;
_nop_();
_nop_();
sda=1;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** gui 1 dia chi co do dai 8 bit ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void send_adr(unsigned char x)
{
unsigned char i;
for(i=0;i<8;i++)
{
sda=(x&0x80)? 1:0; //dua bit du lieu ra chan SDA
scl=1;
_nop_();
_nop_();
scl=0;
x<<=1; //bit co trong so lon hon dc truyen truoc
}
scl=1; //nhan bit ACK tu SLAVER
_nop_();
_nop_();
scl=0;
}
unsigned char recv_rtc(void)
{
unsigned char Data,i;
for(i=0;i<8;i++) // nhan vao 8 bit
{
scl=1;
Data<<=1;
Data=Data|sda;
scl=0;
}
sda=1; //
scl=1; //master nhan/gui bit du lieu(sda) khi scl o muc cao
_nop_();
scl=0;
_nop_();//du lieu(sda) thay doi khi scl muc thap/
return Data;//tra gia tri cho ham
}
char recv_data(bit_8 x)
{ unsigned char Data;
start_rtc();
send_adr(0xd0);//
send_adr(x); //bat dau doc du lieu tu thanh ghi co dia chi 0x00
start_rtc();
send_adr(0xd1); //0xd0 + 0xd1 la dia chi cua ds1307 va che do doc du lieu
Data=recv_rtc();//con tro dang tro toi dia chi 0x0 chua du lieu second
stop_rtc();//Stop I2C
return Data;}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** khoi tao time cho RTC ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void RTC_INI(void)
{
unsigned char t;
for(t=0;t<9;t++)
{
start_rtc(); //DK start RTC
send_adr(0xd0); // gui dia chi ghi
send_adr(t); //gui dia chi thanh ghi can khoi tao
send_adr(rtc_ini_val[t]);//send data to write cho rtc
stop_rtc(); //dk stop
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Hien thi du lieu cua RTC len LCD ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void disp_rtc(void)
{
wrt_cmd(0xca); // ep con tro den vi tri thu 11 dong thu 2
disp_data_rtc(recv_data(0)); //hien thi giay , du lieu doc ra la ma bcd nhung ham hienthi_dulieu_rtc da chuyen sang dec roi
wrt_cmd(0xc7); // ep con tro den vi tri thu 8 dong thu 2
disp_data_rtc(recv_data(1)); // hien thi phut
wrt_byte(':');
wrt_cmd(0xc4); // ep con tro den vi tri thu 5 dong thu 2
disp_data_rtc(recv_data(2)); //hien thi gio
wrt_byte(':');
wrt_cmd(0xcd);
wrt_cmd(0x80); //ep con tro den dau dong thu 1
wrt_data(day[recv_data(3)-1]);//hien thi thu
wrt_cmd(0x88); //ep con tro den vi tri thu 8 dong thu 1
disp_data_rtc(recv_data(4)); //hien thi ngay
wrt_byte('/');
disp_data_rtc(recv_data(5)); //hien thi thang
wrt_byte('/');
disp_data_rtc(recv_data(6)); //nam
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
****cài dat time cho RTC ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void rtc_set()
{
bit_8 mins,hours,days,date,month,year;
mins = hex_dec(recv_data(1));
hours = hex_dec(recv_data(2));
days = hex_dec(recv_data(3));
date = hex_dec(recv_data(4));
month = hex_dec(recv_data(5));
year = hex_dec(recv_data(6));
wrt_cmd(1);
wrt_data("Chinh");
wrt_cmd(0x8C);
wrt_data("Gio");
wrt_cmd(0x0e);
wrt_cmd(0xc4);
data_in(hours);
wrt_byte(':');
data_in(mins);
wrt_cmd(0xC8);
while(TIME_KEY==0);
up: while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0); //neu co tac dong den phim bam thji kiem tra
if(INC_KEY==0) //neu INC_KEY dc nhan
{
mins++; //tang phut
if(mins==60) //neu phut=60
mins=0; //thi phut ve gtri 0
wrt_cmd(0xC7); //ghi gia tri phut tai vi tri dong 1 cot 7
data_in(mins); //hien thi phut
wrt_cmd(0x10); //dich tro sang trai
delay();
goto up; //tre
}
if(DEC_KEY==0)
{
mins--;
if(mins==0xff)
mins=59;
wrt_cmd(0xC7);
data_in(mins);
wrt_cmd(0x10);
delay();
goto up;
}
while(TIME_KEY==0);//ko lam gi ca
wrt_cmd(0xC5);//tro o vi tri 1,5
up1:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
hours++;
if(hours==24)
hours=0;
wrt_cmd(0xC4);
data_in(hours);
wrt_cmd(0xC5);
delay();
goto up1;
}
if(DEC_KEY==0)
{
hours--;
if(hours==0)
{
hours=23;
}
wrt_cmd(0xC4);
data_in(hours);
wrt_cmd(0xC5);
delay();
goto up1;
}
while(TIME_KEY==0);
wrt_cmd(1);
wrt_cmd(0x80);
wrt_data("Chinh");
wrt_cmd(0x8c);
wrt_data("Ngay");
wrt_cmd(0xc4);
data_in(date);
wrt_byte('/');
data_in(month);
wrt_byte('/');
data_in(year);
wrt_cmd(0xc5);
up2:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
date++;
if(date==32)
date=1;
wrt_cmd(0xC4);
data_in(date);
wrt_cmd(0x10);
delay();
goto up2;
}
if(DEC_KEY==0)
{
date--;
if(date==0)
date=31;
wrt_cmd(0xC4);
data_in(date);
wrt_cmd(0x10);
delay();
goto up2;
}
while(TIME_KEY==0);
wrt_cmd(0xC8);
up3:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
month++;
if(month==13)
month=1;
wrt_cmd(0xC7);
data_in(month);
wrt_cmd(0x10);
delay();
goto up3;
}
if(DEC_KEY==0)
{
month--;
if(month==0)
month=12;
wrt_cmd(0xC7);
data_in(month);
wrt_cmd(0x10);
delay();
goto up3;
}
while(TIME_KEY==0);
wrt_cmd(0xCB);
up4:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
year++;
if(year==100)
year=0;
wrt_cmd(0xCA);
data_in(year);
wrt_cmd(0x10);
delay();
goto up4;
}
if(DEC_KEY==0)
{
year--;
if(year==0xff)
year=99;
wrt_cmd(0xCA);
data_in(year);
wrt_cmd(0x10);
delay();
goto up4;
}
while(TIME_KEY==0);
wrt_cmd(1);
wrt_cmd(0x80);
wrt_data("Chinh");
wrt_cmd(0x8c);
wrt_data("Thu");
wrt_cmd(0xc4);
wrt_data(day[days-1]);
up6:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
days++;
if(days==8)
days=1;
wrt_cmd(0xC4);
wrt_data(day[days-1]);
delay();
goto up6;
}
if(DEC_KEY==0)
{
days--;
if(days==0)
days=7;
wrt_cmd(0xC4);
wrt_data(day[days-1]);
delay();
goto up6;
}
while(TIME_KEY==0);
wrt_cmd(1);
wrt_cmd(0xC);
rtc_ini_val[0] = 0x00;
rtc_ini_val[1] = dec_hex(mins);
rtc_ini_val[2] = dec_hex(hours);
rtc_ini_val[3] = dec_hex(days);
rtc_ini_val[4] = dec_hex(date);
rtc_ini_val[5] = dec_hex(month);
rtc_ini_val[6] = dec_hex(year);
rtc_ini_val[7] = 0x00;
rtc_ini_val[8] = '~';
RTC_INI();
wrt_cmd(1);
wrt_cmd(0x82);
wrt_data("DA CHINH");
wrt_cmd(0xC3);
wrt_data("XONG ROI");
delay();
delay();
delay();
delay();
delay();
wrt_cmd(1);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** kiem tra xem RTC có duoc cai dat chua ?
neu chua dung time thi no se khoi tao
nhu ben duoi ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void rtc_check(void)
{
bit_8 temp;
start_rtc();
send_adr(0xd0);
send_adr(0x08);//gui dia chi thanh ghi dieu khien 08H
start_rtc();
send_adr(0xd1); //dia chi doc RTC
temp=recv_rtc();// temp luu gia tri doc dc tu RTC tai dia chi thanh ghi dieu khien
stop_rtc();//dk dung RTC
if(temp!='~') //neu nó chua dc khoi tao tuc gia tri thanh ghi dk khac '~' thi thuc hien khoitao cho RTC
{
rtc_ini_val[0]=0x00;//secs=0
rtc_ini_val[1]=0x00;//mins=0
rtc_ini_val[2]=0x09;//khi tao 12h o che do 24h(xoa bit D7=0,D6=0)
rtc_ini_val[3]=0x01; //chu nhat
rtc_ini_val[4]=0x29;// ngay 16
rtc_ini_val[5]=0x05;// Thang 10
rtc_ini_val[6]=0x11;//nam 2010
rtc_ini_val[7]=0x0;//ko dung den nen gan cho no gtri 00
rtc_ini_val[8]='~';//dia chi
RTC_INI();
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Data Convert HEX-DEC and DEC-HEX ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
bit_8 hex_dec(bit_8 hex)
{
return((hex/0x10)*0xA+(hex%0x10));
}
/*====================================*/
bit_8 dec_hex(bit_8 dec)
{
return((dec/0xA)*0x10+(dec%0xA));
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** DELAY ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void delay(void)
{
bit_8 i,j;
TMOD=0x11;
for(i=0;i<2;i++)
{
TH1=0;
TH0=1;
TL1=0;
TL0=0;
TR1=1;
while(TF1!=1)
{
for(j=0;j<20;j++);
}
TF1=0;
TR0=1;
TR1=0;
while(TF0!=1)
{}
TF0=0;
TR0=0;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~
**** hien thi thang , neu <9 thi them 0 phia trc ***
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void data_in(bit_8 a)
{
bit_8 j;
j=a/10;
wrt_data(rtc[j]);
j=a%10;
wrt_data(rtc[j]);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~
****Chuong trình kiem tra hen gio bao chuong ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~*/
/*================================================= ==================*/
/*STT hour_ST min_ST hour_FN min_FN */
/*1 07------00------07------45 */
/*2 07------50------08------35 */
/*3 08------45------09------30 */
/*4 09------35------10------20 */
/*5 10------25------11------10 */
/*6 xx------xx------xx------xx */
/*7 xx------xx------xx------xx */
/*8 13------30------14------15 */
/*9 14------20------15------05 */
/*10 15------15------16------00 */
/*11 16------05------16------50 */
/*12 xx------xx------xx------xx */
/*================================================= ==================*/
void check_alarm()
{
bit_8 ah[]={7 ,9 ,10 ,14 ,16};
bit_8 am[]={45 ,30 ,20 ,15 ,0};
unsigned char i;//khai bao bien chay cho mang h hen
// kiem tra cac truong hop dac biet time khi bat dau va ket thuc
if(((hex_dec(recv_data(2))==7)&&((hex_dec(recv_dat a(1)))==0))||((hex_dec(recv_data(2))==8)&&((hex_de c(recv_data(1)))==35))||((hex_dec(recv_data(2))==8 )&&((hex_dec(recv_data(1)))==45))||((hex_dec(recv_ data(2))==11)&&((hex_dec(recv_data(1)))==10))||((h ex_dec(recv_data(2))==13)&&((hex_dec(recv_data(1)) ==30)))||((hex_dec(recv_data(2))==15)&&((hex_dec(r ecv_data(1)))==5))||((hex_dec(recv_data(2))==15)&& ((hex_dec(recv_data(1)))==15))||((hex_dec(recv_dat a(2))==16)&&((hex_dec(recv_data(1)))==50)))
{
if(hex_dec(recv_data(0))<10)
{
aoff=1;
aon =0;
}
}
else//ngoai ra neu ko phai cac gia tri tren thi kiem tra xem cso thoa man diu kien duoi day ko?
{
for (i=0;i<11;i++)
{
if((hex_dec(recv_data(2))==ah[i])&&(((hex_dec(recv_data(1)))==am[i])||((hex_dec(recv_data(1)))==am[i]+5)))
{
if(hex_dec(recv_data(0))<5)
{
aoff=1;
aon =0;
}
}
}
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** chuong trình chuông báo ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void ring_alarm()
{
alarm_port=~alarm_port;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
alarm_port=~alarm_port;
alarm_port=~alarm_port;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
alarm_port=~alarm_port;
DELAY ;
alarm_port=~alarm_port;
alarm_port=~alarm_port;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
alarm_port=~alarm_port;
alarm_port=0;
aoff=0;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** THE ++++END ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void docacdulieu(void)
{ int i;
for(i=0;i<=6;i++){recv_data(i);
}
}
void main()
{
alarm_port=0;
LCD_INI(); //khoi tao cho LCD
disp_intro();//hien len LCD
wrt_cmd(0x1);//xoa man hinh LCD
rtc_check();//kiêm tra RTC
ENABLE_INT//cho phep ngat
docacdulieu();
while(1)
{
docacdulieu();
disp_rtc();
if(_testbit_(flag)) //kiem tra co ngat
{
DISABLE_INT //cam ngat
rtc_set(); //goi chuong trinh set cho rtc
ENABLE_INT //cho phep ngat
flag=0; //xoa co ngat
}
aon=1;//dieu kien de luon so sanh time hen voi time hien tai
if(aon)
check_alarm(); // kiem tra
if(aoff) //bao chuong
ring_alarm();
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
****chuong trinh phuc vu ngat ngoai 0 ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void set_flag() interrupt 0 //chuong trinh ngat cho rtc_set
{
flag=1;
}
#include <ports.h>
#include <lcd.h>
#include <rtc.h>
extern bit aon,aoff;
unsigned char *rtc[]={"0","1","2","3","4","5","6","7","8","9"};
unsigned char *day[]={"C.Nhat: ","Thu 2: ","Thu 3: ","Thu 4: ","Thu 5: ","Thu 6: ","Thu 7: "};
unsigned char rtc_ini_val[9];
bit_8; code *intro[]={"MINH PHUNG - THI NHUNG"}
bit flag=0,aon=0,a0ff=0;
void busy()
{
D7=1;
rs=0;
rw=1;
while(D7!=0)
{
en=0;
en=1;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Ghi mot lenh cho LCD ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void wrt_cmd(bit_8 lcd)
{
busy();
rs=0; // chon thanh ghi lenh
rw=0; // ghi len lcd
lcd_port=lcd; // gia tri LCD
en=1; // cho phep muc cao
en=0; //xung cao xuong thap
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** hien thi 1 xau ki tu string ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void wrt_data(bit_8 *string)
{
bit_8 i;
for(i=0;string[i]!='\0';i++)
wrt_byte(string[i]);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** hien thi 1 byte du lieu len LCD ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void wrt_byte(bit_8 value)
{
busy();
rs=1;
rw=0;
lcd_port=value;
en=1;
en=0;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Khoi tao cho LCD****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void LCD_INI(void)
{
wrt_cmd(0X38); //khoi tao LCD o che do 2 dong &ma tran 5x7
wrt_cmd(0X0C); //bat hien thi tat con tro
wrt_cmd(0X01);//xoa man hinh hien thi
wrt_cmd(0X06);//dich contro sang phai
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** hien thi phan user mún gioi thieu len LCD **
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void disp_intro()
{
bit_8 i;
bit_16 j;
wrt_cmd(0x80);//dua con tro ve dau dong thu 2
wrt_data(intro[0]);
wrt_cmd(0xc0);
wrt_data(intro[1]);
for(i=0x5;i>0;i--)
for(j=0xffff;j>0;j--); //tre de nhin thay chuong trinh hien thi
}
void disp_data_rtc(unsigned char x)
{
unsigned char temp;
temp = x/0x10;
wrt_data(rtc[temp]);
temp = x%0x10;
wrt_data(rtc[temp]);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** RTC start condition ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void start_rtc(void) //dk start: 1 su cdoi tthai tu cao xuong thap tren duong sda trong khi
{ //duong scl dang o muc cao
scl=1;
sda=1;
_nop_();
_nop_();
sda=0;
scl=0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void stop_rtc(void) //dk stop: 1 su cdoi trang thai tu muc thap len cao tren duong sda trong khi duong
{ // slc dang o muc cao
sda=0;
scl=1;
_nop_();
_nop_();
sda=1;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** gui 1 dia chi co do dai 8 bit ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void send_adr(unsigned char x)
{
unsigned char i;
for(i=0;i<8;i++)
{
sda=(x&0x80)? 1:0; //dua bit du lieu ra chan SDA
scl=1;
_nop_();
_nop_();
scl=0;
x<<=1; //bit co trong so lon hon dc truyen truoc
}
scl=1; //nhan bit ACK tu SLAVER
_nop_();
_nop_();
scl=0;
}
unsigned char recv_rtc(void)
{
unsigned char Data,i;
for(i=0;i<8;i++) // nhan vao 8 bit
{
scl=1;
Data<<=1;
Data=Data|sda;
scl=0;
}
sda=1; //
scl=1; //master nhan/gui bit du lieu(sda) khi scl o muc cao
_nop_();
scl=0;
_nop_();//du lieu(sda) thay doi khi scl muc thap/
return Data;//tra gia tri cho ham
}
char recv_data(bit_8 x)
{ unsigned char Data;
start_rtc();
send_adr(0xd0);//
send_adr(x); //bat dau doc du lieu tu thanh ghi co dia chi 0x00
start_rtc();
send_adr(0xd1); //0xd0 + 0xd1 la dia chi cua ds1307 va che do doc du lieu
Data=recv_rtc();//con tro dang tro toi dia chi 0x0 chua du lieu second
stop_rtc();//Stop I2C
return Data;}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** khoi tao time cho RTC ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void RTC_INI(void)
{
unsigned char t;
for(t=0;t<9;t++)
{
start_rtc(); //DK start RTC
send_adr(0xd0); // gui dia chi ghi
send_adr(t); //gui dia chi thanh ghi can khoi tao
send_adr(rtc_ini_val[t]);//send data to write cho rtc
stop_rtc(); //dk stop
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Hien thi du lieu cua RTC len LCD ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void disp_rtc(void)
{
wrt_cmd(0xca); // ep con tro den vi tri thu 11 dong thu 2
disp_data_rtc(recv_data(0)); //hien thi giay , du lieu doc ra la ma bcd nhung ham hienthi_dulieu_rtc da chuyen sang dec roi
wrt_cmd(0xc7); // ep con tro den vi tri thu 8 dong thu 2
disp_data_rtc(recv_data(1)); // hien thi phut
wrt_byte(':');
wrt_cmd(0xc4); // ep con tro den vi tri thu 5 dong thu 2
disp_data_rtc(recv_data(2)); //hien thi gio
wrt_byte(':');
wrt_cmd(0xcd);
wrt_cmd(0x80); //ep con tro den dau dong thu 1
wrt_data(day[recv_data(3)-1]);//hien thi thu
wrt_cmd(0x88); //ep con tro den vi tri thu 8 dong thu 1
disp_data_rtc(recv_data(4)); //hien thi ngay
wrt_byte('/');
disp_data_rtc(recv_data(5)); //hien thi thang
wrt_byte('/');
disp_data_rtc(recv_data(6)); //nam
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
****cài dat time cho RTC ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void rtc_set()
{
bit_8 mins,hours,days,date,month,year;
mins = hex_dec(recv_data(1));
hours = hex_dec(recv_data(2));
days = hex_dec(recv_data(3));
date = hex_dec(recv_data(4));
month = hex_dec(recv_data(5));
year = hex_dec(recv_data(6));
wrt_cmd(1);
wrt_data("Chinh");
wrt_cmd(0x8C);
wrt_data("Gio");
wrt_cmd(0x0e);
wrt_cmd(0xc4);
data_in(hours);
wrt_byte(':');
data_in(mins);
wrt_cmd(0xC8);
while(TIME_KEY==0);
up: while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0); //neu co tac dong den phim bam thji kiem tra
if(INC_KEY==0) //neu INC_KEY dc nhan
{
mins++; //tang phut
if(mins==60) //neu phut=60
mins=0; //thi phut ve gtri 0
wrt_cmd(0xC7); //ghi gia tri phut tai vi tri dong 1 cot 7
data_in(mins); //hien thi phut
wrt_cmd(0x10); //dich tro sang trai
delay();
goto up; //tre
}
if(DEC_KEY==0)
{
mins--;
if(mins==0xff)
mins=59;
wrt_cmd(0xC7);
data_in(mins);
wrt_cmd(0x10);
delay();
goto up;
}
while(TIME_KEY==0);//ko lam gi ca
wrt_cmd(0xC5);//tro o vi tri 1,5
up1:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
hours++;
if(hours==24)
hours=0;
wrt_cmd(0xC4);
data_in(hours);
wrt_cmd(0xC5);
delay();
goto up1;
}
if(DEC_KEY==0)
{
hours--;
if(hours==0)
{
hours=23;
}
wrt_cmd(0xC4);
data_in(hours);
wrt_cmd(0xC5);
delay();
goto up1;
}
while(TIME_KEY==0);
wrt_cmd(1);
wrt_cmd(0x80);
wrt_data("Chinh");
wrt_cmd(0x8c);
wrt_data("Ngay");
wrt_cmd(0xc4);
data_in(date);
wrt_byte('/');
data_in(month);
wrt_byte('/');
data_in(year);
wrt_cmd(0xc5);
up2:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
date++;
if(date==32)
date=1;
wrt_cmd(0xC4);
data_in(date);
wrt_cmd(0x10);
delay();
goto up2;
}
if(DEC_KEY==0)
{
date--;
if(date==0)
date=31;
wrt_cmd(0xC4);
data_in(date);
wrt_cmd(0x10);
delay();
goto up2;
}
while(TIME_KEY==0);
wrt_cmd(0xC8);
up3:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
month++;
if(month==13)
month=1;
wrt_cmd(0xC7);
data_in(month);
wrt_cmd(0x10);
delay();
goto up3;
}
if(DEC_KEY==0)
{
month--;
if(month==0)
month=12;
wrt_cmd(0xC7);
data_in(month);
wrt_cmd(0x10);
delay();
goto up3;
}
while(TIME_KEY==0);
wrt_cmd(0xCB);
up4:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
year++;
if(year==100)
year=0;
wrt_cmd(0xCA);
data_in(year);
wrt_cmd(0x10);
delay();
goto up4;
}
if(DEC_KEY==0)
{
year--;
if(year==0xff)
year=99;
wrt_cmd(0xCA);
data_in(year);
wrt_cmd(0x10);
delay();
goto up4;
}
while(TIME_KEY==0);
wrt_cmd(1);
wrt_cmd(0x80);
wrt_data("Chinh");
wrt_cmd(0x8c);
wrt_data("Thu");
wrt_cmd(0xc4);
wrt_data(day[days-1]);
up6:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
days++;
if(days==8)
days=1;
wrt_cmd(0xC4);
wrt_data(day[days-1]);
delay();
goto up6;
}
if(DEC_KEY==0)
{
days--;
if(days==0)
days=7;
wrt_cmd(0xC4);
wrt_data(day[days-1]);
delay();
goto up6;
}
while(TIME_KEY==0);
wrt_cmd(1);
wrt_cmd(0xC);
rtc_ini_val[0] = 0x00;
rtc_ini_val[1] = dec_hex(mins);
rtc_ini_val[2] = dec_hex(hours);
rtc_ini_val[3] = dec_hex(days);
rtc_ini_val[4] = dec_hex(date);
rtc_ini_val[5] = dec_hex(month);
rtc_ini_val[6] = dec_hex(year);
rtc_ini_val[7] = 0x00;
rtc_ini_val[8] = '~';
RTC_INI();
wrt_cmd(1);
wrt_cmd(0x82);
wrt_data("DA CHINH");
wrt_cmd(0xC3);
wrt_data("XONG ROI");
delay();
delay();
delay();
delay();
delay();
wrt_cmd(1);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** kiem tra xem RTC có duoc cai dat chua ?
neu chua dung time thi no se khoi tao
nhu ben duoi ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void rtc_check(void)
{
bit_8 temp;
start_rtc();
send_adr(0xd0);
send_adr(0x08);//gui dia chi thanh ghi dieu khien 08H
start_rtc();
send_adr(0xd1); //dia chi doc RTC
temp=recv_rtc();// temp luu gia tri doc dc tu RTC tai dia chi thanh ghi dieu khien
stop_rtc();//dk dung RTC
if(temp!='~') //neu nó chua dc khoi tao tuc gia tri thanh ghi dk khac '~' thi thuc hien khoitao cho RTC
{
rtc_ini_val[0]=0x00;//secs=0
rtc_ini_val[1]=0x00;//mins=0
rtc_ini_val[2]=0x09;//khi tao 12h o che do 24h(xoa bit D7=0,D6=0)
rtc_ini_val[3]=0x01; //chu nhat
rtc_ini_val[4]=0x29;// ngay 16
rtc_ini_val[5]=0x05;// Thang 10
rtc_ini_val[6]=0x11;//nam 2010
rtc_ini_val[7]=0x0;//ko dung den nen gan cho no gtri 00
rtc_ini_val[8]='~';//dia chi
RTC_INI();
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Data Convert HEX-DEC and DEC-HEX ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
bit_8 hex_dec(bit_8 hex)
{
return((hex/0x10)*0xA+(hex%0x10));
}
/*====================================*/
bit_8 dec_hex(bit_8 dec)
{
return((dec/0xA)*0x10+(dec%0xA));
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** DELAY ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void delay(void)
{
bit_8 i,j;
TMOD=0x11;
for(i=0;i<2;i++)
{
TH1=0;
TH0=1;
TL1=0;
TL0=0;
TR1=1;
while(TF1!=1)
{
for(j=0;j<20;j++);
}
TF1=0;
TR0=1;
TR1=0;
while(TF0!=1)
{}
TF0=0;
TR0=0;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~
**** hien thi thang , neu <9 thi them 0 phia trc ***
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void data_in(bit_8 a)
{
bit_8 j;
j=a/10;
wrt_data(rtc[j]);
j=a%10;
wrt_data(rtc[j]);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~
****Chuong trình kiem tra hen gio bao chuong ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~*/
/*================================================= ==================*/
/*STT hour_ST min_ST hour_FN min_FN */
/*1 07------00------07------45 */
/*2 07------50------08------35 */
/*3 08------45------09------30 */
/*4 09------35------10------20 */
/*5 10------25------11------10 */
/*6 xx------xx------xx------xx */
/*7 xx------xx------xx------xx */
/*8 13------30------14------15 */
/*9 14------20------15------05 */
/*10 15------15------16------00 */
/*11 16------05------16------50 */
/*12 xx------xx------xx------xx */
/*================================================= ==================*/
void check_alarm()
{
bit_8 ah[]={7 ,9 ,10 ,14 ,16};
bit_8 am[]={45 ,30 ,20 ,15 ,0};
unsigned char i;//khai bao bien chay cho mang h hen
// kiem tra cac truong hop dac biet time khi bat dau va ket thuc
if(((hex_dec(recv_data(2))==7)&&((hex_dec(recv_dat a(1)))==0))||((hex_dec(recv_data(2))==8)&&((hex_de c(recv_data(1)))==35))||((hex_dec(recv_data(2))==8 )&&((hex_dec(recv_data(1)))==45))||((hex_dec(recv_ data(2))==11)&&((hex_dec(recv_data(1)))==10))||((h ex_dec(recv_data(2))==13)&&((hex_dec(recv_data(1)) ==30)))||((hex_dec(recv_data(2))==15)&&((hex_dec(r ecv_data(1)))==5))||((hex_dec(recv_data(2))==15)&& ((hex_dec(recv_data(1)))==15))||((hex_dec(recv_dat a(2))==16)&&((hex_dec(recv_data(1)))==50)))
{
if(hex_dec(recv_data(0))<10)
{
aoff=1;
aon =0;
}
}
else//ngoai ra neu ko phai cac gia tri tren thi kiem tra xem cso thoa man diu kien duoi day ko?
{
for (i=0;i<11;i++)
{
if((hex_dec(recv_data(2))==ah[i])&&(((hex_dec(recv_data(1)))==am[i])||((hex_dec(recv_data(1)))==am[i]+5)))
{
if(hex_dec(recv_data(0))<5)
{
aoff=1;
aon =0;
}
}
}
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** chuong trình chuông báo ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void ring_alarm()
{
alarm_port=~alarm_port;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
alarm_port=~alarm_port;
alarm_port=~alarm_port;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
alarm_port=~alarm_port;
DELAY ;
alarm_port=~alarm_port;
alarm_port=~alarm_port;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
alarm_port=~alarm_port;
alarm_port=0;
aoff=0;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** THE ++++END ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void disp_data_rtc(unsigned char x)
{
unsigned char temp;
temp = x/0x10;
wrt_data(rtc[temp]);
temp = x%0x10;
wrt_data(rtc[temp]);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** RTC start condition ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void start_rtc(void) //dk start: 1 su cdoi tthai tu cao xuong thap tren duong sda trong khi
{ //duong scl dang o muc cao
scl=1;
sda=1;
_nop_();
_nop_();
sda=0;
scl=0;
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~//
void stop_rtc(void) //dk stop: 1 su cdoi trang thai tu muc thap len cao tren duong sda trong khi duong
{ // slc dang o muc cao
sda=0;
scl=1;
_nop_();
_nop_();
sda=1;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** gui 1 dia chi co do dai 8 bit ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void send_adr(unsigned char x)
{
unsigned char i;
for(i=0;i<8;i++)
{
sda=(x&0x80)? 1:0; //dua bit du lieu ra chan SDA
scl=1;
_nop_();
_nop_();
scl=0;
x<<=1; //bit co trong so lon hon dc truyen truoc
}
scl=1; //nhan bit ACK tu SLAVER
_nop_();
_nop_();
scl=0;
}
unsigned char recv_rtc(void)
{
unsigned char Data,i;
for(i=0;i<8;i++) // nhan vao 8 bit
{
scl=1;
Data<<=1;
Data=Data|sda;
scl=0;
}
sda=1; //
scl=1; //master nhan/gui bit du lieu(sda) khi scl o muc cao
_nop_();
scl=0;
_nop_();//du lieu(sda) thay doi khi scl muc thap/
return Data;//tra gia tri cho ham
}
char recv_data(bit_8 x)
{ unsigned char Data;
start_rtc();
send_adr(0xd0);//
send_adr(x); //bat dau doc du lieu tu thanh ghi co dia chi 0x00
start_rtc();
send_adr(0xd1); //0xd0 + 0xd1 la dia chi cua ds1307 va che do doc du lieu
Data=recv_rtc();//con tro dang tro toi dia chi 0x0 chua du lieu second
stop_rtc();//Stop I2C
return Data;}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** khoi tao time cho RTC ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void RTC_INI(void)
{
unsigned char t;
for(t=0;t<9;t++)
{
start_rtc(); //DK start RTC
send_adr(0xd0); // gui dia chi ghi
send_adr(t); //gui dia chi thanh ghi can khoi tao
send_adr(rtc_ini_val[t]);//send data to write cho rtc
stop_rtc(); //dk stop
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Hien thi du lieu cua RTC len LCD ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void disp_rtc(void)
{
wrt_cmd(0xca); // ep con tro den vi tri thu 11 dong thu 2
disp_data_rtc(recv_data(0)); //hien thi giay , du lieu doc ra la ma bcd nhung ham hienthi_dulieu_rtc da chuyen sang dec roi
wrt_cmd(0xc7); // ep con tro den vi tri thu 8 dong thu 2
disp_data_rtc(recv_data(1)); // hien thi phut
wrt_byte(':');
wrt_cmd(0xc4); // ep con tro den vi tri thu 5 dong thu 2
disp_data_rtc(recv_data(2)); //hien thi gio
wrt_byte(':');
wrt_cmd(0xcd);
wrt_cmd(0x80); //ep con tro den dau dong thu 1
wrt_data(day[recv_data(3)-1]);//hien thi thu
wrt_cmd(0x88); //ep con tro den vi tri thu 8 dong thu 1
disp_data_rtc(recv_data(4)); //hien thi ngay
wrt_byte('/');
disp_data_rtc(recv_data(5)); //hien thi thang
wrt_byte('/');
disp_data_rtc(recv_data(6)); //nam
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
****cài dat time cho RTC ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void rtc_set()
{
bit_8 mins,hours,days,date,month,year;
mins = hex_dec(recv_data(1));
hours = hex_dec(recv_data(2));
days = hex_dec(recv_data(3));
date = hex_dec(recv_data(4));
month = hex_dec(recv_data(5));
year = hex_dec(recv_data(6));
wrt_cmd(1);
wrt_data("Chinh");
wrt_cmd(0x8C);
wrt_data("Gio");
wrt_cmd(0x0e);
wrt_cmd(0xc4);
data_in(hours);
wrt_byte(':');
data_in(mins);
wrt_cmd(0xC8);
while(TIME_KEY==0);
up: while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0); //neu co tac dong den phim bam thji kiem tra
if(INC_KEY==0) //neu INC_KEY dc nhan
{
mins++; //tang phut
if(mins==60) //neu phut=60
mins=0; //thi phut ve gtri 0
wrt_cmd(0xC7); //ghi gia tri phut tai vi tri dong 1 cot 7
data_in(mins); //hien thi phut
wrt_cmd(0x10); //dich tro sang trai
delay();
goto up; //tre
}
if(DEC_KEY==0)
{
mins--;
if(mins==0xff)
mins=59;
wrt_cmd(0xC7);
data_in(mins);
wrt_cmd(0x10);
delay();
goto up;
}
while(TIME_KEY==0);//ko lam gi ca
wrt_cmd(0xC5);//tro o vi tri 1,5
up1:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
hours++;
if(hours==24)
hours=0;
wrt_cmd(0xC4);
data_in(hours);
wrt_cmd(0xC5);
delay();
goto up1;
}
if(DEC_KEY==0)
{
hours--;
if(hours==0)
{
hours=23;
}
wrt_cmd(0xC4);
data_in(hours);
wrt_cmd(0xC5);
delay();
goto up1;
}
while(TIME_KEY==0);
wrt_cmd(1);
wrt_cmd(0x80);
wrt_data("Chinh");
wrt_cmd(0x8c);
wrt_data("Ngay");
wrt_cmd(0xc4);
data_in(date);
wrt_byte('/');
data_in(month);
wrt_byte('/');
data_in(year);
wrt_cmd(0xc5);
up2:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
date++;
if(date==32)
date=1;
wrt_cmd(0xC4);
data_in(date);
wrt_cmd(0x10);
delay();
goto up2;
}
if(DEC_KEY==0)
{
date--;
if(date==0)
date=31;
wrt_cmd(0xC4);
data_in(date);
wrt_cmd(0x10);
delay();
goto up2;
}
while(TIME_KEY==0);
wrt_cmd(0xC8);
up3:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
month++;
if(month==13)
month=1;
wrt_cmd(0xC7);
data_in(month);
wrt_cmd(0x10);
delay();
goto up3;
}
if(DEC_KEY==0)
{
month--;
if(month==0)
month=12;
wrt_cmd(0xC7);
data_in(month);
wrt_cmd(0x10);
delay();
goto up3;
}
while(TIME_KEY==0);
wrt_cmd(0xCB);
up4:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
year++;
if(year==100)
year=0;
wrt_cmd(0xCA);
data_in(year);
wrt_cmd(0x10);
delay();
goto up4;
}
if(DEC_KEY==0)
{
year--;
if(year==0xff)
year=99;
wrt_cmd(0xCA);
data_in(year);
wrt_cmd(0x10);
delay();
goto up4;
}
while(TIME_KEY==0);
wrt_cmd(1);
wrt_cmd(0x80);
wrt_data("Chinh");
wrt_cmd(0x8c);
wrt_data("Thu");
wrt_cmd(0xc4);
wrt_data(day[days-1]);
up6:while(INC_KEY!=0&&DEC_KEY!=0&&TIME_KEY!=0);
if(INC_KEY==0)
{
days++;
if(days==8)
days=1;
wrt_cmd(0xC4);
wrt_data(day[days-1]);
delay();
goto up6;
}
if(DEC_KEY==0)
{
days--;
if(days==0)
days=7;
wrt_cmd(0xC4);
wrt_data(day[days-1]);
delay();
goto up6;
}
while(TIME_KEY==0);
wrt_cmd(1);
wrt_cmd(0xC);
rtc_ini_val[0] = 0x00;
rtc_ini_val[1] = dec_hex(mins);
rtc_ini_val[2] = dec_hex(hours);
rtc_ini_val[3] = dec_hex(days);
rtc_ini_val[4] = dec_hex(date);
rtc_ini_val[5] = dec_hex(month);
rtc_ini_val[6] = dec_hex(year);
rtc_ini_val[7] = 0x00;
rtc_ini_val[8] = '~';
RTC_INI();
wrt_cmd(1);
wrt_cmd(0x82);
wrt_data("DA CHINH");
wrt_cmd(0xC3);
wrt_data("XONG ROI");
delay();
delay();
delay();
delay();
delay();
wrt_cmd(1);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** kiem tra xem RTC có duoc cai dat chua ?
neu chua dung time thi no se khoi tao
nhu ben duoi ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void rtc_check(void)
{
bit_8 temp;
start_rtc();
send_adr(0xd0);
send_adr(0x08);//gui dia chi thanh ghi dieu khien 08H
start_rtc();
send_adr(0xd1); //dia chi doc RTC
temp=recv_rtc();// temp luu gia tri doc dc tu RTC tai dia chi thanh ghi dieu khien
stop_rtc();//dk dung RTC
if(temp!='~') //neu nó chua dc khoi tao tuc gia tri thanh ghi dk khac '~' thi thuc hien khoitao cho RTC
{
rtc_ini_val[0]=0x00;//secs=0
rtc_ini_val[1]=0x00;//mins=0
rtc_ini_val[2]=0x09;//khi tao 12h o che do 24h(xoa bit D7=0,D6=0)
rtc_ini_val[3]=0x01; //chu nhat
rtc_ini_val[4]=0x29;// ngay 16
rtc_ini_val[5]=0x05;// Thang 10
rtc_ini_val[6]=0x11;//nam 2010
rtc_ini_val[7]=0x0;//ko dung den nen gan cho no gtri 00
rtc_ini_val[8]='~';//dia chi
RTC_INI();
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** Data Convert HEX-DEC and DEC-HEX ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
bit_8 hex_dec(bit_8 hex)
{
return((hex/0x10)*0xA+(hex%0x10));
}
/*====================================*/
bit_8 dec_hex(bit_8 dec)
{
return((dec/0xA)*0x10+(dec%0xA));
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** DELAY ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void delay(void)
{
bit_8 i,j;
TMOD=0x11;
for(i=0;i<2;i++)
{
TH1=0;
TH0=1;
TL1=0;
TL0=0;
TR1=1;
while(TF1!=1)
{
for(j=0;j<20;j++);
}
TF1=0;
TR0=1;
TR1=0;
while(TF0!=1)
{}
TF0=0;
TR0=0;
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~
**** hien thi thang , neu <9 thi them 0 phia trc ***
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
void data_in(bit_8 a)
{
bit_8 j;
j=a/10;
wrt_data(rtc[j]);
j=a%10;
wrt_data(rtc[j]);
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~
****Chuong trình kiem tra hen gio bao chuong ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~*/
/*================================================= ==================*/
/*STT hour_ST min_ST hour_FN min_FN */
/*1 07------00------07------45 */
/*2 07------50------08------35 */
/*3 08------45------09------30 */
/*4 09------35------10------20 */
/*5 10------25------11------10 */
/*6 xx------xx------xx------xx */
/*7 xx------xx------xx------xx */
/*8 13------30------14------15 */
/*9 14------20------15------05 */
/*10 15------15------16------00 */
/*11 16------05------16------50 */
/*12 xx------xx------xx------xx */
/*================================================= ==================*/
void check_alarm()
{
bit_8 ah[]={7 ,9 ,10 ,14 ,16};
bit_8 am[]={45 ,30 ,20 ,15 ,0};
unsigned char i;//khai bao bien chay cho mang h hen
// kiem tra cac truong hop dac biet time khi bat dau va ket thuc
if(((hex_dec(recv_data(2))==7)&&((hex_dec(recv_dat a(1)))==0))||((hex_dec(recv_data(2))==8)&&((hex_de c(recv_data(1)))==35))||((hex_dec(recv_data(2))==8 )&&((hex_dec(recv_data(1)))==45))||((hex_dec(recv_ data(2))==11)&&((hex_dec(recv_data(1)))==10))||((h ex_dec(recv_data(2))==13)&&((hex_dec(recv_data(1)) ==30)))||((hex_dec(recv_data(2))==15)&&((hex_dec(r ecv_data(1)))==5))||((hex_dec(recv_data(2))==15)&& ((hex_dec(recv_data(1)))==15))||((hex_dec(recv_dat a(2))==16)&&((hex_dec(recv_data(1)))==50)))
{
if(hex_dec(recv_data(0))<10)
{
aoff=1;
aon =0;
}
}
else//ngoai ra neu ko phai cac gia tri tren thi kiem tra xem cso thoa man diu kien duoi day ko?
{
for (i=0;i<11;i++)
{
if((hex_dec(recv_data(2))==ah[i])&&(((hex_dec(recv_data(1)))==am[i])||((hex_dec(recv_data(1)))==am[i]+5)))
{
if(hex_dec(recv_data(0))<5)
{
aoff=1;
aon =0;
}
}
}
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** chuong trình chuông báo ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void ring_alarm()
{
alarm_port=~alarm_port;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
alarm_port=~alarm_port;
alarm_port=~alarm_port;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
alarm_port=~alarm_port;
DELAY ;
alarm_port=~alarm_port;
alarm_port=~alarm_port;
DELAY ;
DELAY ;
DELAY ;
DELAY ;
alarm_port=~alarm_port;
alarm_port=0;
aoff=0;
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**** THE ++++END ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void docacdulieu(void)
{ int i;
for(i=0;i<=6;i++){recv_data(i);
}
}
void main()
{
alarm_port=0;
LCD_INI(); //khoi tao cho LCD
disp_intro();//hien len LCD
wrt_cmd(0x1);//xoa man hinh LCD
rtc_check();//kiêm tra RTC
ENABLE_INT//cho phep ngat
docacdulieu();
while(1)
{
docacdulieu();
disp_rtc();
if(_testbit_(flag)) //kiem tra co ngat
{
DISABLE_INT //cam ngat
rtc_set(); //goi chuong trinh set cho rtc
ENABLE_INT //cho phep ngat
flag=0; //xoa co ngat
}
aon=1;//dieu kien de luon so sanh time hen voi time hien tai
if(aon)
check_alarm(); // kiem tra
if(aoff) //bao chuong
ring_alarm();
}
}
/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
****chuong trinh phuc vu ngat ngoai 0 ****
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
void set_flag() interrupt 0 //chuong trinh ngat cho rtc_set
{
flag=1;
}
Comment