Hi, I have a timing problem on my coding on PIC16F887. (Datasheet for reference:http://www.kynix.com/uploadfiles/pdf8798/PIC16F887-I2fPT_95093.pdf (http://www.kynix.com/uploadfiles/pdf8798/PIC16F887-I2fPT_95093.pdf))My code want to have exact 3 second for testing and 4 second for delay. But at the end come out with the problem that the timing ain't accurate. Can anyone point out my mistake? Thank you very much. Below is my coding: 
; Description:                                                                                                                          ; 
; -SW simulates door switch, and should allow 3s delay for disarming before triggering the alarm.                                       ; 
; -Double click SW simulates the "disarm" switch that allows the legitimate user to avoid the alarm.                                    ; 
; -Triple click SW simulate the "arm" switch that starts the armed state after 4s.                                                      ; 
; -LEDs show the present state of the system (use separate LED for every state if possible)                                             ; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
#include "prologue.inc" 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
; Declaring Variable used 
     cblock     0x20 
Value                                    ; Assign an address 0x20 to label Value 
Read                                     ; Assign an address 0x21 to label Read 
Value1                                   ; Assign an address 0x22 to label Value1 
Read1                                    ; Assign an address 0x23 to label Read1 
Delay1                                   ; Assign an address 0x24 to label Delay1 
Delay2                                   ; Assign an address 0x25 to label Delay2 
Delay3                                   ; Assign an address 0x26 to label Delay3 
Counter                                  ; Assign an address 0x27 to label Counter 
Direction 
LookingFor 
Time 
Test 
SwitchPressed 
LastStableState 
Memory 
Delay 
Mem 
     endc 
  
  
Start: 
     bsf       STATUS,RP0                ; select Register Bank 1 
     clrf      TRISD                     ; Make PortD all output 
     movlw     0x01                      ; Bit one to work register 
     movlw     0xFF                      ; b'11111111' 
     movwf     TRISA                     ; Make PortA all input 
     movwf     TRISB                     ; Make RBO pin input (switch) 
     movlw     b'10000010'               ; PortB pull up is disable, Interrupt on rising edge of INT pin, Internal instruction cycle clock (FOSC/4) 
     movwf     OPTION_REG                ; Timer0 increment from internal clock with a prescale of 1:16 
     bsf       STATUS,RP1                ; select Register Bank 3 
     movlw     0x00                      ; move b'00000000' to work register 
     movwf     ANSELH                    ; PortB pins are digitial (important as RB0 is switch) 
     bcf       STATUS,RP0                ; select Register Bank 2 
     bcf       STATUS,RP1                ; select Register Bank 0 
     clrf      PORTD                     ; clear value in PORTD 
     clrf      Counter                   ; clear value in Counter 
     movlw     1 
     movwf     LastStableState 
  
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
MainLoop: 
     clrf      Memory 
     btfsc     PORTB,0 
     goto      MainLoop 
     movlw     b'10000000' 
     movwf     PORTD 
     call      DelayThreeSecond 
     call      PressTwo 
     call      PressThree  
     goto      MainLoop 
      
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;    
; Function Delays for Dots and Pause between the dash and dots 
DelayThreeSecond: 
     clrf      Time 
WaitThreeSecond 
     clrf      Mem                       ; clear value in Mem register 
OneSecondWait: 
     clrf      TMR0                      ; clear Timer0 
LoopTMR0: 
     call      CheckButton 
     call      NumberPress 
     movf      TMR0,w                    ; move value in TMR0 register to work register 
     xorlw     .250                      ; wait for 4ms (250x16us) 
     btfss     STATUS,Z                  ; check whether zero present in STATUS 
     goto      LoopTMR0                  ; loop back to LoopTMR0 
     incf      Mem,f                     ; increase the value of Mem register by 1 and store in counter register 
     movlw     .250                      ; wait for 1s (250x4ms) 
     xorwf     Mem,w                     ; move value in Mem register to work register 
     btfss     STATUS,Z                  ; check whether zero present in STATUS 
     goto      OneSecondWait             ; loop back to OneSecondWait 
     incf      Time,f                    ; increase the value of Time register by 1 and store in counter register 
     movlw     .3                        ; wait for 3s (3x1s) 
     xorwf     Time,w                    ; move value in Time register to work register 
     btfss     STATUS,Z                  ; check whether zero present in STATUS 
     goto      WaitThreeSecond           ; loop back to WaitThreeSecond 
     return                              ; return back to the next instruction after function call 
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
; Function Delays for Button Check 
CheckButton: 
     btfsc      LastStableState,0 
     goto       ButtonNotPress 
ButtonPress: 
     clrw 
     btfss     PORTB,0             ; test if the switch is press 
     incf      Counter,w           ; if switch press, increase the counter 
     movwf     Counter             ; store either the 0 or incremented value 
     goto      EndDebounce 
ButtonNotPress: 
     clrw 
     btfsc     PORTB,0 
     incf      Counter,w 
     movwf     Counter 
     goto      EndDebounce 
EndDebounce: 
     movf      Counter,w           ; have we seen 5 in a row? 
     xorlw     5 
     btfss     STATUS,Z    
     goto      Delay1mS 
     comf      LastStableState,f   ; after 5 straight, reverse the direction 
     clrf      Counter 
     btfss     LastStableState,0   ; Was it a key-down press? 
     goto      Delay1mS            ; no: take no action 
     bsf       SwitchPressed,0 
  
Delay1mS: 
     movlw     .71                 ; delay ~1000uS 
     movwf     Delay 
     decfsz    Delay,f             ; this loop does 215 cycles 
     goto      $-1          
     decfsz    Delay,f             ; This loop does 786 cycles 
     goto      $-1 
     btfss     LastStableState,0   ; Was it a key-down press? 
     return 
     goto      CheckButton 
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
; Function Delays for Number Button Press 
NumberPress: 
     btfss     SwitchPressed,0 
     return 
     incf      Memory 
     clrf      SwitchPressed 
     return 
     return 
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
; Function Delays for Number Button Press 2 times 
PressTwo: 
     movlw     .3                        ; wait for 1s (250x4ms) 
     xorwf     Memory,w                     ; move value in Mem register to work register 
     btfss     STATUS,Z                  ; check whether zero present in STATUS 
     return 
     movlw     b'00000000' 
     movwf     PORTD 
     return 
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
; Function Delays for Number Button Press 3 times 
PressThree: 
     movlw     .4                        ; wait for 1s (250x4ms) 
     xorwf     Memory,w                     ; move value in Mem register to work register 
     btfss     STATUS,Z                  ; check whether zero present in STATUS 
     return 
     movlw     b'00000000' 
     movwf     PORTD 
     call      DelayFourSecond 
     movlw     b'01000000' 
     movwf     PORTD 
     return 
  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 
; Function Delays for 4 Second 
DelayFourSecond: 
     clrf      Time 
WaitFourSecond 
     clrf      Mem                       ; clear value in Mem register 
OneSecondDelay: 
     clrf      TMR0                      ; clear Timer0 
WaitTMR0: 
     movf      TMR0,w                    ; move value in TMR0 register to work register 
     xorlw     .250                      ; wait for 4ms (250x16us) 
     btfss     STATUS,Z                  ; check whether zero present in STATUS 
     goto      WaitTMR0                  ; loop back to LoopTMR0 
     incf      Mem,f                     ; increase the value of Mem register by 1 and store in counter register 
     movlw     .250                      ; wait for 1s (250x4ms) 
     xorwf     Mem,w                     ; move value in Mem register to work register 
     btfss     STATUS,Z                  ; check whether zero present in STATUS 
     goto      OneSecondDelay             ; loop back to OneSecondWait 
     incf      Time,f                    ; increase the value of Time register by 1 and store in counter register 
     movlw     .4                        ; wait for 4s (4x1s) 
     xorwf     Time,w                    ; move value in Time register to work register 
     btfss     STATUS,Z                  ; check whether zero present in STATUS 
     goto      WaitFourSecond           ; loop back to WaitThreeSecond 
     return                              ; return back to the next instruction after function call 
end 
			
			
			
				What does it exactly mean not accurate? You calculated for example 1 seconds but when you measure it is always 1,2 seconds? Or always less?
I think the problem is this:
     movf      TMR0,w                    ; move value in TMR0 register to work register
     xorlw     .250                      ; wait for 4ms (250x16us)
     btfss     STATUS,Z                  ; check whether zero present in STATUS
     goto      LoopTMR0                  ; loop back to LoopTMR0
     incf      Mem,f                     ; increase the value of Mem register by 1 and store in counter register
     movlw     .250                      ; wait for 1s (250x4ms)
     xorwf     Mem,w                     ; move value in Mem register to work register
     btfss     STATUS,Z                  ; check whether zero present in STATUS
     goto      OneSecondWait             ; loop back to OneSecondWait 
You read the timer value, then you do some instructions. So you wait not only 4ms but 4ms + time of some instructions. You need to compensate the run time of your own code. Or use interrupts instead of synchronous blocking loops. Use C instead of asm, because in C you will find much more examples and help, also this microcontroller is big enough to be programmed quite reasonable in C. Also interrupthandling becomes much more easier in C if the compiler gives support for it (you do not need to save the context by hand or so)