set date and time in PIC16f877A using push buttons

Discussion in 'Embedded Systems and Microcontrollers' started by roshani, Sep 8, 2012.

  1. roshani

    roshani Thread Starter New Member

    Joined:
    Sep 8, 2012
    Messages:
    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.
  2. t06afre

    t06afre AAC Fanatic!

    Joined:
    May 11, 2009
    Messages:
    5,939
    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
  3. roshani

    roshani Thread Starter New Member

    Joined:
    Sep 8, 2012
    Messages:
    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.

    Attached Files:

    • DL1.PNG
      DL1.PNG
      File size:
      24.4 KB
      Views:
      33
    • DL2.PNG
      DL2.PNG
      File size:
      24.6 KB
      Views:
      25
    • DL3.PNG
      DL3.PNG
      File size:
      51.5 KB
      Views:
      23
  4. absf

    absf Active Member

    Joined:
    Dec 29, 2010
    Messages:
    988
    Location:
    Sarawak (GMT+8)
    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
    roshani likes this.
  5. t06afre

    t06afre AAC Fanatic!

    Joined:
    May 11, 2009
    Messages:
    5,939
    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
  6. Eric007

    Eric007 Active Member

    Joined:
    Aug 5, 2011
    Messages:
    988
    Location:
    Paris, France!
    !:)

    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!:)
    roshani likes this.
  7. takao21203

    takao21203 Well-Known Member

    Joined:
    Apr 28, 2012
    Messages:
    2,498
    Location:
    Ireland
    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.
    roshani likes this.
  8. roshani

    roshani Thread Starter New Member

    Joined:
    Sep 8, 2012
    Messages:
    3
    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.
  9. BMorse

    BMorse Well-Known Member

    Joined:
    Sep 26, 2009
    Messages:
    2,668
    Location:
    Vermontville, Michigan (GMT -5)
    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)

    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: Sep 8, 2012
    roshani, absf and Eric007 like this.
  10. MMcLaren

    MMcLaren Active Member

    Joined:
    Feb 14, 2010
    Messages:
    648
    Location:
    Michigan, USA
    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

    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
    
    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
        } 
    
    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
      }
    }
    

    Attached Files:

    Last edited: Sep 9, 2012
    roshani and absf like this.
  11. absf

    absf Active Member

    Joined:
    Dec 29, 2010
    Messages:
    988
    Location:
    Sarawak (GMT+8)
    That was terrific...:cool:

    Allen
Similar Threads
Forum Title Date
Embedded Systems and Microcontrollers 8x8 LED matrix update Aug 23, 2014
Embedded Systems and Microcontrollers Flash Programming (to update your firmware) Apr 22, 2012
Embedded Systems and Microcontrollers Update Delay in DSP Mar 4, 2012
Embedded Systems and Microcontrollers Please update me where should I starts Feb 10, 2012
Embedded Systems and Microcontrollers GPS module - data op only updates when speed > 3km Oct 8, 2011

Share This Page