Musings about timer 1

oracacle

Senior Member
Been thinking about projects and bits an pieces. With the work that hippy did with a 20x2 based timer a few years ago I thought about adapting it to a 28x2 instead. I ran into difficulties and then life took over.
However now I think I may have gotten closer to what I need, full control over the start and stop control of the timer, which can be either hardware or software, and sub millisecond timing. I hoping to be able to use this as a chronograph at some point.

Some work needed on the maths side of things, and the picaxe will be tied up while timing in this manner. hopefully I got the maths that I have done so far correct
I haven't gotten around to testing this yet, I don't know when I will. If you have the things, please feel free to do so.

Code:
#picaxe 28x2
setfreq em64
'generate PWM signal and pass through and gate to c.0
'second leg of and gate connected to b.7
'pokesfr $CD, %10000111  'poke t1con if needed to set correctly
'can poke preload values in into trm1l and tmr1h if needed
settimer count 65530
pwmout B.0, 1, 3   '8mhz pwm
do
loop while pinc.3 = 0  'start timing
high b.7    'set and gate to on

do
  b0 = flags
  if bit7 = 1 then
   inc b1
   flags = 0
  end if
loop while pinc.4 = 0  'end timing
low b.7    'set and gate to off
peeksfr $ce, b2   'get tmr1 LSB
peeksfr $cf, b3   'get tmr MSB
'now, do some maths.
'with preload over flow happens 0.000625ms
'at 8mhz overflow from 0 to 65535 will be 8.191875ms
'b1*(8.191*1000) will give whole ms - overflow issues
'@ 8mhz PWM a clock signal will last 0.000000125s
'each unit in the tmr1 registers = 0.125us - 0.000125ms
'will need to find the best way to do the maths here...
 

hippy

Technical Support
Staff member
You might have to explain exactly what maths it is you are wanting to do.

If it is to determine elapsed time as accurately as possible the best way IMO to do that is to keep separate word variables for nanoseconds, microseconds, milliseconds and upwards, have each sub-second word hold a 0-999 value.

So, assuming on every overflow the elapsed time from the last is 8.191875 ms, you just add the component parts of that to the appropriate words -
Code:
ns = ns + 875
us = us + 191
ms = ms + 8
You can handle overflow with -
Code:
us = ns / 1000 + us
ms = us / 1000 + ms
s  = ms / 1000 + s
m  = s  / 60   + m
h  = m  / 60   + h
d  = h  / 24   + d
Having done that one also needs to keep the values within their 0-999 or other constraints -
Code:
ns = ns // 1000
us = us // 1000
ms = ms // 1000
s  = s  // 60
m  = m  // 60
h  = h  // 24
To display the elapsed time to maximum resolution, all you need to do is display all the values with an appropriate number of digits by inserting leading zeroes.

The actual maths can be optimised, steps can be combined, depending on how the time data is being used.
 

oracacle

Senior Member
Add it will be used as a chronograph the time will be used to calculate speed, and maybe time to destination after the speed has been calculated. Think I may have an FPU here, or use another picaxe to do the maths
 

hippy

Technical Support
Staff member
Add it will be used as a chronograph the time will be used to calculate speed, and maybe time to destination after the speed has been calculated.
In that case it might be better to store time as a multi-bit binary number which would allow 32-bit or even larger maths to be done. You can still store time as component parts; just limit them to a more computer convenient 0-2047 (0-$FFF) than humanly convenient 0-999.

With the individual parts ( h:m:l here ) being 0-$FFF the larger nanosecond unit time is just those individual parts concatenated into a larger bit-sized value.

8191875 ns = $7CFF83 so ...
Code:
l = l & $FFF + $F83
m = m & $FFF + $7CF
Code:
m = l >> 12 + m
h = m >> 12 + h
Then it's just a matter of bit shifting those three entities into a 48-bit 'ns' value, for example -
Code:
    h       m       l
.------..------..------.
| hhhh || -mmm || -lll |
`------'`------'`------' 
.------..------..------.
| --hh || hhmm || mlll |
`------'`------'`------'
   w2      w1      w0
 
Top