All you have to do is code a delay that takes exactly 1/2 second minus 2 clock periods and use that as a delay between setting and clearing an output port pin, then goto the start again. That makes the entire period exactly 1 second subject to the crystal tolerance and drift:
Remember though the timing is still subject to the crystal tolerance and drift. If you use the internal RC oscillator then the timing will be subject to that tolerance and drift which is even worse.
Here is sample code to generate a one half second (minus 2 instruction times) delay using the internal 4MHz oscillator or an external 4MHz crystal:
Code:
Delay_OneHalfSecondMinus2InstructionTimes
movlw .83
movwf d1
movlw .138
movwf d2
movlw .3
movwf d3
Loop_499998us
decfsz d1,f ;dec reg d1 and skip next instr if zero, place result in d1
goto Loop_499998us
decfsz d2,f ;dec reg d2 and skip next instr if zero, place result in d2
goto Loop_499998us
decfsz d3,f ;dec reg d3 and skip next instr if zero, place result in d3
goto Loop_499998us
goto Goto_499998us
Goto_499998us
return
Note the above code does not generate a perfect 50 percent duty cycle either, if you need that then we would have to use this instead:
and the one half second minus 3 instructions times delay is the same as the delay code above except change the line:
'goto Goto_499998us'
to:
'nop'
Code:
Delay_OneHalfSecondMinus3InstructionTimes
movlw .83
movwf d1
movlw .138
movwf d2
movlw .3
movwf d3
Loop_499997us
decfsz d1,f ;dec reg d1 and skip next instr if zero, place result in d1
goto Loop_499997us
decfsz d2,f ;dec reg d2 and skip next instr if zero, place result in d2
goto Loop_499997us
decfsz d3,f ;dec reg d3 and skip next instr if zero, place result in d3
goto Loop_499997us
nop
return
I have a code in which all three timers of PIC 16F887 are being used for some or the other functions.
My objective is to clear the counter on LCD display after every 1 second. When I try to clear one of the timers and use them for 1 second, I am not getting the desired result.
It is actually interfering the whole operation. The three timers in that code are used in the Interrupt Service routine of the program.
Hence I want to know if there is any way I can keep resetting the counter after every one second.
Also when I tried using the delay loop of 1 second it did not work.
Basically I want something similar to timer that will keep running for one second in the background and help me reset the counter after every one second.
Chances are you're using more timers than you really need. For example, I use a single timer for a 100-usec interrupt interval on a 16F1827 project. It's running with a 32-MHz clock so there are plenty of instruction cycles (800 cycles) between interrupts. Every 100-usec interrupt interval I sample and decode an IR decoder signal and I setup the PWM duty cycle for the next 100-usec PWM period (used for display brightness control). Every 10th interrupt (1-msec) I refresh the 4-digit 7-segment display. Every 200th interrupt (20-msecs) I sample and debounce the push-button switches. One timer interrupt, the TMR2 PWM interrupt, is doing everything with a modest 6% to 19% ISR overhead...