Timer vs timer3

hugoxp1

Member
Hi,
I'm from Portugal and since i discover Picaxe chips my life never been the same :)
this is my first post because since last october I have read the manuals and forum posts, but now i have these questions and i can't find a answer.

well, my questions are:

a) timer and timer 3 are both a background variables?
b) why use timer3 instead timer?

honestly can not understand what the advantages of timer3, since we have no way of getting to zero or detect overflow

can you give me an example how to use timer3 instead timer?

thank you
 

hippy

Ex-Staff (retired)
Welcome to the PICAXE forum.

It is not really a case of 'why use timer3 instead of timer', it is really a case of providing options and alternatives which may be most appropriate or useful for particular programs.

As you note, 'timer3' is in some ways inferior to 'timer', but where timer3 does the job the programmer requires then they can choose to use that.

The 'timer3' variable can be reset to zero ( 'Let timer3=0' ) and overflow can be detected by checking for when its value increases from 65535 and wraps back to zero. The timer can be stopped and started using TMR3SETUP.

One use of 'timer3' could be to test how long it took for a person to push a button after a LED was turned on. Stop timer3 with TMR3SETUP, clear timer3, start the timer with TMR3SETUP, turn on the LED wait for button push, and the time taken will be in the timer3 variable.

You could also use timer3 in a program to track elapsed time in the background. Having started it running you could check its value to see if an hour or so had elapsed no matter what else the program was doing.

All that could be achieved with 'timer' so it's really down to the programmer deciding which to use.
 

BeanieBots

Moderator
Choosing an appropriate timer to use can be quite a task.
Many of the time critical commands also require the use of the internal timers.
timer3 is a good option to use if your program also uses serial output (not the hardware serial) as the internal interrupts that clock it are not affected by serial commands (unless they are very long ones).

Have a play.
 

Flyer007

New Member
The 'timer3' variable can be reset to zero ( 'Let timer3=0' ) and overflow can be detected by checking for when its value increases from 65535 and wraps back to zero. The timer can be stopped and started using TMR3SETUP.

One use of 'timer3' could be to test how long it took for a person to push a button after a LED was turned on. Stop timer3 with TMR3SETUP, clear timer3, start the timer with TMR3SETUP, turn on the LED wait for button push, and the time taken will be in the timer3 variable.
Hi, I am trying to do just this. My trouble is understanding the math after to calculate the time down to 1/100's second.

I am using a 28x2 and using a very basic test
Code:
main:
tmr3setup %10110001
high b.7

turnoff:
if pinc.7=1 then timesup 
goto turnoff  

timesup:
tmr3setup %10110000
low b.7
b1= timer3
pause 10000
timer3=0
goto main
When my serial enabled 7-segment LED comes in tomorrow I would like to write out the elapsed time in 00.00 seconds (10s,1s,1/10ths,1/100ths)

Thanks for such a great forum. I have learned so much in my short time here. But the tmr3 is kicking my butt.
 

Chavaquiah

Senior Member
My trouble is understanding the math after to calculate the time down to 1/100's second.
Unless you increase the 28X2's frequency, I don't think you can get a resolution better than 3.2 hundredths of a second with timer3.

At 8MHz, using a 1:1 prescaler, the timer variable will increment every 65536 x 0.5µs = 32.768ms.

If you're not using servo or serial commands, the regular timer (see SETTIMER) might be a better option.
 

hippy

Ex-Staff (retired)
Chavaquiah is correct. The 'timer3' variables increment every 32.768ms with pre-scaler 1:1 so the best resolution you can measure to is about 3 hundredths of a second. With 'timer3' enabled for one second the 'timer3' value will be around 31.

If you want higher resolution timing you will have to deal with the internal SFR registers of the timers themselves. One example for doing this is -

http://www.picaxeforum.co.uk/showthread.php?t=14517
 

Flyer007

New Member
Chavaquiah is correct. The 'timer3' variables increment every 32.768ms with pre-scaler 1:1 so the best resolution you can measure to is about 3 hundredths of a second. With 'timer3' enabled for one second the 'timer3' value will be around 31.

If you want higher resolution timing you will have to deal with the internal SFR registers of the timers themselves. One example for doing this is -

http://www.picaxeforum.co.uk/showthread.php?t=14517
I have read through your code and am looking to test it. Using a 28x2 in a AXE020 should I connect the button directly to PIN6 (SERIN) on the chip? Since there is no pads on board that match to SERIN and SEROUT


Thanks,
Ben
 

hippy

Ex-Staff (retired)
Nearly every PICmicro has a different hardware structure so when dealing with SFR and external interfacing it's rarely a case of simply transposing the pinout for another and using the same code.

For the 28X2 the PWM routed through the button should go to T1OSO/T13CKI, pin C.0, leg 11 which will need a 1K-10K pull-down. The SFR addresses and SFR bit assignments may also have to be adjusted. Timer 3 could be used in the same way with additional SFR configuration.

What would probably be easier is to use the TMR3SETUP command to set timer 3 running, then just peek the TMR3:TMR3L registers and use a similar algorithm to determine elapsed time.
 

womai

Senior Member
Hippy,

one possible issue with peeking these two registers is that you can get completely wrong results if the LSB overflows between the two peeks. E.g. let's assume the counter value changes from 0x00ff to 0x0100:

peek TMR3L, b0 ' counter is 0x00ff, so b0 is 0xff
peek TMR3, b1 ' counter incremented to 0x100 in the mean time, so b1 is 0x01

Total result in w0 will then be 0x01ff instead of the correct 0x00ff or 0x0100. Similar effect if you read the MSB first and the LSB after that.

Depending on how the Picaxe interpreter is implemented, the solution could be to peek a word variable (of course that is only possible if TMR3 and TMR3L are at adjacent addresses, and it only works if the Picaxe isn't executing a WORD peek a s two subsequent byte peeks):

peek TMR3L, WORD w0

Wolfgang
 

BeanieBots

Moderator
This is a classic problem when reading any form of multibyte counter.
The only solution is to do multiple reads and test for a change. If there is a change, then read again.

The PICAXE word function for peek is two seperate reads so it does not solve that problem.

Get MSB
Get LSB
Get MSB again, if it's changed, start again.

The problem can also manifest with hardware counters that are read in with a single port read.
A 'ripple' counter is exactly that. The bits ripple along when one bit carries over to the next. If you are unfortunate enough to read it at the exact moment it changes, you can get a very wrong value. The only solution is to a synchronous counter and read the latched result.
 
Last edited:

MartinM57

Moderator
In AVR-land, reading 16 bit timer values is made easy by the AVR having a temporary 8-bit register that is internally used to assist writing and reading. From a typical AVR datasheet (with some editing):
The TCNTn,...are 16-bit registers that can be accessed by the AVR CPU via the 8-bit data bus. The 16-bit register must be byte accessed using two read or write operations. Each 16-bit timer has a single 8-bit register for temporary storing of the high byte of the 16-bit access. ...

Accessing the low byte triggers the 16-bit read or write operation. When the low byte of a 16-bit register is written by the CPU, the high byte stored in the temporary register, and the low byte written are both copied into the 16-bit register in the same clock cycle. When the low byte of a 16-bit register is read by the CPU, the high byte of the 16-bit register is copied into the temporary register in the same clock cycle as the low byte is read.
...
To do a 16-bit write, the high byte must be written before the low byte. For a 16-bit read, the low byte must be read before the high byte
..or in simple terms, read the low byte first, then the high byte and the results will be a guaranteed atomic read of the 16 bit value.

I'd have thought a raw PIC must have something similar as it's a fairly fundamental problem otherwise?
 
Last edited:

hippy

Ex-Staff (retired)
Most times the 'read and check if changed' trick is used and this even applies to high level languages such as determining the date and time in VB where you can get problems at the roll-over through midnight ...

Function DateAndTime$()
Do
d$ = Date$
t$ = Time$
Loop While d$ <> Date$
DateAndTime$ = d$ + " " + t$
End Function

Latest PICmicro ( including 28X2 ) do have the ability to take the 16-bit counts as an atomic entity even when reading it as two bytes.
 

Flyer007

New Member
Thanks for the help guys. I have concluded that the resolution will be close enough with built in timer3 so that I can use simple code. Right now this is running on a slower 28x2 (since using the AXE020 board) I will need to adjust the dividers when I clock it correctly.

Code:
 #picaxe 28x2

main:
high b.7
tmr3setup %10000001 'timer3 on, 1:1

Do
if pinc.7 =1 then goto shutoff
Loop

Shutoff:
tmr3setup %10000000 'disable timer
low b.7 'turn off led
w0= timer3/31 'get int of time
'We need to convert time into single numbers for serial LED
if w0>10 then 
w1= w0/10 
w2 = w0 % 10 
else 
w1 = 0 
w2=w0
end if
w3= timer3 % 31
if w3>10 then 
w4= w3/10 
w5 = w3 % 10 
else 
w4 = 0 
w5=w3
end if

SerTxd( #w1,#w2,".",#w4,#w5, CR, LF ) 'Send out the numbers. Will convert to 7 segment serial LED string later
 
Top