Understanding TMR3

mortifyu

New Member
Hello Guru's,

Just trying to appreciate exactly how to use TMR3.

I wrote this basic CODE in order to understand the timer. It appears to function as I expected in the PE6 simulator. TIMER3 increments, C.1 and C.2 go HIGH accordingly. But when running on a LIVE 20X2 chip the TIMER3 value remains at ZERO and therefore C.1 and C.2 remain LOW.

I have a DSO connected to C.1 and C.2 set to trigger on the rising edge of C.1 ready to see the result.

From my CODE, I am expecting at the 250uS mark C.1 will go HIGH and then 250uS later C.2 will go HIGH. I realize there will be slight discrepancies due to program CODE execution time, however this unimportant.

Also I am expecting TIMER3 to increment +1 every 1uS (32MHz clock with 1:8 prescale set). Am I understanding the setup correctly here?


Code:
setfreq m32

tmr3setup   %00110011   ' timer3 on, 1:8 prescale

low c.1
low c.2

main:

sertxd("Timer3: ",#timer3,cr)

if timer3 > 250 then
    high c.1
endif

if timer3 > 500 then
    high c.2
endif

goto main

Also running this CODE at 64MHz with 'SETFREQ M64' in PE simulator, the Timer3 value remains at 1 and does not increment.

Where am I going wrong?




Thanks in advance.


Regards,
Mort.
 

AllyCat

Senior Member
Hi,
.... when running on a LIVE 20X2 chip the TIMER3 value remains at ZERO and therefore C.1 and C.2 remain LOW.
Code:
tmr3setup   %00110011   ' timer3 on, 1:8 prescale
Sorry, it's not a feature I've ever used (or can check), but remember that The Simulator is basically a Program Instruction Simulator, it's NOT a PIC{axe} Hardware Emulator, so I'm quite surprised if it Simulates correctly. However, the Command syntax says:

"Config is defined as (20X2, 28X2-5V, 28X2-3V, 40X2-3V, 40X2-5V):
Bit7 Must be set(1) ....
Bit1 Must be clear(0) "


But you appear to be setting Bit7 as clear (0) and Bit1 as set (1) ? And perhaps the issue with Setfreq M64 is something to do with the external resonator ?

Cheers, Alan.

 
Last edited:

mortifyu

New Member
Hi Alan,

Thank you. Hope you are well.

Lucky for me I have learnt to strap myself into my chair prior to reading your responses in case I was to fall out on the RARE occasions YOU say something like "Sorry, it's not a feature I've ever used".:giggle:

Mort = A Goose

You are correct, BIT 7 MUST be SET and BIT 1 MUST be clear. I was too hasty to copy & paste some example tmr3setup CODE without review and this has resolved the issue and now triggers the C.1 and C.2 lines HIGH with the HARDWARE, however in the simulator TIMER3 value remains only at 1.

So... Updated TEST CODE...

Code:
setfreq m64

tmr3setup   %10000001   ' timer3 on, 1:1 prescale

low c.1
low c.2

main:

if timer3 > 1 then
    high c.1
endif

if timer3 > 2 then
    high c.2
endif

goto main

This updated CODE does operate with a 20X2, but doesn't operate in the simulator.

Now to understand the timing...

SetFREQ M64 (64MHz internal oscillator) is possible with a 20X2. I am operating at 64MHz so as to minimize the extra delay time required to process the rest of the CODE ie IF statements & GOTO main.

The above CODE returns a space between C.1 and C.2 HIGH states of 4.234mS even with the prescale set to 1:1

From what I am understanding of the TMR3SETUP, this should be much much faster although I could be reading it wrong as two different things are stated.

1. "...the internal timer increment occurs every 0.5us. "

2. "The PICAXE word variable 'timer3' increments on every overflow of the internal timer, ie 65536 x the increment delay. So at 8MHz with 1:8 prescalar the timer3 value will increment every 262144us (262ms). "


So basing on the TIMER3 incrementing on every overflow...

((1/resonator speed) * 4) * 65536 = ((1/64) * 4) * 65536 = 4096uS

1000uS = 1mS, therefore the returned hardware result of 4234uS sounds about right factoring in the required program execution time (138uS).


For resolution purposes, what I am really wanting to work with is "the internal timer increment occurs every 0.5us" This would be REALLY nice.


Anyone...?





Regards,
Mort.
 

Flenser

Senior Member
Mort,

Your code works in the simulator if:
1) you comment out the cmd "setfreq"
2) you use any prescaler settings except for "1:1"

The timer3 simulation obviously is not working with the 1:1 prescaler and the setfreq cmd has some effect that I don't understand.
 

AllyCat

Senior Member
Hi,
For resolution purposes, what I am really wanting to work with is "the internal timer increment occurs every 0.5us" This would be REALLY nice.
Most of the PIC{axe} timing functions are derived from the "Master" clock oscillator, which is determined by the SETFREQ command. To "Keep It SimpleS" the PICaxe User Manual sometimes assumes the "Default" frequency for statements like that you've quoted above. The "Instruction Clock" (Execution time) which is used as a base for most timing functions, is usually 1/4 of the master clock, which makes 0.5us from the default X2 SERFREQ of 8 MHz.

Therefore, you could obtain that 0.5us period by using SETFREQ M8, or at M64 if you hadn't already set the pre-scaler to 8 . Unfortunately 8 is the largest divider value available. The reason that the "xxxxSETUP" flags are different in the various X2s is because they are usually sent directly to the "SFR" of the "base PIC" Hardware (T3CON in this case). If you REALLY wanted to run Timer3 at a slower frequency then the following might be possible, but I'm not recommending it:

Bit1 of T3CON is described as "1 = External clock input from Timer1 oscillator ... or 0 = Internal clock (FOSC/4)" , and as you've seen "should" be set to 0. The "Timer 1 oscillator" is not normally used by PICaxe (because Timer1 is driven from the internal Master clock) and is typically intended for use at lower frequencies such as a 32kHz "watch" crystal for accurate, low-power timing. But in principle it could be driven from elsewhere, such as a PWM output pin. Since it's not used by the PICaxe system, it might be possible to enable this "oscillator" (input) and connect it through (only) to Timer 3.

However, one "problem" is that the Timer1 oscillator is Leg2 on most M2 Picaxes (and the 20X), which is the "Programming" input. Therefore, as a minimum, you would need to use a DISCONNECT command (with the later necessary Hard Reset procedure) and arrange to physically switch a PWM output to this clock input pin. In practice, you might find that the PICaxe Operating System prevents this being done, but I believe that hippy did do it successfully, many years ago with an 8-pin PICaxe, possibly an 08M (not2).

Cheers, Alan.
 

mortifyu

New Member
Thanks Alan,

I may have to come up with a different approach to my dilemma.

Ultimately what I want to do is:

HIGH C.1 (only for 25mS)

with a pre-selectable delay time between C.1 and C.2. This delay may be as low as 1mS or as high as 250mS.

HIGH C.2 (only for 25mS)


Thus far my thoughts have been utilizing an elapsed timer knowing things could be out by perhaps a couple hundred uS, I could live with that.

However my failed attempt at using TMR3 as mentioned above is only leaving me with an absolute minimum of 4096uS or 4.096mS.

I very reluctantly may end up having to step away from PICAXE to accomplish this task.



Thanks for the input.

Regards,
Mort.
 

AllyCat

Senior Member
Hi,

That specification (alone) doesn't look too difficult, so are there other features that require the use of M64 and/or an X2 chip? Is this a "One Shot" operation, or part of a continuous "oscillation" cycle? If you can tolerate errors (or a variation) of "a couple of hundred us" then I would have thought that there might be several software / interrupt solutions possible.

Sometimes it can we worth "thinking outside the box", for example starting and timing the first pulse with a HIGH xx : PAUSEUS xx and then timing the "delay" with a PULSOUT xxx , followed by a PAUSEUS : LOW xx , etc.** A direct 250ms delay might always be an issue with M64, but a PICaxe program might be "intelligent" enough to switch the delay mode (e.g. hardware versus software), depending on the required delay period.

**EDIT: Ah, that could work with two pulses on the SAME pin, but not pulses on two different pins. :(

Cheers, Alan.
 
Last edited:

mortifyu

New Member
Hi Alan,

It is effectively a one shot operation where there is possibly up to 8 outputs to be sent HIGH with varying delays (1-250mS) between each output, but each output MUST only remain HIGH for 25mS (no longer and no shorter (with an inaccuracy of 100-200uS being acceptable. The more accurate the better though.))

(I think) I get what you are saying above.

In the meantime I have tried a different approach with reasonable success...

Code:
setfreq m64

low c.1
low c.2

settimer 65511     '100uS per TIMER increment (major tick that advances the TIMER variable at each overflow)
                   '@ 64MHz oscillator there is 4uS per minor tick, therefore 100uS/4uS = 25, therefore 65536 - 25 = 65511.


main:
if timer > 1 then
    high c.1
endif

if timer > 2 then
    high c.2
endif
goto main
The measured result from running this CODE has demonstrated the time between C.1 and C.2 going HIGH to be 124.00 uS.

I can take it a little further, but the chip doesn't seem to like it, and the scope is not triggering. The PICAXE also then requires a HARD RESET in order to reprogram it. Nonetheless I think I can work with this because ultimately I need to work in 1000uS or 1mS increments with a little bit (couple hundred uS) of inaccuracy being acceptable in this instance.

This method has proven to be 40x better than my attempt using TMR3.

Not that it matters with this functional testing, but I am actually using a 40X2. It's just that I currently have a 20X2 setup on the bench and am using it to work this issue out.



Thank you Alan. You are a MAJOR wealth to the PICAXE community at large.



Kind Regards,
Mort.
 

AllyCat

Senior Member
Hi,

A PULSOUT should be accurate to better than about 1%, or even less if using the CALIBFREQ option, or with an External Crystal oscillator (clock). The "problem" with PICaxe is that it has a significant "overhead" Execution time on every instruction. So for example, the gap between two pulses: PULSOUT xxx : PAUSEUS xxx : PULSOUT xxx will be longer than "expected" (by about two "overheads", which might be about 700 "PIC Instruction cycles" or 350us each at 8 MHz). A partial solution is to use a higher clock frequency, but it's also possible to predict (or measure) the overhead to quite good (but not perfect) accuracy and repeatability, and then correct the PAUSEUS parameters accordingly.

If you actually want to synchronise (the start or stop of) several pulses, then you could use the OUTPINSx instruction (if they're on the same port). Or a simple HIGH xxx : HIGH yyy should have a "stagger" (delay offset) of about 25us (at 64 MHz), but any intervening conditional instructions (e.g. IF... ENDIF) may add considerably to that. However, PICaxe does allow several "tricks" such as permitting for example HIGH b2 : TOGGLE b3 where b2, etc. can be set in advance as a port.pin number (including "don't care" ones, or perhaps that don't even exist) , and you can use TOGGLE if you might want the pin to go either HIGH or LOW.

Another possibility might be to use PWM outputs, which can be very accurate, perhaps with the output pins enabled and disabled "on the fly" by the program. Or perhaps use the feature that some PWM pins "share" a common oscillator/counter, which could synchronise several pulses. Note that I've edited my post #7.

Cheers, Alan.
 
Top