set date and time in PIC16f877A using push buttons

Thread Starter

roshani

Joined Sep 8, 2012
3
I am trying to set time(hour, minute, second) and date(year, month, day) using pic16f877A, 16*2 LCD display and push buttons. i have used timer0 for RTC. How do i define variables and set the date and time with push buttons? please help me with code in c language.
 

t06afre

Joined May 11, 2009
5,934
Schoolwork ;) Anyway I think you have to tell us more about your project before we can help. Have you made some schematic you can show us. And what is your coding so far
 

Thread Starter

roshani

Joined Sep 8, 2012
3
i am working on data logger project. analog inputs are made to the channels(AN0-AN5). portB pins (RB4-RB7) have been used to generate interrupt on change in their input state (RBIE=1). portD(D0-D7) is used for providing data to LCD, RC4 and RC5 connected to control pins.
The ports are initialized as:
TRISA=0xff;
TRISC=0x00;
TRISB=0b11111111;
TRISD=0x00;
i have attached 3 views of my circuit layout.
i have handled the ADC conversions. To record the data, first i have to set the date and time once.
 

Attachments

absf

Joined Dec 29, 2010
1,968
If you look an ordinary digital clock, there should be some buttons like MODE, UP, DOWN,"<-" and "->" for setting the clock.

Of course, you may also need to give the Date and time some default values in your program like:

(Date) 01:01:2012
(Time) 12:00:00

But once you switched on your mcu, the time and date would never be the current time and date, cause you are not using an external RTC with battery back up. Even if you did use an RTC, it would still need to be set up once at least.

As for how you can set up the Date and Time, I am sure there are lots of programs written in PIC C that you can refer to. But first you'll need to put some push button switches on your PIC.

Allen
 

t06afre

Joined May 11, 2009
5,934
The analog part with the opamps of your project will not work in any way. It has to be redesign. And I can not grasp what you want it to do. Your project has several parts. Why not start with the more easy parts. Like writing stuff to the LCD.
Are you planing to use the internal oscillator. In a real world project that would not be wise. A common method then using a PIC as clock. Is to use a clock crystal connected to one of the 16 bit timers. Most often timer2 I think. As it is now your project has way to many serious issues
 

Eric007

Joined Aug 5, 2011
1,158
!:)

I am actually doing somrthing very smilar at the moment and only have tomorrow to finish up everything or else I am dead!!

The only difference is I am Not displaying date and using seven segments and all the setting of the time, of the alarm, displaying of the alarm/current time MUST be done (or execute instantaneously)...

I am suding the concept of cooperative multitasking which is an alternative of RTOS!

Gudluck!:)
 

takao21203

Joined Apr 28, 2012
3,702
Having character LCD code available (in working condition) is the foundation which is required for your project.

I have some code for that on my website:
http://pic.hitechworld.org/data/

hitachi LCD, and gc_1824 (which is a newer revision of the same code).

This code can be made working for 16F and 18F PIC relatively easily.
If you don't need the serial interface, simply remove it.

The LCD interface is not optimized for minimum possible timing, but it works.

If you expect someone to write the complete program for you, it must be someone with a lot of time available, and very generous towards the general public.

Learning to use C language is an active process which requires time, resources, experimentation, and considerable efforts. If you want to delegate the work, expect to have to pay for it if you want professional code.

On public forums you may be able to obtain some useful bits and pieces of source code, if you ask the right questions.
 

Thread Starter

roshani

Joined Sep 8, 2012
3
The analog part with the opamps of your project will not work in any way. It has to be redesign. And I can not grasp what you want it to do. Your project has several parts. Why not start with the more easy parts. Like writing stuff to the LCD.
Are you planing to use the internal oscillator. In a real world project that would not be wise. A common method then using a PIC as clock. Is to use a clock crystal connected to one of the 16 bit timers. Most often timer2 I think. As it is now your project has way to many serious issues
actually, i am using an external 20MHz oscillator crystal in the hardware. Don't get confused with the comparators, they are just there to generate square wave. I would be thankful if i could get some idea regarding how the selection for date and time is to be made with four push buttons for setting them and how i can use pull up or pull down buttons to make increaments and decrements in their values.
 

BMorse

Joined Sep 26, 2009
2,675
You have to have atleast 3 switches to use to set the time/Date, 1 switch will be the Select/Enter switch(Middle_Switch), the other 2 will be for incrementing the value (Right_Switch) and decrementing the value (Left_Switch), all switches are pulled High with internal pullups on PORTB, and we look for it to go LOW when a switch is pressed...

for example: (this code is actually used in a PIC16F887 @ 20Mhz, written in Hi-Tech C, and used with a DS1302 Real time clock and Calendar)

Rich (BB code):
/*********************************************************************/
void set_clock()
{	unsigned char i;   
	unsigned char temp;      //temp is used to hold a value specifying which digit we are changing
	temp=1;                      //start with HOUR
	i=1;
	lcd_clear();                 //clear display
	lcd_goto(0x40);           //go to second row
	lcd_puts(mSet);          //display user message
	//must convert values to decimal for displaying since they are in Binary Coded Decimal format used in the RTC
	rtc_hour=myBCD2DEC(rtc_hour);
	rtc_min=myBCD2DEC(rtc_min);
	rtc_month=myBCD2DEC(rtc_month);
	rtc_date=myBCD2DEC(rtc_date);
	rtc_year=myBCD2DEC(rtc_year);
	rtc_day=myBCD2DEC(rtc_day);
	update_time();             //display time/date on LCD

	while(!Middle_Switch){};		//wait for button to be released
	
	while(i){
	if(!Middle_Switch){
		++temp;
		DelayMs(200);
		while(!Middle_Switch){};		//wait for button to be released
	};	
	switch(temp) {
		case 1:	//Hour
			if (!Right_Switch){
				++rtc_hour;
				if(rtc_hour>23){rtc_hour=0;};
				DelayMs(200);           //delay to De-Bounce switch
			}
			else if (!Left_Switch){
				if(rtc_hour==0){
					rtc_hour=23;}
				else{
					--rtc_hour;
				};
				DelayMs(200);
			};
			break;
		case 2:	//Minutes
			if (!Right_Switch){
				++rtc_min;
				if(rtc_min>59){rtc_min=0;};
				DelayMs(200);
			}
			else if (!Left_Switch){
				if(rtc_min==0){
					rtc_min=59;}
				else{
					--rtc_min;
				};
				DelayMs(200);
			};
			break;
		case 3:	//Month
			if (!Right_Switch){
				++rtc_month;
				if(rtc_month>12){rtc_month=1;};
				DelayMs(200);
			}
			else if (!Left_Switch){
				if(rtc_month==1){
					rtc_month=12;}
				else{
					--rtc_month;
				};
				DelayMs(200);
			};
			break;
		case 4:	//Date
			if (!Right_Switch){
				++rtc_date;
				if(rtc_date>31){rtc_date=1;};
				DelayMs(200);
			}
			else if (!Left_Switch){
				if(rtc_date==1){
					rtc_date=31;}
				else{
					--rtc_date;
				};
				DelayMs(200);
			};
			break;
		case 5:	//year
			if (!Right_Switch){
				++rtc_year;
				if(rtc_year>99){rtc_year=0;};
				DelayMs(200);
			}
			else if (!Left_Switch){
				if(rtc_year==0){
					rtc_year=99;}
				else{
					--rtc_year;
				};
				DelayMs(200);
			};
			break;
		case 6:	//day of week (sunday = 1)
			if (!Right_Switch){
				++rtc_day;
				if(rtc_day>7){rtc_day=1;};
				DelayMs(200);
			}
			else if (!Left_Switch){
				if(rtc_day==1){
					rtc_day=7;}
				else{
					--rtc_day;
				};
				DelayMs(200);
			};
			break;
		case 7:
			//convert settings back to BCD
			rtc_hour=myDEC2BCD(rtc_hour);
			rtc_min=myDEC2BCD(rtc_min);
			rtc_sec=0;
			rtc_month=myDEC2BCD(rtc_month);
			rtc_date=myDEC2BCD(rtc_date);
			rtc_year=myDEC2BCD(rtc_year);
			rtc_day=myDEC2BCD(rtc_day);
			//save all settings back to registers
			write_clk_regs();
			i=0;		
			break;
		};//end switch
		update_time();
	};//end while
}//end set clock
/*********************************************************************/
//Function used to display the date/time on 2x16 LCD//
void update_time()
{	lcd_goto(0x00);
	sprintf(LCD_Buffer,"%2d:%2d %2d|%2d|%2d %d",rtc_hour,rtc_min,rtc_month,rtc_date,rtc_year,rtc_day);
	lcd_puts(LCD_Buffer);
}
/*********************************************************************/
 
Last edited:

MMcLaren

Joined Feb 14, 2010
861
Would anyone mind if I supplement the fine example code excerpt from BMorse? I don't mean to suggest one example is "better" than the other... just different.

In my single chip Charlie Clock program (2007) I decided to use a single set of routines for the <up> arrow, <down> arrow, and <right> arrow keys while in [set] mode. Basically, the <up> and <down> arrow keys are used to increment or decrement the current display group (month, day, year, hour, minutes, or seconds) of the current display (clock, timer, or calendar) and the <right> arrow key is used to move to the next display group. The routines include relatively simple upper/lower field limit logic which prevents users from entering invalid dates such as 02/30/12 or 04/31/12.

Good luck on your project.

Cheerful regards, Mike

Rich (BB code):
#define setmode swflags.0       // set sw on RB0
#define rtarrow swflags.1       // rt arrow on RB1
#define uparrow swflags.2       // up arrow on RB2
#define dnarrow swflags.3       // dn arrow on RB3
#define uplatch swlatch.2       // up arrow switch state latch bit
#define dnlatch swlatch.3       // dn arrow switch state latch bit
Rich (BB code):
    if(setmode & mode < 3)      // if <set> switch and display "on"
    { loadbuffer();             // copy source array to set[] buffer
      group = 0;                // set starting group (hours/months)
      setlimits();              // set lower/upper field limits
      while(setmode)            // while <set> switch "on"
      { if(rtarrow)             // if <rt arrow> press
        { rtarrow = 0;          // clear the "new press" flag and
          if(group == 2)        // bump display group, 0..2
            group = 0;          //
          else                  //
            group++;            //
          setlimits();          // set lower/upper field limits
        }                       //
        while(uplatch)          // while <up arrow> held pressed
        { uparrow = 0;          // increment display group value
          if(set[group] == hilimit)
            set[group] = lolimit;
          else                  //
            set[group]++;       //
          delay_ms(220);        // delay approx 1/4 sec
          if(uplatch)           // if <up arrow> still pressed
            beepctr = 16;       // send repeat 'click'
        }
        while(dnlatch)          // while <dn arrow> held pressed
        { dnarrow = 0;          // decrement display group value
          if(set[group] == lolimit)
            set[group] = hilimit;
          else                  //
            set[group]--;       //
          delay_ms(220);        // delay approx 1/4 sec
          if(dnlatch)           // if still pressed
            beepctr = 16;       // send repeat 'click'
        }
      }
      intcon.GIE = 0;           // suspend interrupts
      savebuffer();             // copy set[] buffer to source array
      if(mode == 0)             // if 'clock' was 'source' then
      { rtcl = 25;              // reset RTC counters, including
        rtch = 0;               // set switch debounce time...
      }
      intcon.GIE = 1;           // restart interrupts
    }
Rich (BB code):
void setlimits()
{ if(mode == 2)                 // if calendar mode
  { lolimit = 1;                //
    hilimit = days_in[month-1]; // limits 1..days_in_month
    if(group == 0)              // if 'month' group
      hilimit = 12;             // limits 1..12
    if(group == 1)              // if 'date' group and
    { if(month == 2)            // if 'month' is february and
        if(!(year & 3))         // if a leap year then
          hilimit = 29;         // limits 1..29
      if(date > hilimit)        // if 'date' field > hilimit
        date = hilimit;         // set it to hilimit
    }
    if(group == 2)              // if 'year' group
    { lolimit = 0;              //
      hilimit = 99;             // limits 0..99
    }
  }
  else                          // clock or timer mode
  { lolimit = 0;                //
    hilimit = 59;               // limits 00..59
    if(group == 0)              // if 'hour' group
      hilimit = 23;             // limits 00..23
  }
}
 

Attachments

Last edited:
Top