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日 16:06, local time: 2025年9月1日 04:25,
40.74.122.252:LOG IN

©2025 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://techref.massmind.org/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?

Welcome to massmind.org!

Welcome to techref.massmind.org!

.

AltStyle によって変換されたページ (->オリジナル) /