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
    3
    0
    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.
     
    #1
  2. t06afre

    t06afre AAC Fanatic!

    Joined:
    May 11, 2009
    5,939
    1,222
    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
     
    #2
  3. roshani

    roshani Thread Starter New Member

    Joined:
    Sep 8, 2012
    3
    0
    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.
     
    • DL1.PNG
      DL1.PNG
      File size:
      24.4 KB
      Views:
      98
    • DL2.PNG
      DL2.PNG
      File size:
      24.6 KB
      Views:
      82
    • DL3.PNG
      DL3.PNG
      File size:
      51.5 KB
      Views:
      74
    #3
  4. absf

    absf Well-Known Member

    Joined:
    Dec 29, 2010
    1,213
    272
    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
     
    #4
    roshani likes this.
  5. t06afre

    t06afre AAC Fanatic!

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

    Eric007 Well-Known Member

    Joined:
    Aug 5, 2011
    1,008
    33
    !:)

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

    takao21203 Well-Known Member

    Joined:
    Apr 28, 2012
    3,322
    435
    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.
     
    #7
    roshani likes this.
  8. roshani

    roshani Thread Starter New Member

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

    BMorse Senior Member

    Joined:
    Sep 26, 2009
    2,673
    233
    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 ( (Unknown Language)):
    1. /*********************************************************************/
    2. void set_clock()
    3. {   unsigned char i;  
    4.     unsigned char temp;      //temp is used to hold a value specifying which digit we are changing
    5.     temp=1;                      //start with HOUR
    6.     i=1;
    7.     lcd_clear();                 //clear display
    8.     lcd_goto(0x40);           //go to second row
    9.     lcd_puts(mSet);          //display user message
    10.     //must convert values to decimal for displaying since they are in Binary Coded Decimal format used in the RTC
    11.     rtc_hour=myBCD2DEC(rtc_hour);
    12.     rtc_min=myBCD2DEC(rtc_min);
    13.     rtc_month=myBCD2DEC(rtc_month);
    14.     rtc_date=myBCD2DEC(rtc_date);
    15.     rtc_year=myBCD2DEC(rtc_year);
    16.     rtc_day=myBCD2DEC(rtc_day);
    17.     update_time();             //display time/date on LCD
    18.  
    19.     while(!Middle_Switch){};        //wait for button to be released
    20.    
    21.     while(i){
    22.     if(!Middle_Switch){
    23.         ++temp;
    24.         DelayMs(200);
    25.         while(!Middle_Switch){};        //wait for button to be released
    26.     }; 
    27.     switch(temp) {
    28.         case 1: //Hour
    29.             if (!Right_Switch){
    30.                 ++rtc_hour;
    31.                 if(rtc_hour>23){rtc_hour=0;};
    32.                 DelayMs(200);           //delay to De-Bounce switch
    33.             }
    34.             else if (!Left_Switch){
    35.                 if(rtc_hour==0){
    36.                     rtc_hour=23;}
    37.                 else{
    38.                     --rtc_hour;
    39.                 };
    40.                 DelayMs(200);
    41.             };
    42.             break;
    43.         case 2: //Minutes
    44.             if (!Right_Switch){
    45.                 ++rtc_min;
    46.                 if(rtc_min>59){rtc_min=0;};
    47.                 DelayMs(200);
    48.             }
    49.             else if (!Left_Switch){
    50.                 if(rtc_min==0){
    51.                     rtc_min=59;}
    52.                 else{
    53.                     --rtc_min;
    54.                 };
    55.                 DelayMs(200);
    56.             };
    57.             break;
    58.         case 3: //Month
    59.             if (!Right_Switch){
    60.                 ++rtc_month;
    61.                 if(rtc_month>12){rtc_month=1;};
    62.                 DelayMs(200);
    63.             }
    64.             else if (!Left_Switch){
    65.                 if(rtc_month==1){
    66.                     rtc_month=12;}
    67.                 else{
    68.                     --rtc_month;
    69.                 };
    70.                 DelayMs(200);
    71.             };
    72.             break;
    73.         case 4: //Date
    74.             if (!Right_Switch){
    75.                 ++rtc_date;
    76.                 if(rtc_date>31){rtc_date=1;};
    77.                 DelayMs(200);
    78.             }
    79.             else if (!Left_Switch){
    80.                 if(rtc_date==1){
    81.                     rtc_date=31;}
    82.                 else{
    83.                     --rtc_date;
    84.                 };
    85.                 DelayMs(200);
    86.             };
    87.             break;
    88.         case 5: //year
    89.             if (!Right_Switch){
    90.                 ++rtc_year;
    91.                 if(rtc_year>99){rtc_year=0;};
    92.                 DelayMs(200);
    93.             }
    94.             else if (!Left_Switch){
    95.                 if(rtc_year==0){
    96.                     rtc_year=99;}
    97.                 else{
    98.                     --rtc_year;
    99.                 };
    100.                 DelayMs(200);
    101.             };
    102.             break;
    103.         case 6: //day of week (sunday = 1)
    104.             if (!Right_Switch){
    105.                 ++rtc_day;
    106.                 if(rtc_day>7){rtc_day=1;};
    107.                 DelayMs(200);
    108.             }
    109.             else if (!Left_Switch){
    110.                 if(rtc_day==1){
    111.                     rtc_day=7;}
    112.                 else{
    113.                     --rtc_day;
    114.                 };
    115.                 DelayMs(200);
    116.             };
    117.             break;
    118.         case 7:
    119.             //convert settings back to BCD
    120.             rtc_hour=myDEC2BCD(rtc_hour);
    121.             rtc_min=myDEC2BCD(rtc_min);
    122.             rtc_sec=0;
    123.             rtc_month=myDEC2BCD(rtc_month);
    124.             rtc_date=myDEC2BCD(rtc_date);
    125.             rtc_year=myDEC2BCD(rtc_year);
    126.             rtc_day=myDEC2BCD(rtc_day);
    127.             //save all settings back to registers
    128.             write_clk_regs();
    129.             i=0;       
    130.             break;
    131.         };//end switch
    132.         update_time();
    133.     };//end while
    134. }//end set clock
    135. /*********************************************************************/
    136. //Function used to display the date/time on 2x16 LCD//
    137. void update_time()
    138. {   lcd_goto(0x00);
    139.     sprintf(LCD_Buffer,"%2d:%2d %2d|%2d|%2d %d",rtc_hour,rtc_min,rtc_month,rtc_date,rtc_year,rtc_day);
    140.     lcd_puts(LCD_Buffer);
    141. }
    142. /*********************************************************************/
    143.  
    144.  
     
    Last edited: Sep 8, 2012
    #9
    roshani, absf and Eric007 like this.
  10. MMcLaren

    MMcLaren Well-Known Member

    Joined:
    Feb 14, 2010
    661
    91
    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 ( (Unknown Language)):
    1. #define setmode swflags.0       // set sw on RB0
    2. #define rtarrow swflags.1       // rt arrow on RB1
    3. #define uparrow swflags.2       // up arrow on RB2
    4. #define dnarrow swflags.3       // dn arrow on RB3
    5. #define uplatch swlatch.2       // up arrow switch state latch bit
    6. #define dnlatch swlatch.3       // dn arrow switch state latch bit
    7.  
    Code ( (Unknown Language)):
    1.     if(setmode & mode < 3)      // if <set> switch and display "on"
    2.     { loadbuffer();             // copy source array to set[] buffer
    3.       group = 0;                // set starting group (hours/months)
    4.       setlimits();              // set lower/upper field limits
    5.       while(setmode)            // while <set> switch "on"
    6.       { if(rtarrow)             // if <rt arrow> press
    7.         { rtarrow = 0;          // clear the "new press" flag and
    8.           if(group == 2)        // bump display group, 0..2
    9.             group = 0;          //
    10.           else                  //
    11.             group++;            //
    12.           setlimits();          // set lower/upper field limits
    13.         }                       //
    14.         while(uplatch)          // while <up arrow> held pressed
    15.         { uparrow = 0;          // increment display group value
    16.           if(set[group] == hilimit)
    17.             set[group] = lolimit;
    18.           else                  //
    19.             set[group]++;       //
    20.           delay_ms(220);        // delay approx 1/4 sec
    21.           if(uplatch)           // if <up arrow> still pressed
    22.             beepctr = 16;       // send repeat 'click'
    23.         }
    24.         while(dnlatch)          // while <dn arrow> held pressed
    25.         { dnarrow = 0;          // decrement display group value
    26.           if(set[group] == lolimit)
    27.             set[group] = hilimit;
    28.           else                  //
    29.             set[group]--;       //
    30.           delay_ms(220);        // delay approx 1/4 sec
    31.           if(dnlatch)           // if still pressed
    32.             beepctr = 16;       // send repeat 'click'
    33.         }
    34.       }
    35.       intcon.GIE = 0;           // suspend interrupts
    36.       savebuffer();             // copy set[] buffer to source array
    37.       if(mode == 0)             // if 'clock' was 'source' then
    38.       { rtcl = 25;              // reset RTC counters, including
    39.         rtch = 0;               // set switch debounce time...
    40.       }
    41.       intcon.GIE = 1;           // restart interrupts
    42.     }
    43.  
    Code ( (Unknown Language)):
    1. void setlimits()
    2. { if(mode == 2)                 // if calendar mode
    3.   { lolimit = 1;                //
    4.     hilimit = days_in[month-1]; // limits 1..days_in_month
    5.     if(group == 0)              // if 'month' group
    6.       hilimit = 12;             // limits 1..12
    7.     if(group == 1)              // if 'date' group and
    8.     { if(month == 2)            // if 'month' is february and
    9.         if(!(year & 3))         // if a leap year then
    10.           hilimit = 29;         // limits 1..29
    11.       if(date > hilimit)        // if 'date' field > hilimit
    12.         date = hilimit;         // set it to hilimit
    13.     }
    14.     if(group == 2)              // if 'year' group
    15.     { lolimit = 0;              //
    16.       hilimit = 99;             // limits 0..99
    17.     }
    18.   }
    19.   else                          // clock or timer mode
    20.   { lolimit = 0;                //
    21.     hilimit = 59;               // limits 00..59
    22.     if(group == 0)              // if 'hour' group
    23.       hilimit = 23;             // limits 00..23
    24.   }
    25. }
    26.  
     
    Last edited: Sep 9, 2012
    #10
    roshani and absf like this.
  11. absf

    absf Well-Known Member

    Joined:
    Dec 29, 2010
    1,213
    272
    That was terrific...:cool:

    Allen
     
    #11
Loading...