How to set alarm using conditional loop in AT89C52?

Status
Not open for further replies.

ps_arunkumar

Member level 1
Joined
Nov 24, 2011
Messages
36
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,286
Activity points
1,545
RTC interfacing with AT89C52

Hi all,
I have interfaced ds1307 with AT89C52 and display time and date in lcd. I have interfaced 3 switches to controller. I am trying to achieve" When P1^0 is pressed i should be taken to set time and using P1^1 and P1^2, i should be able to set hour and minute. I am trying to compare the time with RTC using conditional loop. When the time matches, in lcd it display as Alarm".

As of now I am able to display time in lcd. When i press the P1^o, its taking me to set time but once i release the button I quits and displays the time again. I am making some logical mistakes in loop. Can you please look after my program and tell me where i am missing the logic.

thanks,
arun

Code:
 /************************************************
 * PIN descriptions
 ***********************************************
 * Hardware : Controller  -> AT89C52
 *            XTAL        -> 11.0592 MHz												 
 * I/O      : SCL         -> P2^6; 
 *            SDA         -> P2^7;          
 *            RS          -> P2.5
 *            Enable      -> P2.4
 *            Data4567    -> P2.0,P2.1,P2.2,P2.3   
 *    	  settime     -> P1^0;
 *            hour_pin    -> P1^1;
*             min_pin     -> P1^2;
 * Compiler : KEIL uVision 4.22
 * Date     : 27/11/2011
 */

#include<at89x52.h>
#include<stdio.h>
#include<ds1307.c>
#include<lcd.c>

sbit settime = P1^0;
sbit hour_pin =P1^1;
sbit min_pin = P1^2;
unsigned char  RTC_ARR[7];  /* Buffer for second,minute,.....,year */

unsigned int j, p;  
unsigned char hour_update = 0, min_update = 0;


void set_hour()
{
	while(hour_pin==1);
	hour_update++;
	if(hour_update>23)
	hour_update=0;
	LCD_command(0x80);
	sendno2lcd(hour_update);
	LCD_putc(':');
}			

void set_min()
{
	while(min_pin==1);
	min_update++;
	if(min_update>59)
	min_update=0;
	LCD_command(0x83);
	sendno2lcd(min_update);
}

void display_time()
{
		LCD_row1(); LCD_puts("Date:");	
		LCD_row2(); LCD_puts("Time:");
		/* Show Date in format dd/mm/yr */
		LCD_command(0x86);	/* Set LCD cursor at (1,6) */
		
		send2lcd(RTC_ARR[4]);		/* Show date on LCD */
		
		LCD_putc('/');		
		
		send2lcd(RTC_ARR[5]);	/* Show month on LCD */
		
		LCD_putc('/');	
		
		send2lcd(RTC_ARR[6]);		/* Show year on LCD */

		/* Show Time in format hr:min:sec */	
		LCD_command(0xC6);	/* Set LCD cursor at (2,6) */
		
		send2lcd(RTC_ARR[2]);		/* Show hour on LCD */
		
		LCD_putc(':');       
		   	
		send2lcd(RTC_ARR[1]);		/* Show min on LCD */
		
		LCD_putc(':');		
		
		send2lcd(RTC_ARR[0]);		/* Show sec on LCD */
}
/***************************** Main function *************************************/
void main()
{
	P0 = 0; P1 = 0;

	PowerOn();	/*Initialize LCD */
    
	LCD_row1(); LCD_puts("Date:");	
	LCD_row2(); LCD_puts("Time:");

/*  Setup time and enable oscillator */

	ReadRTC(&RTC_ARR[0]);        
	RTC_ARR[0] = RTC_ARR[0] & 0x7F;	/* enable oscillator (bit 7=0) */
	RTC_ARR[1] = 0x59;	/* minute = 59 */
	RTC_ARR[2] = 0x11;	/* hour = 11 ,24-hour mode(bit 6=0)	*/
	RTC_ARR[3] = 0x04;	/* Day = 1 or sunday */
	RTC_ARR[4] = 0x23;	/* Date = 23 */
	RTC_ARR[5] = 0x11;	/* month = November */
	RTC_ARR[6] = 0x11;	/* year = 2011 */
	WriteRTC(&RTC_ARR[0]);	/* Set RTC */

    while(1)
	{
		ReadRTC(&RTC_ARR[0]);        
 	
		display_time();

		if(settime==1)
		{	
			for(p=0;p=10;p++);		//debounce check
			if(settime==1)
			{
				LCD_clear();		  
				LCD_puts("Time set");
				for(j=0;j<1000;j++);
				if(hour_pin==1)
				set_hour();
				if(min_pin==1)
				set_min();
   			}		
			LCD_clear();
		}

		if(RTC_ARR[2]==hour_update)
		{
			if(RTC_ARR[1]==min_update)
			{
				LCD_clear();
				LCD_puts("Alarm");
			}
		}
	}
}
 
Last edited:

To monitor P1.0 you must set it as input.

Before checking settime variable, initialize it with 1 to make it input port pin. This is applicable other pins connected to a switch.
The structure of the program have to be changed slightly. try to use while loop to monitor port pins
or , better
Try to use external hardware inturrupt
 
Last edited:

Also, Its important what settime variable is receiving(0 or 1) when you close the switch. It depends upon how the switch is connected.
 

I am using external interrupt 1(INT 1). I am able to set the time but the alarm i not triggering in the set time. I have attached the screen shot of circuit diagram. Please tell me why the alarm is not triggering.

Code:
 /************************************************
 * PIN descriptions
 ***********************************************
 * Hardware : Controller  -> AT89C52
 *            XTAL        -> 11.0592 MHz												 
 * I/O      : SCL         -> P2^6; 
 *            SDA         -> P2^7;          
 *            RS          -> P2.5
 *            Enable      -> P2.4
 *            Data4567    -> P2.0,P2.1,P2.2,P2.3   
 *    	       Serial port -> P3^1;
 * Compiler : KEIL uVision 4.22
 */

#include<at89x52.h>
#include<stdio.h>
#include<ds1307.c>
#include<lcd.c>

sbit led = P3^5;
sbit set_time = P1^0;
sbit hour_pin =P1^1;
sbit min_pin = P1^2;
unsigned char  RTC_ARR[7];  /* Buffer for second,minute,.....,year */

unsigned int j, p;  
unsigned char hour_update = 0, min_update = 0;


void set_hour()
{
	while(hour_pin==0);
	hour_update++;
	if(hour_update>23)
	hour_update=0;
	LCD_command(0x80);
	sendno2lcd(hour_update);
	LCD_putc(':');
}			

void set_min()
{
	while(min_pin==0);
	min_update++;
	if(min_update>59)
	min_update=0;
	LCD_command(0x83);
	sendno2lcd(min_update);
}

void settime() interrupt 2
{
	unsigned int i,j;
	LCD_clear();
	if(set_time == 0)
	{
		LCD_puts("Set time");
		for(j=0;j<=1000;j++);		    
		LCD_clear();
		sendno2lcd(hour_update);
		LCD_putc(':');
		sendno2lcd(min_update);
		while(set_time==0)
		{
		   	for(i=0;i<10;i++);
			if(hour_pin==0)
			set_hour();
			if(min_pin==0)
			set_min();
		}
	}
	else
	{
		LCD_puts("Exit");
		LCD_clear();
	}
}		

void display_time()
{
		LCD_row1(); LCD_puts("Date:");	
		LCD_row2(); LCD_puts("Time:");
		/* Show Date in format dd/mm/yr */
		LCD_command(0x86);	/* Set LCD cursor at (1,6) */
		
		send2lcd(RTC_ARR[4]);		/* Show date on LCD */
		
		LCD_putc('/');		
		
		send2lcd(RTC_ARR[5]);	/* Show month on LCD */
		
		LCD_putc('/');	
		
		send2lcd(RTC_ARR[6]);		/* Show year on LCD */

		/* Show Time in format hr:min:sec */	
		LCD_command(0xC6);	/* Set LCD cursor at (2,6) */
		
		send2lcd(RTC_ARR[2]);		/* Show hour on LCD */
		
		LCD_putc(':');       
		   	
		send2lcd(RTC_ARR[1]);		/* Show min on LCD */
		
		LCD_putc(':');		
		
		send2lcd(RTC_ARR[0]);		/* Show sec on LCD */
}
/***************************** Main function *************************************/
void main(void)
{
//	P0 = 0; P1 = 1;

	PowerOn();	/*Initialize LCD */
    
	IE = 0x84;  /* Enable INT1 */

	LCD_row1(); LCD_puts("Date:");	
	LCD_row2(); LCD_puts("Time:");

/*  Setup time and enable oscillator */

	ReadRTC(&RTC_ARR[0]);        
	RTC_ARR[0] = RTC_ARR[0] & 0x7F;	/* enable oscillator (bit 7=0) */
	RTC_ARR[1] = 0x59;	/* minute = 59 */
	RTC_ARR[2] = 0x11;	/* hour = 11 ,24-hour mode(bit 6=0)	*/
	RTC_ARR[3] = 0x04;	/* Day = 1 or sunday */
	RTC_ARR[4] = 0x23;	/* Date = 23 */
	RTC_ARR[5] = 0x11;	/* month = November */
	RTC_ARR[6] = 0x11;	/* year = 2011 */
	WriteRTC(&RTC_ARR[0]);	/* Set RTC */

    while(1)
	{
		ReadRTC(&RTC_ARR[0]);        
 	
		display_time();

		if(hour_update==RTC_ARR[2])
		{
			if(min_update==RTC_ARR[1])
			{
				LCD_clear();
				LCD_puts("Alarm");
				led=0;
			}
		LCD_clear();
		}
	}
}
 

Attachments

  • circuit diagram.png
    50.8 KB · Views: 181
Last edited:

Dear Arun,

I think your code is ok. All you need is a short delay after LCD_puts("Alarm"); Actually "Alarm" is displayed but there is no delay, so it is cleared by the next function call and showing time again.!


One thing, Can you tell me the source of your circuit? Your DS1307's SCL and SDA are using pulldown resistances in place of Pulled up resistances as indicated by datasheet.
 
Last edited:

I have attached my ds1307 and lcd files, please correct me where I am going wrong.
 

Attachments

  • files.zip
    2.1 KB · Views: 95

Here is a standard connection picture. see two 10K resistors connectod between +5V supply and SCL and SDA? I told you about them in my previous post


 

Yes you are right and i have used pull down resistor. If i use pull up resistor do i need to change anything on my code. Can you please look into my code and tell me.
 

According to the code, there should be a LED connected to pin 3.5(but not shown in the schematic). Before using it set this pin as output.
 

I changed the code so that I can compare the hexadecimal no. of RTC with alarm loop. It worked and I am able to achieve the result. I used pull up resistor for RTC and it worked.

Code:
 /************************************************
 * PIN descriptions
 ***********************************************
 * Hardware : Controller  -> AT89C52
 *            XTAL        -> 11.0592 MHz												 
 * I/O      : SCL         -> P2^6; 
 *            SDA         -> P2^7;          
 *            RS          -> P2.5
 *            Enable      -> P2.4
 *            Data4567    -> P2.0,P2.1,P2.2,P2.3   
 *    		  Serial port -> P3^1;
 * Compiler : KEIL uVision 4.22
 * Date     : 27/11/2011
 * Author   : Arun
 */

#include<at89x52.h>
#include<stdio.h>
#include<ds1307.c>
#include<lcd.c>

sbit led = P3^5;
sbit set_time = P1^0;
sbit hour_pin =P1^1;
sbit min_pin = P1^2;
unsigned char  RTC_ARR[7];  /* Buffer for second,minute,.....,year */

unsigned int j, p;  
unsigned char hour_update = 0, min_update = 0;


void set_hour()
{
	while(hour_pin==0);
	hour_update++;
	if(hour_update>23)
	hour_update=0;
	LCD_command(0x80);
	sendno2lcd(hour_update);
	LCD_putc(':');
}			

void set_min()
{
	while(min_pin==0);
	min_update++;
	if(min_update>59)
	min_update=0;
	LCD_command(0x83);
	sendno2lcd(min_update);
}

void settime() interrupt 2
{
	unsigned int i,j;
	LCD_clear();
	if(set_time == 0)
	{
		LCD_puts("Set time");
		for(j=0;j<=1000;j++);		    
		LCD_clear();
		sendno2lcd(hour_update);
		LCD_putc(':');
		sendno2lcd(min_update);
		while(set_time==0)
		{
		   	for(i=0;i<10;i++);
			if(hour_pin==0)
			set_hour();
			if(min_pin==0)
			set_min();
		}
	}
	else
	{
		LCD_puts("Exit");
		LCD_clear();
	}
}		

void display_time()
{
		LCD_row1(); LCD_puts("Date:");	
		LCD_row2(); LCD_puts("Time:");
		/* Show Date in format dd/mm/yr */
		LCD_command(0x86);	/* Set LCD cursor at (1,6) */
		
		send2lcd(RTC_ARR[4]);		/* Show date on LCD */
		
		LCD_putc('/');		
		
		send2lcd(RTC_ARR[5]);	/* Show month on LCD */
		
		LCD_putc('/');	
		
		send2lcd(RTC_ARR[6]);		/* Show year on LCD */

		/* Show Time in format hr:min:sec */	
		LCD_command(0xC6);	/* Set LCD cursor at (2,6) */
		
		send2lcd(RTC_ARR[2]);		/* Show hour on LCD */
		
		LCD_putc(':');       
		   	
		send2lcd(RTC_ARR[1]);		/* Show min on LCD */
		
		LCD_putc(':');		
		
		send2lcd(RTC_ARR[0]);		/* Show sec on LCD */
}
/***************************** Main function *************************************/
void main(void)
{
	led=0;
	PowerOn();	/*Initialize LCD */
    
	IE = 0x84;  /* Enable INT1 */

	LCD_row1(); LCD_puts("Date:");	
	LCD_row2(); LCD_puts("Time:");

/*  Setup time and enable oscillator */

	ReadRTC(&RTC_ARR[0]);        
	RTC_ARR[0] = RTC_ARR[0] & 0x7F;	/* enable oscillator (bit 7=0) */
	RTC_ARR[1] = 0x01;	/* minute = 59 */
	RTC_ARR[2] = 0x10;	/* hour = 11 ,24-hour mode(bit 6=0)	*/
	RTC_ARR[3] = 0x04;	/* Day = 1 or sunday */
	RTC_ARR[4] = 0x23;	/* Date = 23 */
	RTC_ARR[5] = 0x11;	/* month = November */
	RTC_ARR[6] = 0x11;	/* year = 2011 */
	WriteRTC(&RTC_ARR[0]);	/* Set RTC */

    while(1)
	{
		ReadRTC(&RTC_ARR[0]);        
 	
		display_time();

		if(BCD2HEX(RTC_ARR[2])==hour_update)
		{
			if(BCD2HEX(RTC_ARR[1])==min_update)
			{
				LCD_clear();
				LCD_puts("Alarm");
				led=1;
				for(i=0;i<100;i++)
				for(j=0;j<=1000;j++);
			}
	//	LCD_clear();
		}	 
	}
}

Thank you so much for the help Sir!
 

Still some problems are there. The clock will display time as initialize at the starting of main() and will display the incremented time as well. But there are still some problems in settime function().
 
Last edited:

When i simulated in Proteus i got the result which i intended. Now i am working on keypad interfacing.
 

Status
Not open for further replies.

Similar threads

Cookies are required to use this site. You must accept them to continue using the site. Learn more…