PDA

View Full Version : TMR1 counter debounce?



jderson
- 19th March 2008, 21:27
My 16F689 TMR1 counter is counting too well! How does one debounce this? My code:

TRISC = %00000000
TRISA = %100100
TRISB = %0000

@ DEVICE pic16f689,wdt_off

HIGH PORTB.4

Define LCD_DREG PORTC 'Set LCD data port
DEFINE LCD_DBIT 0 'Set LCD starting data bit
DEFINE LCD_RSREG PORTC 'Set LCD register select port
DEFINE LCD_RSBIT 4 'Set LCD register select bit
DEFINE LCD_EREG PORTC 'Set LCD enable port
DEFINE LCD_EBIT 5 'Set LCD enable bit
DEFINE LCD_BITS 4 'Set LCD bus size
DEFINE LCD_LINES 2 'Set LCD number of lines

OPTION_REG = %00111000
ANSEL = 0
CM1CON0 = %00000000
LCDOUT $fe,1

COUNT1 Var Word
COUNT1 = 0
TMR1H = 0
TMR1L = 0

'Set TMR1 to increment on rising edge of T1CKI pin, no prescaler, no sync to internal clock, TMR 1 is on.
T1CON = %00000111

Loop:
Count1.highbyte = TMR1H 'Get high byte of counter
Count1.Lowbyte = TMR1L 'Get low byte of counter


'Make sure that the counter did not roll over between reads of the high and low byte.

Temp var TMR1H 'Get highbyte again.
If Temp - Count1.HighByte <> 0 then 'The two values differs so we read it again.
Count1.HighByte = TMR1H
Count1.LowByte = TMR1L
ENDIF

Lcdout $fe,1
LCDOUT DEC COUNT1
PAUSE 100

Goto Loop

Any help would be appreciated.

JD123
- 19th March 2008, 22:20
What's shown on the LCD when it runs (DEC count1)?

paul borgmeier
- 20th March 2008, 03:55
>> Temp var TMR1H

possibly part of the problem ... this gets redeclared each time through the "loop". You might want to move it up above where your other declaration resides.

paul borgmeier
- 20th March 2008, 13:12
>>My 16F689 TMR1 counter is counting too well

After sleeping on your question, it sounds like you need a hardware debounce filter, possibly like

http://www.elexp.com/t_bounc.htm

I do not know how to add one in software when using the TMR1 as a counter. You could switch to another software means of counting all together (e.g., Interrupt on change of one of the port pins, etc) where adding software debounce would be a piece of cake.

falingtrea
- 20th March 2008, 13:47
If he is counting edges for some type of signal, a series R - shunt C filter may be better than the debounce filter. Just pick the 1/RC time constant to be higher than the max frequency of the signal you are trying to count, the nyquist freq (f*2) being a good starting point.

jderson
- 20th March 2008, 14:56
Thanks to every one for your help. Sorry for the delay in responding, our internet connection was down for 12 hours. I am trying to count the number of switch closures of a very fast reed switch. TMR1 is counting edges on T1CKI, just as it's supposed to. Ultimately,this switch will wake the program from SLEEP, and resume counting. I haven't as yet quite figured out how to use DT's Instant Interrupts to do this, but in doing so, maybe this will help with the "debounce" problem.

For now, I may use Paul's idea of just counting the pin, or try using falingtrea's RC filter.

Thanks again.

Steve_88
- 20th March 2008, 20:19
I added debouncing for a switch to >> timer input of a F876 back in the day.

I tried using a simple R/C network but found that the slow rise time of the signal as it was charging the capacitor back up violated the maximum rise time for the pic I/O.

I ended up using the R/C filter but fed it into a schmidtt trigger prior to sending it to the timer I/O.

This took care of things, I routinely test my devices by having another pic activate a relay thousands of times and test to see that the receiving pic counted correctly.

fwiw