Program Function
  
				  We are  counting 1 second in software using Pause 1000 statement.  Pause statement works with milliseconds, so  1000 ms = 1s.  After each second  counted, Seconds variable is incremented by one.  If Seconds variable becomes 60, it gets reset to 0, and Minutes  variable is incremented by one.  When  Minutes variable reaches 60, it gets reset to 0, and Hours variable is  incremented by one.  When Hours variable  reaches 24, it gets reset to 0, & Days variable is incremented by one.  After each Seconds increment (&  increment of Minutes/Hours/Days variables if required), current time is  displayed on LCD in a nicely formatted message.  
				  
				  All of the  above instructions are placed in main loop, which runs over and over  again.  In each iteration of the main  loop, state of Reset & Trigger inputs are checked.  Based on the state of Reset & Trigger  inputs, either the main loop continues or is exited to clear all variables if  Reset input is low or is exited to a halt state if Trigger input becomes  inactive.
				  
				  Since we  are counting the time in software, instructions for incrementing Seconds,  Minutes, Hours, Days variables & displaying the time on LCD accounts for  overhead to actual time counting.  Ideally,  these instructions should be executed while the time is being counted  simultaneously, using hardware timers.   To keep things simple, we are not using hardware timers here (PIC16F88  has got hardware timers).  These  overheads create a lag in time counting, which accumulates into a few minutes a  day, this I feel is acceptable.  Note  that only variable values are updated every second on LCD, and not the text  “Time” “D” “S” “M” “S”.  If all of LCD  display was updated every second, it would increase the overhead resulting in  more lag.  
				  
	  Note that  we are dependent on the accuracy of PIC16F88’s internal clock frequency because  of software timing.  This can also  deviate from its normal value and cause about 5% error in timing accuracy.
CODE:
PIC16F88
                  'Elapsed  Time Firmware
                  'Measures elapse  time
                  'Displays  time in Seconds, Minutes, Hours, Days to 16 x 2 LCD
                  'RB4 input  as Reset, resets and stops the timer, active low
                  'RB5 input  as Trigger Active Level Select, 
                  'RB6 input  as Trigger, timer progresses when input is active level
                  'Unused  inputs made inputs
#CONFIG
    __config _CONFIG1,_INTRC_IO & _WDT_OFF  &  _PWRTE_ON &  _MCLR_OFF & _LVP_OFF & _CP_OFF 
#ENDCONFIG
define OSC 8 '8 MHz Device Frequency
RESET var  PORTB.4                     'reset input
                  LEVEL VAR  PORTB.5                    'trigger  level select input
                  TRIGGER  var PORTB.6                 'trigger input
RBPU var OPTION_REG.bit7 'Port B internal pullup enable bit
SECONDS  var byte                        'holds  seconds
                  MINUTES  var byte                         'holds  minutes
                  HOURS var  byte                            'holds  hours
                  DAYS var  byte                                'holds days
                    
                  OSCCON =  %01110100                 'select 8MHz  Device Frequency
                  ANSEL =  %00000000                     'make  PORTA pins digital I/O
                  PORTA =  %00000000                    'clear  PORTA data latches
                  TRISA =  %11100000                     'make PORTA (LCD Pins output, unused pins  inputs)
                  PORTB =  %00000000                   'clear PORTB  data latches
                  TRISB =  %11110111                   'make  PORTB  (LCD Pins output, unsued pins inputs)
                  RBPU =  0                                      'enable weak pull ups for PortB
pause  500                                     'let LCD initialize on power up
                  lcdout  254, 1, "TIME D     H", 254,  192, "     M     S"          'Display the fixed template
                  rst:
                  seconds =  0                                   'initialize seconds, minutes, hours, days
                  minutes =  0
                  hours = 0
                  days = 0
                  lcdout  254, 135, "000", 254, 141, "00", 254, 199, "00",  254, 205, "00"     'fill in  the display
                  stp:
                  if reset =  0 then rst                        'check if reset is pressed
                  if trigger  <> level then stp               'don't start/resume counting till trigger is active
main:                                        'main  loop for timing
                  pause  1000                                'count one second
                  seconds =  seconds + 1             'increment  seconds counter 
                  if seconds  = 60 then                  'check if 60  (0-59) seconds have elapsed
                  seconds =  0                               'reset seconds counter on passage of 60  seconds
                  minutes =  minutes + 1            'increment minute counter on passage of 60 seconds
                  if minutes  = 60 then                'check if 60  (0-59) minutes have elapsed
        minutes = 0                       'reset minutes counter on passage of 60  minutes
        hours = hours + 1              'increment the hours counter on passage of 60 minutes
        if hours = 24 then              'check if 24 (0-23) hours have  elapsed
           hours = 0                        'reset hours counter on passage of 24 hours
           days = days + 1              'increment days counter on passage of 24 hours
        endif                                  '
     endif
                  endif
                  lcdout  254, 135, dec3 days, 254, 141, dec2 hours, 254, 199, dec2 minutes, 254, 205,  dec2 seconds                            'update  the display after updating the timing registers
                  if trigger  <> level then stp         'check  for active trigger level, if its not there stop timing
                  if reset =  0 then rst                    'check for reset, if present stop counting
                  goto main
 
 
