Somebody please help me with this code. Pressing set button will cycle through weekday, day, month, year, hour, minute, alarm day, alarm, month, alarm, year, alarm hour, alarm minute.
inc and dec buttons increment or decrements the values. Ok sets the time and runs the clock.
The problem is I don't know what format the values should be written to ds1307 using I2Cx_Wr() function. Should I use a Dec2Bcd conversion to convert my values and write it to ds1307.
The problem is shown in the attached image.
Code: Select all
#ifndef DS1307
#define DS1307 0xD0
#endif
#define SET RA0_bit
#define INC RA1_bit
#define DEC RA2_bit
#define OK RA3_bit
// LCD module connections
sbit LCD_RS at RB2_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB4_bit;
sbit LCD_D5 at RB5_bit;
sbit LCD_D6 at RB6_bit;
sbit LCD_D7 at RB7_bit;
sbit LCD_RS_Direction at TRISB2_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB4_bit;
sbit LCD_D5_Direction at TRISB5_bit;
sbit LCD_D6_Direction at TRISB6_bit;
sbit LCD_D7_Direction at TRISB7_bit;
// End LCD module connections
unsigned char num, flag, set_time_flag;
char b, x, i, sec, min1, hr, week_day, day, mn, year;
char *txt, tnum[4], time_format[3], sihr[17];
char colon[] = ":";
int cnt, ihr, error, am_pm = 0;
bit set_flag, inc_flag, dec_flag, ok_flag, do_once_hr, do_once_min, do_once_sec, do_once_day, do_once_mn, do_once_year;
bit dec_do_once_hr, dec_do_once_min, dec_do_once_sec, dec_do_once_day, dec_do_once_mn, dec_do_once_year;
bit inc_do_once_hr, inc_do_once_min, inc_do_once_sec, inc_do_once_day, inc_do_once_mn, inc_do_once_year;
bit alarm_flag, alarm_set_flag;
unsigned char set_cnt, inc_cnt, dec_cnt = 0;
unsigned char ssec, smin, shr, sweek_day, sday, smn, syear;
unsigned char asec, amin, ahr, aweek_day, aday, amn, ayear;
void Zero_Fill(char *value) {
if (value[1] == 0) {
value[1] = value[0];
value[0] = 48;
value[2] = 0;
}
}
void Write_Time() {
I2C1_Start(); // issue start signal
I2C1_Wr(DS1307); // address DS1307
I2C1_Wr(0); // start from word at address (REG0)
I2C1_Wr(0x80); // write $80 to REG0. (pause counter + 0 sec)
I2C1_Wr(smin); // write 11 to minutes word to (REG1)
I2C1_Wr(shr); // write 17 to hours word (24-hours mode)(REG2)
I2C1_Wr(sweek_day); // write 6 - Friday (REG3)
I2C1_Wr(sday); // write 23 to date word (REG4)
I2C1_Wr(smn); // write 11 (Nov) to month word (REG5)
I2C1_Wr(syear); // write 12 to year word (REG6)
I2C1_Stop(); // issue stop signal
I2C1_Start(); // issue start signal
I2C1_Wr(DS1307); // address DS1307
I2C1_Wr(0); // start from word at address 0
I2C1_Wr(0); // write 0 to REG0 (enable counting + 0 sec)
I2C1_Stop(); // issue stop signal
}
void Read_Time(char *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
I2C1_Start();
I2C1_Wr(DS1307);
I2C1_Wr(0);
I2C1_Repeated_Start();
I2C1_Wr(0xD1);
*sec = I2C1_Rd(1);
*min = I2C1_Rd(1);
*hr = I2C1_Rd(1);
*week_day = I2C1_Rd(1);
*day = I2C1_Rd(1);
*mn = I2C1_Rd(1);
*year = I2C1_Rd(0);
I2C1_Stop();
I2C1_Start();
I2C1_Wr(DS1307);
I2C1_Wr(0);
I2C1_Repeated_Start();
I2C1_Wr(0xD1);
ssec =I2C1_Rd(1);
smin =I2C1_Rd(1);
shr =I2C1_Rd(1);
sweek_day =I2C1_Rd(1);
sday =I2C1_Rd(1);
smn =I2C1_Rd(1);
syear =I2C1_Rd(0);
I2C1_Stop();
}
void Transform_Time(char *sec, char *min, char *hr, char *week_day, char *day, char *mn, char *year) {
*sec = ((*sec & 0x70) >> 4)*10 + (*sec & 0x0F);
*min = ((*min & 0xF0) >> 4)*10 + (*min & 0x0F);
*hr = ((*hr & 0x30) >> 4)*10 + (*hr & 0x0F);
*week_day =(*week_day & 0x07);
*day = ((*day & 0xF0) >> 4)*10 + (*day & 0x0F);
*mn = ((*mn & 0x10) >> 4)*10 + (*mn & 0x0F);
*year = ((*year & 0xF0)>>4)*10+(*year & 0x0F);
}
void Display_Time(char sec, char min, char hr, char week_day, char day, char mn, char year) {
if(alarm_flag == 0) {
switch(week_day){
case 1: txt="Sun"; break;
case 2: txt="Mon"; break;
case 3: txt="Tue"; break;
case 4: txt="Wed"; break;
case 5: txt="Thu"; break;
case 6: txt="Fri"; break;
case 7: txt="Sat"; break;
}
Lcd_Out(1,1,txt);
Lcd_Chr(1,5,(day / 10) + 48); // Print tens digit of day variable
Lcd_Chr(1,6, (day % 10) + 48); // Print oness digit of day variable
Lcd_Chr(1,7,'/');
Lcd_Chr(1,8,(mn / 10) + 48);
Lcd_Chr(1,9,(mn % 10) + 48);
Lcd_Chr(1,10,'/');
Lcd_Out(1,11,"2");
Lcd_Out(1,12,"0");
Lcd_Chr(1,13, (year / 10) + 48); // Print year vaiable + 8 (start from year 2008)
Lcd_Chr(1,14, (year % 10) + 48);
/*
if(hr >= 12) {
Lcd_Out(2,2,"PM");
am_pm = 1;
}
else if(hr < 12) {
Lcd_Out(2,2,"AM");
am_pm = 0;
}
*/
Lcd_Chr(2,5,(hr / 10) + 48);
Lcd_Chr(2,6,(hr % 10) + 48);
Lcd_Out(2,7,":");
Lcd_Chr(2,8,(min / 10) + 48);
Lcd_Chr(2,9,(min % 10) + 48);
Lcd_Out(2,10,":");
Lcd_Chr(2,11,(sec / 10) + 48);
Lcd_Chr(2,12,(sec % 10) + 48);
}
}
void Display_Alarm_Time(char asec, char amin, char ahr, char aweek_day, char aday, char amn, char ayear) {
if(alarm_flag == 1) {
Lcd_Out(1,1,"ALR");
Lcd_Chr(1,5,(aday / 10) + 48); // Print tens digit of day variable
Lcd_Chr(1,6, (aday % 10) + 48); // Print oness digit of day variable
Lcd_Chr(1,7,'/');
Lcd_Chr(1,8,(amn / 10) + 48);
Lcd_Chr(1,9,(amn % 10) + 48);
Lcd_Chr(1,10,'/');
Lcd_Out(1,11,"2");
Lcd_Out(1,12,"0");
Lcd_Chr(1,13, (ayear / 10) + 48); // Print year vaiable + 8 (start from year 2008)
Lcd_Chr(1,14, (ayear % 10) + 48);
Lcd_Chr(2,5,(ahr / 10) + 48);
Lcd_Chr(2,6,(ahr % 10) + 48);
Lcd_Out(2,7,":");
Lcd_Chr(2,8,(amin / 10) + 48);
Lcd_Chr(2,9,(amin % 10) + 48);
Lcd_Out(2,10,":");
Lcd_Chr(2,11,(asec / 10) + 48);
Lcd_Chr(2,12,(asec % 10) + 48);
}
}
void main() {
TRISA = 0b00001111;
PORTA = 0b00000000;
TRISB = 0b00000000;
PORTB = 0b00000000;
ADCON0 = 0b00000000;
ADCON1 = 0b10000111;
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_Out(1,4,"RTC DS1307");
Delay_ms(3000);
I2C1_Init(100000);
Lcd_Cmd(_LCD_CLEAR);
set_time_flag = 0;
ok_flag = 1;
alarm_flag = 0;
alarm_set_flag = 0;
ssec = 0x00;
smin = 0x00;
shr = 0x00;
sweek_day = 0x01;
sday = 0x00;
smn = 0x00;
syear = 0x00;
asec = 0x00;
amin = 0x00;
ahr = 0x00;
aday = 0x00;
amn = 0x00;
ayear = 0x00;
Uart1_Init(9600);
while(1) {
if(set_time_flag == 1) {
Write_Time();
ok_flag = 0;
Read_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);
}
if((SET == 1) && (INC == 0) && (DEC == 0) &&(OK == 0)) {
Delay_ms(100);
if((SET == 1) && (INC == 0) && (DEC == 0) && (OK == 0)) {
set_flag = 1;
set_time_flag = 1;
set_cnt++;
if(set_cnt > 11) {
set_cnt = 1;
alarm_flag = 0;
}
else if(set_cnt == 7) alarm_flag = 1;
}
}
else if((INC == 1) && (DEC == 0) && (SET == 0) && (OK == 0) && (set_flag == 1)) {
Delay_ms(100);
if((INC == 1) && (DEC == 0) && (SET == 0) && (OK == 0) && (set_flag == 1)) {
inc_flag = 1;
if(alarm_flag == 0) {
switch(set_cnt) {
case 0:
break;
case 1:
sweek_day++;
if(sweek_day > 7) sweek_day = 1;
break;
case 2:
sday++;
if((sday == 16) || (sday == 32)) {
sday = sday + 6;
}
else if(sday > 43) {
sday = 1;
}
break;
case 3:
smn++;
if(smn > 12) smn = 1;
break;
case 4:
syear++;
if((syear == 16) || (syear == 32) || (syear == 48) || (syear == 64) || (syear == 80) || (syear == 96)
|| (syear == 112) || (syear == 128) || (syear == 144)) {
syear = syear + 6;
}
if(syear > 153) {
syear = 0;
}
break;
case 5:
shr++;
if(shr == 16) {
shr = shr + 6;
}
if(shr > 29) {
shr = 0;
}
break;
case 6:
smin++;
if((smin == 16) || (smin == 32) || (smin == 48) || (smin == 64) || (smin == 80)) {
smin = smin + 6;
}
if(smin > 89) {
smin = 0;
}
break;
default:
break;
};
}
else if(alarm_flag == 1) {
switch(set_cnt) {
case 7:
aday++;
if(aday > 31) aday = 1;
break;;
case 8:
amn++;
if(amn > 12) amn = 1;
break;
case 9:
ayear++;
if(ayear > 99) ayear = 0;
break;
case 10:
ahr++;
if(ahr > 23) ahr = 0;
break;
case 11:
amin++;
if(amin > 59) amin = 0;
break;
default:
break;
};
}
}
}
else if((DEC == 1) && (SET == 0) && (INC == 0) && (OK == 0) && (set_flag == 1)) {
Delay_ms(100);
if((DEC == 1) && (SET == 0) && (INC == 0) && (OK == 0) && (set_flag == 1)) {
dec_flag = 1;
if(alarm_flag == 0) {
switch(set_cnt) {
case 0:
break;
case 1:
sweek_day--;
if(sweek_day < 1) sweek_day = 7;
break;
case 2:
sday--;
if(sday > 43) sday = 43;
if((sday == 31) || (sday == 15)) {
sday = sday - 6;
}
break;
case 3:
smn--;
if(smn > 12) smn = 12;
if(smn < 1) smn = 12;
break;
case 4:
syear--;
if(syear > 153) {
syear = 153;
}
if((syear == 143) || (syear == 127) || (syear == 111) || (syear == 95) || (syear == 79) || (syear == 63)
|| (syear == 47) || (syear == 47) || (syear == 31) || (syear == 15)) {
syear = syear - 6;
}
break;
case 5:
shr--;
if(shr > 29) {
shr = 29;
}
if(shr == 15) {
shr = shr - 6;
}
break;
case 6:
smin--;
if(smin > 89) {
smin = 89;
}
if((smin == 79) && (smin == 63) && (smin == 47) || (smin == 31) || (smin == 15)) {
smin = smin - 6;
}
break;
default:
break;
};
}
else if(alarm_flag == 1) {
switch(set_cnt) {
case 7:
aday--;
if(aday > 31) aday = 31;
if(aday < 1) aday = 31;
break;
case 8:
amn--;
if(amn > 12) amn = 12;
if(amn < 1) amn = 12;
break;
case 9:
ayear--;
if(ayear > 99) ayear = 99;
if(ayear < 0) ayear = 99;
break;
case 10:
ahr--;
if(ahr > 23) ahr = 23;
if(ahr < 0) ahr = 23;
break;
case 11:
amin--;
if(amin > 59) amin = 59;
if(amin < 0) amin = 59;
break;
default:
break;
};
}
}
}
else if((OK == 1) && (SET == 0) && (INC == 0) && (DEC == 0) && (set_flag == 1)) {
Delay_ms(100);
if((OK == 1) && (SET == 0) && (INC == 0) && (DEC == 0) && (set_flag == 1)) {
set_flag = 0;
set_time_flag = 0;
ok_flag = 1;
alarm_flag = 0;
alarm_set_flag = 1;
set_cnt = 0;
}
}
if(ok_flag == 1) {
Read_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);
}
if(alarm_flag == 0) {
Transform_Time(&sec,&min1,&hr,&week_day,&day,&mn,&year);
Display_Time(sec, min1, hr, week_day, day, mn, year);
if(alarm_set_flag == 1) {
if((day == aday) && (mn == amn) && (year == ayear) && (hr == ahr) && (min1 == amin)) {
PORTB.F0 = 1;
}
}
}
if(alarm_flag == 1) {
Display_Alarm_Time(asec, amin, ahr, aweek_day, aday, amn, ayear);
}
}
}