PDA

View Full Version : "Extending" timer1



chips123
- 19th October 2009, 02:09
Greetings all, this forum has been a great source of info, so thanks!

I am doing the speed, miles thing as shown in the following code. This works great until I slow to around 9 mph, then the timer overflows. If I test for an overflow, I can either set the speed to 0 or I can add 524 ms to the time and assume one timer overflow. That now works great down to ~4 mph. Below that, another overflow happens and my time is once again inaccurate. 16f676 running at 4MHz. In the code below, I have the first overflow commented out (PIR1.0) . Any suggestions on keeping track of these overflows? Thanks, Scott



define LCD_DREG PORTC
define LCD_DBIT 0
define LCD_RSREG PORTC
define LCD_RSBIT 5
define LCD_EREG PORTC
Define LCD_EBIT 4
define LCD_BITS 4

define LCD_LINES 2
Define LCD_COMMANDUS 2000
Define LCD_DATAUS 50

Define OSCCAL_1K 1

CMCON = 7 'Port A to digital
ANSEL = 0

TRISA = %00001100
TRISC = %00000000

OPTION_REG = %01000000 'rising edge interrupt
PIE1 = %00000000 'enable tmr1 overflow int w/ bit0
PIR1 = %00000000 'reset per interrupt flags
INTCON = %10010000 'global enable...
T1CON = %00000000 'timer1 reset

eeprom 0,[0,0] 'mile count storage - low byte first
eeprom 2,[0,0] 'pulse count storage

pulses var word 'timer register value 8uS per pulse
pulses = 0
w var word 'miles value
w = 0
x var word 'pulse count value
x = 0
y var word 'mS value
y = 0
z var word 'mph value
z = 0
D var byte
D = 0

Pause 500 'wait for LCD to startup

on interrupt goto myint
intcon = $90

start: Lcdout $fe, 1 'clear LCD
lcdout $fe, $80
lcdout "IntSPEED"
LCDOUT $fe, $C0
LCDOUT "Ver 1.0 "

pause 2000

read 0,w.byte0 'read stored mile value
read 1,w.byte1
read 2,x.byte0 'read stored pulse count
read 3,x.byte1

T1CON = %00110001 'start timer
TMR1L = 0
TMR1H = 0

loop: Lcdout $fe, 1
lcdout $fe, $80
lcdout #y," ",#z
LCDOUT $fe, $C0
lcdout #x," ",#w

for D = 1 to 100
pause 1
next D

Goto loop 'do it forever


Disable
myint: pulses.byte0 = TMR1L 'value of timer to pulses variable
pulses.Byte1 = TMR1H
TMR1L = 0 'start timer over
TMR1H = 0
'.001 = 125 * .000008
y = pulses / 125 'convert X 8uS pulses to mS
'if PIR1.0 = 1 then 'slow speed issues
' y = y + 525 'timer overflow
' PIR1.0 = 0 '~9 mph
' endif
z = 4900 / y 'convert ms to mph
if y = 0 then z = 0 'eliminate 65535 speed at 0mS
if PIR1.0 = 1 then 'timer overflow
z = 0
PIR1.0 = 0
endif
x = x + 1 'increment pulse count
write 2,x.byte0
write 3,x.byte1
if x = 733 then '733 revs per mile at 27.5 dia wheel
w = w + 1 'increment odometer
write 0,w.byte0
write 1,w.byte1
x = 0 'reset pulse counter
endif

intcon.1 = 0
resume
enable

end

aratti
- 19th October 2009, 08:39
Any suggestions on keeping track of these overflows?

Use a variable that you will increment by 1 at each timer overflow. When needed the variable will tell you how many overflows occured during your timing.



write 0,w.byte0
write 1,w.byte1


Remember that EEPROM has a life cycle of 10^6 write/erase cycles

Al.

mehmetOzdemir
- 19th October 2009, 10:30
hi aratti ;




Remember that EEPROM has a life cycle of 10^6 write/erase cycles



it is not about this thread.


do you have any idea , what will happen after 10^6 write/erase cycles.

aratti
- 19th October 2009, 11:03
do you have any idea , what will happen after 10^6 write/erase cycles.

Very likely they will loose reliability.

Read this interesting document @: http://ww1.microchip.com/downloads/en/AppNotes/00537.pdf

Al.

chips123
- 19th October 2009, 13:12
Aratti,
I think I understand the concept, but where would I put the variable increment in my code example? In the main loop, or something in the interrupt routine? That is basically what I was doing with the y=y+545. There I was only able to keep track of one overflow. In my interrupt, I am actually working with the previous timer value, not the current running timer value.

Thanks for the reminder on the EEPROM thing.
Scott

Jumper
- 19th October 2009, 13:32
If you look at the microchip EE-prom lifetime test they have compared different brands.. some better and some worse. I bet there is some advertising involved in the numbers but some brands only guarantee 100k write cycles. 100k or a million makes a difference.

aratti
- 19th October 2009, 15:27
but where would I put the variable increment in my code example?

chips123

Naturally in your interupt routine. Let assume you have a variable Tmr1Z (declared as Word) and you increment TMR1Z by 1 at each overflow then TMR1L & TMR1H and TMR1Z will give you a 32 bits count from which you could pullout a lot of information.

Also y = y + 525 could be used but since y will overflow itself after 124 timer1 overflow is not very helpfull.


100k or a million makes a difference.

Jumper

One is ten times the other! 100K makes life even more difficult.

For pic 16F676 this is what datasheet report:



- 100,000 write FLASH endurance
- 1,000,000 write EEPROM endurance
- FLASH/Data EEPROM Retention: > 40 years


Al.

chips123
- 19th October 2009, 15:54
I thought about this some more and thought that I came to the conclusion that I should do it in the main loop. When I used the y=y+525 in the interrupt routine, it only worked for the first timer overflow. Since the interrupt only cycles through once and the timer continues to run even if an interrupt has not happened, I figured I would need to keep checking for the overflow in my main loop. Let me know what you think of this. I wil need to try it tonight. Thanks.

aratti
- 19th October 2009, 16:16
I had the impression it was an INTERRUPT ON OVERFLOW routine.

Why don't you use Darrel Taylor instant interrupt, it is easy to use and works very well indeed!

Visit Darrel site @ http://darreltaylor.com/DT_INTS-14/intro.html

Al.

chips123
- 20th October 2009, 01:23
I put the new overflow checking inside the little delay loop (delay value was shortened) of the main loop and the results seem right. I need to verify w/ scope. I have been meaning to check out the Darrel Taylor interrupt greatness. Until the next stumbling block. Thanks,Scott