please dont rip this site

PIC Microcontoller IO Method

Pulse Counter

by Scott Dattalo


   cblock   0x20 ;or whatever your ram start is

     total_pulses          ; the number of pulses counted
     current_state         ; bit0 reflects the most recent sampled state
                           ; bit1reflects the most recent filtered state
                           ; bit2 indicates that the debounce filter is running
     steady_state_counter  ; keeps track of the number of consecutive steady
                           ; state samples

   endc


#define    IOPORT   PORTA
#define    IOBIT    0


   ;;--------------------------------------------------------------
   ;; pulse_counter - count pulses on an I/O pin
   ;;
   ;; This routine counts the number of occurances of high pulses
   ;; on the IOBIT of IOPORT (defined above).
   ;;
   ;;
   ;; Must be called at a constant rate and at least 4 times faster
   ;; than the narrowest pulse expected.
   ;; For example, if the narrowest pulse expected is 10 ms then
   ;; this routine should be called at least once every 2.5 ms. 1ms
   ;; would be a good interval.

pulse_counter:

; Define the number of consecutive samples required to measure either
;a high or a low:

#define SAMPLES_FOR_STEADY_STATE  4


    movlw  0                   ;Sample the input
    btfsc  IOPORT,IOBIT
     movlw 1

    xorwf  current_state,w     ;compare to the previous sample
    andlw  1                   ;Clear upper bits of current sample
    skpz                       ;If this sample is different than previous
     goto  detected_a_change   ; then handle below

  ;; no change in last two samples

  ;If we're not filtering, then we can return.
  ;If we are filtering, but the steady state counter hasn't
  ;terminated, then we can also return

    btfsc  current_state,2
     decfsz steady_state_counter,f
      return

  ; We sampled `SAMPLES_FOR_STEADY_STATE' consecutive samples

    bcf    current_state,2     ;We're no longer filtering

    rlf    current_state,w     ;Compare the current filtered state
    xorwf  current_state,w     ;with the previous filtered state
    andlw  2                   ;Just look at the differences
    xorwf  current_state,f     ;and save the current as the previous
    andlw  2                   ;again, look at the differences
    skpz                       ;If there are no differences
     btfss current_state,1     ;or the current filtered state is low
      return                   ;then we found a low pulse


  ; We found a high pulse. Count it!
    incf   pulse_counter,f

  ; This would be a good place to check the pulse counter...

    return

detected_a_change:
    xorwf  current_state,f     ;save this sample for next time

    movlw  SAMPLES_FOR_STEADY_STATE  ; Initialize the steady state counter
    movwf  steady_state_counter

    bsf    current_state,2     ; Set a flag so we know we're filtering

    return


This has not been tested...
  cblock

     sample    ; The most significant bit contains the most recently filtered
               ;state.  The other bits contain the last N samples, where N is
               ;the filter width. (and N must be less than 8).

     pulse_counter  ; each time a pulse is discovered, this is incremented


  endc


;--------------------------
; constants:
;

; Number of consecutive samples of the same state required to declare
;an input as filtered

#define STEADY_STATE_SAMPLES  4


; The FILTER_MASK is a constant with the least significant
;STEADY_STATE_SAMPLES bits set. e.g. if STEADY_STATE_SAMPLES is 4
;then the FILTER_MASK is (1<<4)-1 = 16-1 = 15 = 00001111b

#define FILTER_MASK           ( (1 << STEADY_STATE_SAMPLES) - 1)


count_pulses:
     clrc                       ;Copy the I/O pin state into the carry
     btfsc   IOPORT,IOBIT       ;First, it's assumed the io pin is low
      setc                      ;If it isn't then we set the carry bit
                                ;NOTE, if the I/O pin is either the most
                                ;or least significant bit, then a rlf
                                ;or rrf instruction accomplishes the
                                ;same thing in 2 fewer cycles.

   ; The next 4 instructions copy the new sample to the lsb and shifts
   ;the previous samples left one position. However, the msb (which
   ;contains the filtered state) is left unchanged.
   ; starting with sample == abcdefg and C=s (carry is equal to newest
   ;sample):

     rlf     sample,f           ; bcdefghs C=a
     rlf     sample,f           ; cdefghsa C=b
     rrf     sample,w           ; cdefghsa C=a (W contains bcdefghs)
     rrf     sample,f           ; acdefghs C=a

     andlw   FILTER_MASK        ;examine the last N consecutive samples
     skpnz                      ;If they're all zero
      bcf    sample,7           ; then the filtered state is low.

     xorlw   FILTER_MASK        ;But we're really interested in highs
                                ;If we complement all of the bits
                                ;and the result is zero, then that
                                ;means the last N samples were high.
     skpnz                      ;If any of the last N were low or if
      btfsc  sample,7           ; they're all high but the filter is
       return                   ;  already high, then we're done

   ;If we get here then a positive pulse has been detected

     incf   pulse_counter,f     ;count it
                                ;
     bsf     sample,7           ;Set the "filtered" flag

     return



Questions:


file: /Techref/microchip/pulsecount-sd.htm, 5KB, , updated: 2009/6/3 15:06, local time: 2024/11/9 20:29,
TOP NEW HELP FIND: 
3.148.104.191:LOG IN
©2024 PLEASE DON'T RIP! THIS SITE CLOSES OCT 28, 2024 SO LONG AND THANKS FOR ALL THE FISH!

 ©2024 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions?
Please DO link to this page! Digg it! / MAKE!

<A HREF="http://linistepper.com/techref/microchip/pulsecount-sd.htm"> PIC Microcontoller IO Method - Pulse Counter</A>

After you find an appropriate page, you are invited to your to this massmind site! (posts will be visible only to you before review) Just type a nice message (short messages are blocked as spam) in the box and press the Post button. (HTML welcomed, but not the <A tag: Instead, use the link box to link to another page. A tutorial is available Members can login to post directly, become page editors, and be credited for their posts.


Link? Put it here: 
if you want a response, please enter your email address: 
Attn spammers: All posts are reviewed before being made visible to anyone other than the poster.
Did you find what you needed?