Odd delay behaviour
Hi folks,
I have run into an odd ocurrence when using a calculated delay.
The following is a simple example:
With the code shown above, the LED on Pin 16 never turns on.
If I change the value upwards from the (10) it only comes on when the parameter = 77.
If I replace the calculated delay with a straight forward absolute delay, there is no problem at all.
Comment?
I'm using the Propstick.
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
I have run into an odd ocurrence when using a calculated delay.
The following is a simple example:
con _clkmode = xtal1 _clkfreq = 5_000_000 pub start dira[noparse][[/noparse]16]~~ uSdelay(10) ' 10uS delay outa[noparse][[/noparse]16]~~ repeat pub uSdelay(DelayuS) 'Delay for # of microseconds waitcnt(((clkfreq/1_000_000) * DelayuS) + cnt)
With the code shown above, the LED on Pin 16 never turns on.
If I change the value upwards from the (10) it only comes on when the parameter = 77.
If I replace the calculated delay with a straight forward absolute delay, there is no problem at all.
Comment?
I'm using the Propstick.
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
Comments
You clock your Prop with 5 MHz (PLL1X), which means that the most simple SPIN instruction needs around 80 mys (it needs around 5 us with 80 MHz)
So you have no chance to wait for less!
As you say 77 us does fine, you have exactly meassured, what the second part of WAITCOUNT (i.e. WITHOUT the division, which will take YEARS) takes.
When you want to say only 770 us works fine, then the division is added to the instruction time, which however is against common knowledge, as this is why you write ... + CNT rather than CNT+... to avoid this.
And the LED will OF COURSE shine, but only after 16*23 = 368 seconds. The young persons are sooo impatient these days ....
Post Edited (deSilva) : 8/23/2007 6:19:27 PM GMT
you are not setting right the clock to use. It should look like the following for maximum speed.
It uses the following code[noparse]:([/noparse]Clk = 80mHz)
which is supposed to be 10uS. (It eventually exits after 53 seconds!)
It sets the time of charging the capacitor, which really doesn't require much time at all.
When running the code, it didn't seem to exit this timer and thus I started to investigate.
I tried the uSdelay method, which just happened to be listed in the same Object, but it didn't work either.
That's when I asked the questions in this thread.
Unfortunately, I used a 5mHz example.
kenmac
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Perth, Western Australia
Time Zone = GMT + 8
as deSilva has explained your expression containing a division takes to much time. As the clockfreq is not changed at runtime you could use the result of division as constant.
Post Edited (Kaio) : 8/23/2007 12:35:31 PM GMT
sorry, but your calculation is wrong. Please be aware that clkfreq and _clkfreq have different meanings (p. 176 manual).
And the system counter wraps after 53 seconds at 80 MHz.
@kenmac
Without your multiply for µs the waitcnt uses 381 system clocks (p. 323 manual). This is approximately 5 µs. The multiply takes again 5 µs. So I think the smallest time could be 10 µs if you would use a constant as I mentioned before.
Alas, more reading to do. (Which I did. _clkfreq and clkfreq may be different values but in this trivial program I think they can be considered the same.)
So how fast does the counter wrap at 5 Mhz?
Post Edited (Fred Hawkins) : 8/23/2007 7:18:57 PM GMT
you are right, CLKFREQ can not be used as a constant. I know that the CLKFREQ can be changed during the runtime, but I was thinking if kenmac doesn't do that the result of division is constant.
@Fred
Regarding the counter wrap at 5 MHz I would say it must be 16 times, while the quotient of 80 / 5 equal 16. So it should be nearly 859 seconds. That's a long time if you want to see a LED blinking.
@kenmac
From the discussions before I end up of the following code.
Note: I haven't tested the code yet.
Thomas
When you expect to wait 10 us it will be around 30 us, when you say "50" it will be around "70"... You can compensate for it by subtracting a specific value (around 20, but maybe even 50) from your parameter. You have to calibrate it by e.g. toggling a pin and measuring the frequency. Note that pin-toggling takes time as well (10 us or more...)