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
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 = 161 = 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:
See also:
file: /Techref/microchip/pulsecountsd.htm, 5KB, , updated: 2009/6/3 15:06, local time: 2015/1/28 06:23,

©2015 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? <A HREF="http://www.piclist.com/techref/microchip/pulsecountsd.htm"> PIC Microcontoller IO Method  Pulse Counter</A> 
Did you find what you needed? 
PICList 2015 contributors:
o List host: MIT, Site host massmind.org, Top posters @20150128 RussellMc, alan.b.pearce, Dwayne Reid, Isaac Marino Bavaresco, Neil, IVP, John J. McDonough, Justin Richards, David C Brown, William \Chops\ Westfield, * Page Editors: James Newton, David Cary, and YOU! * Roman Black of Black Robotics donates from sales of Linistep stepper controller kits. * Ashley Roll of Digital Nemesis donates from sales of RCL1 RS232 to TTL converters. * Monthly Subscribers: Gregg Rew. ongoing support is MOST appreciated! * Contributors: Richard Seriani, Sr. 
Welcome to www.piclist.com! 
.