Delay routine - programmable at run-time
Tony Leyland
Posts: 71
Hi all,
Does anybody have any ideas how I can implement a delay routine that is programmed while code is running and not
at assembly time? I've been trying this for sometime now and would like to competely avoid using interupts !
I use this method:-
The amount to delay is loaded into W and the DelayFactor is added as shown. The low nibble therefore has the amount to delay 1-9(say)
and the high nibble the scale factor 10us to 1S. In this was timings from 10us -> 90us in steps of 10, 100us -> 900us in steps of 100 etc..etc
In this example shown the delay is 20mS. The Delay routine knows which delay to jmp to according to the high nibble of w.
I'm having trouble "wasting" the required amount of cycles within the Delay routine itself - I use a different 3 level nested delay loop for
each DelayFactor (6 routines in total) - the ClockSpeed also needs to be included (I calculated everything on the PC and code the
required delay loop counters into lookup tables).
What do you think ? I'm I going about it all wrong !
Many thanks in advance.
Tony
Does anybody have any ideas how I can implement a delay routine that is programmed while code is running and not
at assembly time? I've been trying this for sometime now and would like to competely avoid using interupts !
I use this method:-
ClockSpeed EQU 50_000_000 ; Resonator or SX-Key speed DelayFactor10uS EQU 0 DelayFactor100uS EQU 1*16 DelayFactor1mS EQU 2*16 DelayFactor10mS EQU 3*16 DelayFactor100mS EQU 4*16 DelayFactor1S EQU 5*16 mov w,#2 + DelayFactor10mS call Delay
The amount to delay is loaded into W and the DelayFactor is added as shown. The low nibble therefore has the amount to delay 1-9(say)
and the high nibble the scale factor 10us to 1S. In this was timings from 10us -> 90us in steps of 10, 100us -> 900us in steps of 100 etc..etc
In this example shown the delay is 20mS. The Delay routine knows which delay to jmp to according to the high nibble of w.
I'm having trouble "wasting" the required amount of cycles within the Delay routine itself - I use a different 3 level nested delay loop for
each DelayFactor (6 routines in total) - the ClockSpeed also needs to be included (I calculated everything on the PC and code the
required delay loop counters into lookup tables).
What do you think ? I'm I going about it all wrong !
Many thanks in advance.
Tony
Comments
The problem with just making a 10uSec delay routine, then calling is a bunch of times is that it doesn't take into accout the time spent in the loop. So you end up having something like this.
Delay1: ' Jump here if not in any loop
' Waste time
Delay2: ' Jump here if in a single loop
' Waste time
Delay3: ' Jump here if in a double loop
' Waste time
Delay4: ' Jump here if in a triple loop
' Now delay for 9.??? useconds
RET
Then depending on how many embedded loops you have determines which label you call.
I hope that helps, or that it even makes sense.
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Check out· the "SX-Video Display Module"
www.sxvm.com
·
If I have program space, I put several different delay routines and call them as a sub. At SXlist.com there is a cool delay code generator.
You put it the clock speed, requested delay amount and it spits out the program.
thanks for this info - the delay code generator is really cool!
Here is the full link into sxlist.com for those who are interested:
techref.massmind.org/cgi-bin/delay.exe
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Greetings from Germany,
G
If you write yourself a small simple scheduler you can easily accomplish the same effect of delays without actually looping in a delay cycle. This means you can do other things while the "delay" is happening.
There is a simple method of doing this, invoking a sequential scheduler.
There is also a much more complex and more invasive (nothing comes for free) "pre-emptive" method which will actually hand the processor's cycles over to ever higher priorities as they occur. This is also known as a pre-emptive realtime operating system (RTOS).
I expect soon (when the contest results are out) to be posting both these approaches, and hopefully all will be able to benefit from either of·them.
Cheers,
Peter (pjv)
Why do you want to avoid interrupts?
Thanks, PeterM
I would use interupts for the timing (RTCC rollover), but the rollover is very likely to occur
while an ISR is processing the interupt from port B. I don't know how (or if I can) service an RTCC
rollover within an ISR ?
Thanks
Tony
Ah! You have come across the classic SX snafu - trying to handle interrupts from two different sources. It seems that you have already figured out that this is something that the SX just doesn't handle well. The CPU runs like a bat out of Hell, but has no ability to buffer interrupts. Hence, if you are servicing one interrupt source and another interrupt source triggers, well, that other interrupt is basically going to disappear.
Now, my next question is whether you really need to service the PortB via an interrupt or not. I find that people are always making use of interrupts to service bit I/O changes since the SX has this neat feature that generates interrupts on level changes. However, does your application truly need to service the bit change with the super tight response that an interrupt guarantees, or is there some wiggle room?
For example, I have code where I run the chip at 50 MHz and have an RTCC interrupt period of 200 clock cycles, which gives me an interrupt rate of 250,000 interrupts per second. That a really fast interrupt rate, and I find that it is often more than sufficient for handling on the bit level change handling I need. Often, a super stable time base (via RTCC generating interrupts) is more important than nanosecond accurate handling of bit I/O level changes. You can either piggy back I/O level checking in the interrupt for the RTCC, or you can just run a loop in your main foreground code.
I have no idea what your application is, but I just thought I'd toss this at you to see if it might apply to you.
hanks, PeterM
I agree with you whole heartedly!
In fact in my (hopefully soon to be revealed) pre-emptive RTOS, when running at 50MHz., the interrupt can be selected to occur as fast as every one microsecond, providing for a wonderfully responsive system.
Rarely do I need to use the change-on-rb feature. Polling at 1 uSec is generally plenty fast.
Cheers,
Peter (pjv)
From what I've been reading here it sounds like the Interupt features of PORT B are overrated and we should make use of
the RTCC, which will give extra benefits like being able to setup counters (for delay routines say) and as mentioned
in this thread polling the PORT B instead of using it's Interupt feature, plus other exciting possibilities as stated by other users.
I'll be recoding my application to use RTCC for my PORT B polling, I'll still continue with writing my 1 cycle accurate delay routine
that does not use interupts, as I'm fairly close to working out the extra maths - as I took a lot of time to work out the math for
the delay routine www site that was mentioned earlier in this thread ! If successful, I'll post the code for anyone else who might
be interested in using it.
Thanks
Tony
Bean.
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Check out· the "SX-Video Display Module"
www.sxvm.com
·