PIC 16F88 Experimenter's Board Manual

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

Next Page