Hi to all, I am into a project of "programmable timer" using real time clock with ds1307, for that I am working with Pic16f1847 and using Mikroc pro compiler for programming. I am using 16Mhz internal oscillator for clocking the device. I am using PICKIT3 programmer for building the code. My code is working fine with PIC18f4520 as per my application . When I build the code into Pic16f1847 I am able to set the clock timing but when I am setting the time to switch on the relay, its not switching. Some unexpected problems I came across are as follows:- (i) Whenever I put any if condition of the code in beginning of the infinite loop I am not getting the display on Lcd. (ii) Whenever I add any extra text to display on the Lcd I am not getting anything on the Lcd, (iii) I was getting Rom memory full errors that's why I have written the routines for Lcd messages and delays and now my Rom is 50% free with 42% free Ram space. My clock is working fine and I am able to set the clock and calendar . And this full code works fine in 18f4520 with change in register configuration as per 18f4520. I am posting my code. Help me to find any solution of it.
Code:
// Lcd module connections
sbit LCD_RS at RB0_bit;
sbit LCD_EN at RB3_bit;
sbit LCD_D4 at RB5_bit;
sbit LCD_D5 at RB6_bit;
sbit LCD_D6 at RB7_bit;
sbit LCD_D7 at RB2_bit;
sbit LCD_RS_Direction at TRISB0_bit;
sbit LCD_EN_Direction at TRISB3_bit;
sbit LCD_D4_Direction at TRISB5_bit;
sbit LCD_D5_Direction at TRISB6_bit;
sbit LCD_D6_Direction at TRISB7_bit;
sbit LCD_D7_Direction at TRISB2_bit;
//End LCD connection
sbit set at RA4_bit;
sbit upcount at RA3_bit; // switch to increment the counter
sbit downcount at RA2_bit; // switch to decrement the counter
sbit set_clock at RA1_bit; // switch for setting menu
sbit Relay1 at RA7_bit; // Relay connection
unsigned char BCD2LowerCh(unsigned char bcd); // Binary to Decimal conversion for RTC
unsigned char BCD2UpperCh(unsigned char bcd); // Binary to Decimal conversion for RTC
unsigned short read_ds1307(unsigned short address ); // Function for RTC read
void write_ds1307(unsigned short address,unsigned short w_data); // Function for RTC write
void switching();
bit switch_flag;
char ampm,switch_count_on,switch_count_off;
unsigned char countr, second,days,hours,minutes,years,dates,months,date, month, hour, minute,sec,day,year,count7,count8,count9,count10,minute2,
dy, hrs2, dat2,day2,sec1, mon2, yer2,mint3,hrs3,dat3,mon3,yer3,rr,hrs2pm,hour11,count11,count1,count2,count3,count4,count5,count6,
day11,day12, day13, day14, day15, day16,day17,dt,mt,yr,mint,hrs, minute1,hour1,day1,date1,month1,year1,minute3,hour3, minute4, hour4; // Variables declaration for clock and date
char minuteclk(unsigned char mint2); //Function for minutes
char hoursclk(unsigned char hrs2pm); //Function for hours
char dayclk(unsigned char day2); //Function for day
char dateclk(unsigned char dar2); //Function for date
char monthclk(unsigned char mon2); //Function for month
char yearclk(unsigned char yr2); //Function for year
char days1[] = "SUN";
char days2[] = "MON";
char days3[] = "TUE";
char days4[] = "WED";
char days5[] = "THU";
char days6[] = "FRI";
char days7[] = "SAT";
char clock[9];
char calender[9];
char *text ="0";
char *text0 ="00";
char *text1 ="00";
char *text2 ="00";
char *text3 ="00";
char *text4 ="00";
char *text5 ="00";
void Delay2ms(void);
void Delay200ms(void);
void Delay500ms(void);
void Delay1s(void);
void Delay4s(void);
void lcd_clr(void);
void msg_welcome(void);
void msg_setmenu(void);
void msg_s_option(void);
void msg_setclock(void);
void msg_clock(void);
void msg_calendar(void);
void msg_clock_notify(void);
void msg_switch_min_hr(void);
void msg_switch_on_notify(void);
void msg_switch_off_notify(void);
void msg_on_time(void);
void msg_off_time(void);
void main()
{
PORTA = 0b00000000;
LATA = 0;
ANSELA = 0;
TRISA = 0b01011111;
PORTB = 0;
LATB = 0;
ANSELB = 0b00000000; // PORTB pins are all digital
OSCCON = 0b11110010; // 16MHZ INTOSC
OSCTUNE = 0b00011111;
ADRESH = 0;
ADRESL = 0;
ADCON0 = 0;
ADCON1 = 0b00001111;
C1ON_bit = 0;
TRISA.F4= 1; /// FOR Button
TRISA.F3= 1;
TRISA.F2= 1;
TRISA.F1= 1;
TRISA.F7= 0; // RELAY1
switch_flag = 0;
switch_count_on = 0;
switch_count_off = 0;
I2C1_Init(100000);
Lcd_Init();
lcd_clr();
msg_welcome();
Delay1s();
lcd_clr();
do
{
begin:
second = read_ds1307(0X00); // read second
minute = read_ds1307(0X01); // read minute
hour = read_ds1307(0X02); // read hour
if (hour<0x12)
{
if (hour==0)
{
hour = 0x12;
ampm = 'A';
}
else
ampm = 'A';
}
else if (hour == 0x12){
ampm = 'P';
}
else if (hour>0x12 && hour<0x20)
{
hour = hour-0x12;
ampm= 'P';
}
else if (hour==0x20){
hour = 0x08;
ampm = 'P';
}
else if (hour==0x21){
hour = 0x09;
ampm = 'P';
}
else if (hour==0x22){
ampm = 'P';
hour = 0x10;
}
else if (hour==0x23){
ampm = 'P';
hour = 0x11;
}
day=read_ds1307(0X03); // read day
date=read_ds1307(0X04); // read date
month=read_ds1307(0X05); // read month
year=read_ds1307(0X06); // read year
write_ds1307(0x19,second); // write second
write_ds1307(0x1A,minute); // write minute
write_ds1307(0x1B,hour); // write hour
write_ds1307(0x1C,day); // write day
write_ds1307(0x1D,date); // write date
write_ds1307(0x1E,month); // write month
write_ds1307(0x1F,year); // write year
clock[0] = BCD2UpperCh(hour);
clock[1] = BCD2LowerCh(hour);
clock[2] = ':';
clock[3] = BCD2UpperCh(minute);
clock[4] = BCD2LowerCh(minute);
clock[5] =' ';
clock[6] =ampm;
clock[7] ='M';
clock[8] ='\0';
Lcd_Out(2,1,calender);
Lcd_Out(1,1,clock);
calender[0] = BCD2UpperCh(date);
calender[1] = BCD2LowerCh(date);
calender[2] ='/';
calender[3] = BCD2UpperCh(month);
calender[4] = BCD2LowerCh(month);
calender[5] ='/';
calender[6] = BCD2UpperCh(year);
calender[7] = BCD2LowerCh(year);
calender[8] = '\0';
if(day ==1)
{
Delay2ms();
Lcd_Out(2,10,days1);
}
if(day ==2)
{
Delay2ms();
Lcd_Out(2,10,days2);
}
if(day ==3)
{
Delay2ms();
Lcd_Out(2,10,days3);
}
if(day ==4)
{
Delay2ms();
Lcd_Out(2,10,days4);
}
if(day ==5)
{
Delay2ms();
Lcd_Out(2,10,days5);
}
if(day ==6)
{
Delay2ms();
Lcd_Out(2,10,days6);
}
if(day ==7)
{
Delay2ms();
Lcd_Out(2,10,days7);
}
if(set == 0) // Set switch must be pressed one time
{
start:
Delay200ms();
lcd_clr();
msg_setmenu();
Delay1s();
lcd_clr();
msg_s_option();
Delay500ms();
for(count1=0; count1<4;count1)
{
Delay500ms();
if(upcount == 0 ) // Press upcount switch to select desired option
{
count1+=1;
}
if(downcount == 0 ) // For decrement
{
count1-=1;
}
if(count1 == 4)
{
count1 = 0;
}
text[0] = count1 % 10 +48 ;
Lcd_out(1, 15, text);
if(count1==1 && set == 0)
{
lcd_clr();
msg_setclock();
Delay1s();
goto Clock_setting ;
}
if( count1==2 && set == 0)
{
lcd_clr();
msg_on_time();
Delay1s();
goto On_Status;
}
if( count1==3 && set == 0)
{
lcd_clr();
msg_off_time();
Delay1s();
goto Off_Status;
}
if(set_clock == 0)
{
Delay2ms();
lcd_clr();
goto begin;
}
}
Clock_setting :
TimeSet_clock:
lcd_clr();
msg_clock();
Delay1s();
lcd_clr();
msg_calendar();
for(count2 = 0; count2 <7; count2)
{
Delay500ms();
if(upcount == 0 )
{
count2+=1;
}
if(downcount == 0 )
{
count2-=1;
}
if(count2 == 7)
{
count2 = 0;
}
text[0] = count2 % 10 +48 ;
Lcd_out(2, 15, text);
if(count2==1 && set == 0)
{
minute2 = 1;
minute1=minuteclk(minute2) ;
write_ds1307(0x20,Dec2Bcd(minute1));
goto TimeSet_clock;
}
if( count2==2 && set == 0)
{
hrs2 = 1;
hour1 = hoursclk(hrs2pm);
write_ds1307(0x21,Dec2Bcd(hour1));
goto TimeSet_clock;
}
if( count2==3 && set ==0)
{
dat2 = 1;
date1=dateclk(dat2);
write_ds1307(0x22,Dec2Bcd(date1));
goto TimeSet_clock;
}
if( count2==4 && set == 0)
{
day2 =1;
day1= dayclk(day2);
write_ds1307(0x23,Dec2Bcd(day1));
goto TimeSet_clock;
}
if( count2==5 && set == 0)
{
mon2 = 1;
month1= monthclk(mon2);
write_ds1307(0x24,Dec2Bcd(month1));
goto TimeSet_clock;
}
if( count2==6 && set == 0)
{
yer2 = 1;
year1= yearclk(yer2);
write_ds1307(0x25,Dec2Bcd(year1));
goto TimeSet_clock;
}
if (count2== 0 && set==0)
{
if(set == 0)
{
sec1= 00;
mint=read_ds1307(0x20);
hrs=read_ds1307(0x21);
dt=read_ds1307(0x22);
dy=read_ds1307(0x23);
mt=read_ds1307(0x24);
yr=read_ds1307(0x25);
}
else
{
sec1= read_ds1307(0x19);
mint=read_ds1307(0x1A);
hrs=read_ds1307(0x1B);
dy=read_ds1307(0x1C);
dt=read_ds1307(0x1D);
mt=read_ds1307(0x1E);
yr=read_ds1307(0x1F);
}
write_ds1307(0X00,sec1);
write_ds1307(0X01,mint);
write_ds1307(0X02,hrs);
write_ds1307(0X03,dy);
write_ds1307(0X04,dt);
write_ds1307(0X05,mt);
write_ds1307(0X06,yr);
write_ds1307(0X07,0x10);
lcd_clr();
msg_clock_notify();
Delay1s();
goto TimeSet_clock;
}
if(set_clock ==0)
{
lcd_clr();
goto start;
}
}
///////////////-----------------/////////////////////////
On_Status:
for(count3 = 0; count3 <4; count3)
{
Delay500ms();
if(upcount == 0 )
{
count3+=1;
}
if(downcount == 0 )
{
count3-=1;
}
if(count3 == 4)
{
count3 = 0;
}
lcd_clr();
msg_s_option();
msg_switch_min_hr();
text[0] = count3 % 10 +48 ;
Lcd_out(1, 15, text);
if(count3==1 && set == 0)
{
minute2 = 1;
minute1=minuteclk(minute2) ;
write_ds1307(0x2D,Dec2Bcd(minute1));
goto On_Status;
}
if( count3==2 && set == 0)
{
hrs2 = 1;
hour1 = hoursclk(hrs2pm);
write_ds1307(0x2E,Dec2Bcd(hour1));
goto On_Status;
}
if(count3==3 && set == 0)
{
lcd_clr();
msg_switch_on_notify();
write_ds1307(0x2D,00);
write_ds1307(0x2E,00);
Delay1s();
goto On_Status;
}
if(set_clock == 0)
{
lcd_clr(); // Cursor off
goto start;
}
}
Off_Status:
for(count4 = 0; count4 <4; count4)
{
Delay500ms();
if(upcount == 0 )
{
count4+=1;
}
if(downcount == 0 )
{
count4-=1;
}
if(count4 == 4)
{
count4 = 0;
}
lcd_clr();
msg_s_option();
msg_switch_min_hr();
text[0] = count4 % 10 +48 ;
Lcd_out(1, 15, text);
if(count4==1 && set == 0)
{
minute2 = 1;
minute1=minuteclk(minute2) ;
write_ds1307(0x2F,Dec2Bcd(minute1));
goto Off_Status;
}
if( count4==2 && set == 0)
{
hrs2 = 1;
hour1 = hoursclk(hrs2);
write_ds1307(0x30,Dec2Bcd(hour1));
goto Off_Status;
}
if(count4== 3 && set == 0)
{
lcd_clr();
msg_switch_off_notify();
write_ds1307(0x2F,00);
write_ds1307(0x30,00);
Delay1s();
goto Off_Status;
}
if(set_clock == 0)
{
lcd_clr();
goto start;
}
}
minute3=read_ds1307(0x2D);
hour3=read_ds1307(0x2E);
minute4=read_ds1307(0x2F);
hour4=read_ds1307(0x30);
if((minute==0x25) && (hour==0x11))//||(minute==minute4 && hour==hour4))
{
Delay200ms();
lcd_clr();
Lcd_out(1, 1, "1st SWITCH ON");
Lcd_out(2, 1, " AT SET");
//switch_status1on = 1;
// switch_status1off = 0;
switching();
if(switch_count_on<=0)
{switch_flag= 1;
}
else {switch_flag = 0;
//Delay_ms(3000);
lcd_clr();
}
}else
{
switch_count_on = 0;
}
if((minute==minute4 && hour==hour4))
{
lcd_clr();
switching();
Lcd_out(1, 1, "1st SWITCH OFF");
Lcd_out(2, 1, " AT SET");
if(switch_count_off<=0)
{switch_flag= 1;
}
else {switch_flag = 0;
delay_ms(5000);
lcd_clr();
}
}
else {switch_count_off = 0;}
}
}while(1);
}
void switching()
{
if(switch_flag)
{
switch_count_on++;
switch_count_off++;
Delay200ms();
Relay1 = ~ Relay1;
eeprom_write(0x10,Relay1);
switch_flag = 0;
}
}
unsigned short read_ds1307(unsigned short address )
{
int dat;
I2C1_Start();
I2C1_Wr(0xd0);
I2C1_Wr(address);
I2C1_Start();
I2C1_Wr(0xd1);
dat=I2C1_Rd(0);
I2C1_Stop();
return(dat);
}
unsigned char BCD2UpperCh(unsigned char bcd)
{
return ((bcd >> 4) + '0');
}
unsigned char BCD2LowerCh(unsigned char bcd)
{
return ((bcd & 0x0F) + '0');
}
void write_ds1307(unsigned short address,unsigned short w_data)
{
I2C1_Start(); // issue I2C start signal
//address 0x68 followed by direction bit (0 for write, 1 for read) 0x68 followed by 0 --> 0xD0
I2C1_Wr(0xD0); // send byte via I2C (device address + W)
I2C1_Wr(address); // send byte (address of DS1307 location)
I2C1_Wr(w_data); // send data (data to be written)
I2C1_Stop(); // issue I2C stop signal
}
char minuteclk(unsigned char mint2)
{
Lcd_Cmd(_LCD_CLEAR); //Lcd clear
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_out(1,3, "Select Minute");
for(count5 = 0; count5 < 60; count5)
{
if(upcount == 0 )
{
count5+=1;
}
else if(downcount == 0 )
{
count5-=1;
}
text0[0] = count5/10 + 48;
text0[1] = count5 % 10 +48 ;
Lcd_out(2, 1,"Minute:");
Lcd_out(2, 8, text0);
Delay_ms(300);
if( set == 0)
{
goto return1;
}
}
return1:
return count5;
}
char hoursclk(unsigned char hrs2pm)
{
Lcd_Cmd(_LCD_CLEAR); //Lcd clear
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_out(1,3, "Select Hours");
for(count6 = 0; count6 < 24; count6)
{
if(upcount == 0 )
{
count6+=1;
}
if(downcount == 0 )
{
count6-=1;
}
text0[0] = count6/10 + 48;
text0[1] = count6 % 10 +48 ;
Lcd_out(2, 1,"Hour:");
Lcd_out(2, 6, text0);
Delay_ms(400);
if( set == 0)
{
goto return2;
}
}
return2:
return count6;
}
char dayclk(unsigned char day2)
{
Lcd_Cmd(_LCD_CLEAR); //Lcd clear
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_out(1,1, "Select Day:");
Lcd_out(2, 1, "1:Sun 2:Mon 3:");
Lcd_out(3, -3, "Tue 4:Wed 5:Thu");
Lcd_out(4, -3, "6:Fri 7:Sat ");
for(count7 = 0; count7 < 8; count7)
{
if(upcount == 0 )
{
count7+=1;
}
if(downcount == 0 )
{
count7-=1;
}
if(count7 ==1)
Lcd_Out(1,13,days1);
if(count7 ==2)
Lcd_Out(1,13,days2);
if(count7 ==3)
Lcd_Out(1,13,days3);
if(count7 ==4)
Lcd_Out(1,13,days4);
if(count7 ==5)
Lcd_Out(1,13,days5);
if(count7 ==6)
Lcd_Out(1,13,days6);
if(count7 ==7)
Lcd_Out(1,13,days7);
Delay_ms(500);
if( set == 0)
{
goto return2;
}
}
return2:
return count7;
}
char dateclk(unsigned char dar2)
{
Lcd_Cmd(_LCD_CLEAR); //Lcd clear
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_out(1,3, "Select Date");
for(count8 = 0; count8 <= 31; count8)
{
if(upcount == 0 )
{
count8+=1;
}
if(downcount == 0 )
{
count8-=1;
}
text0[0] = count8/10 + 48;
text0[1] = count8 % 10 +48 ;
Lcd_out(2, 1,"Date:");
Lcd_out(2, 6, text0);
Delay_ms(400);
if( set == 0)
{
goto return3;
}
}
return3:
return count8;
}
char monthclk(unsigned char mon2)
{
Lcd_Cmd(_LCD_CLEAR); //Lcd clear
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_out(1,3, "Select Month");
for(count9 = 0; count9 < 13; count9)
{
if(upcount == 0 )
{
count9+=1;
}
if(downcount == 0 )
{
count9-=1;
}
text0[0] = count9/10 + 48;
text0[1] = count9 % 10 +48 ;
Lcd_out(2, 1,"Month:");
Lcd_out(2, 7, text0);
Delay_ms(500);
if( set == 0)
{
goto return4;
}
}
return4:
return count9;
}
char yearclk(unsigned char yr2)
{
Lcd_Cmd(_LCD_CLEAR); //Lcd clear
Lcd_Cmd(_LCD_CURSOR_OFF);
Lcd_out(1,3, "Select Year");
for(count10 = 0; count10 <= 99; count10)
{
if(upcount == 0 )
{
count10+=1;
}
if(downcount == 0 )
{
count10-=1;
}
text0[0] = count10/10 + 48;
text0[1] = count10 % 10 +48 ;
Lcd_out(2, 1,"Year:");
Lcd_out(2, 7, text0);
Delay_ms(500);
if( set == 0)
{
goto return5;
}
}
return5:
return count10;
}
void Delay2ms(void)
{
delay_ms(2);
}
void Delay200ms(void)
{
delay_ms(200);
}
void Delay500ms(void)
{
delay_ms(500);
}
void Delay1s(void)
{
delay_ms(1000);
}
void Delay4s(void)
{
delay_ms(4000);
}
void lcd_clr(void)
{
Lcd_Cmd(_LCD_CLEAR); //Lcd clear
Lcd_Cmd(_LCD_CURSOR_OFF);
}
void msg_welcome(void)
{Lcd_Out(1,1,"WELCOME ");
}
void msg_setmenu(void)
{
Lcd_out(1, 3, "SETTING MENU");
Lcd_out(2, 1, "Clock & Calender");
}
void msg_s_option(void)
{
Lcd_out(1,1, "SELECT OPTION:");
}
void msg_setclock(void)
{
Lcd_out(1,1, "Set Clock & Date");
}
void msg_clock(void)
{
Lcd_out(1, 1, "1:Minute 2:Hour");
Lcd_out(2, 1, "3:Date 4:Weekday");
}
void msg_calendar(void)
{
Lcd_out(1, 1, "5:Month 6:Year");
Lcd_out(2, 1, "Select Option:");
}
void msg_clock_notify(void)
{
Lcd_out(1, 1,"Clock is set");
}
void msg_switch_min_hr(void)
{
Lcd_out(2,1,"1:S1-Min 2:S1-Hr");
}
void msg_switch_on_notify(void)
{
Lcd_out(1,2,"Switch On time");
Lcd_out(2,3,"Disabled");
}
void msg_switch_off_notify(void)
{
Lcd_out(1,1,"Switch off time");
Lcd_out(2,1,"Disabled");
}
void msg_on_time(void)
{
Lcd_out(1,2, "Select Switch");
Lcd_out(2,2, "On Time");
}
void msg_off_time(void)
{
Lcd_out(1,2, "Select Switch");
Lcd_out(2,2, "Off Time");
}