View previous topic :: View next topic |
Author |
Message |
pilar
Joined: 30 Jan 2008 Posts: 197
|
Delay routine without using a timer |
Posted: Thu Feb 13, 2014 11:30 am |
|
|
Hi,
I want to implement a routine delay but without using a timer ...
With this code I have a delay of about 500ms, but I would like to calculate exactly how much is precision with this delay including instruction for .. someone can tell me how to do this calculation..
Code: | #include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
#use delay(clock=20000000)
#define Led_ROJO PIN_D5
#define LEd_VERDE PIN_D6
#define ON output_high
#define OFF output_low
void xdelay(int32 x){
int32 i;
for (i=0; i<x; i++){
delay_cycles(250); // Retardo de 50useg
}
}
void main(){
while(true){
output_toggle(Led_ROJO);
xdelay(10000);
}
} |
|
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1329
|
|
Posted: Thu Feb 13, 2014 11:33 am |
|
|
why not use delay_ms() and delay_us()? |
|
![](templates/subSilver/images/spacer.gif) |
pilar
Joined: 30 Jan 2008 Posts: 197
|
|
Posted: Thu Feb 13, 2014 11:42 am |
|
|
I need to put a small delay within an interrupt and use any of these, have conflicts |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
![](templates/subSilver/images/spacer.gif) |
jeremiah
Joined: 20 Jul 2010 Posts: 1329
|
|
Posted: Thu Feb 13, 2014 12:23 pm |
|
|
Before I post the rest of this, I just want to note that using delays in interrupts is 99% of the time a bad idea and not needed. That said, you can also trick the compiler into making to copies of each delay routine. In this example, I made the isr version a wrapper function. If the extra overhead bothers you (not usually a lot...depends on the chip...2 instructions on PIC24 chips), you can make the top one for your main program instead and name it something like delay_ms_noisr() or something snazzy and use that in your main program instead.
Basically, delay_ms() and delay_us() always use the last #use delay() statements before they were called. So you can do two of those and wrap the top one in a function to force the compiler to use a different copy for that function versus all the rest of the calls.
Code: |
#include <18F4520.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP,NOBROWNOUT
//************ ISR Delays ********//
#use delay(clock=20000000)
#inline void delay_ms_isr(unsigned int16 ms){
delay_ms(ms);
}
//************ NON ISR Delays ********//
#use delay(clock=20000000)
#int_timer1
void timer1_isr(){
//! delay_ms(5000); //this call causes interrupts to be disabled
delay_ms_isr(5000); //this call does not
}
void main (void){
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
while(TRUE){
delay_ms(5000);
}
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
pilar
Joined: 30 Jan 2008 Posts: 197
|
|
Posted: Thu Feb 13, 2014 12:32 pm |
|
|
Thank you... |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9178 Location: Greensville,Ontario
|
|
Posted: Thu Feb 13, 2014 4:35 pm |
|
|
Having a 1/2second delay inside an ISR defeats the purpose of using interrupts! Any 'inline coded 'delay will keep the PIC 'twiddiling it's thumbs',do absolutely NOTHING until the 1/2 second is up.
Unless you're going to use timers with ISR you should rethink your program.
If you tell us WHY you need a 1/2 second delay(actually the overall concept of the program) we'll be able to point you in the right direction.
hth
jay |
|
![](templates/subSilver/images/spacer.gif) |
pilar
Joined: 30 Jan 2008 Posts: 197
|
|
Posted: Fri Feb 14, 2014 10:54 am |
|
|
Hi temtronic,
The 500ms, I think they were just to give an example of an amount of time, which is obviously out of place to use that amount of time in a service interruption |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19383
|
|
Posted: Sat Feb 15, 2014 2:07 am |
|
|
A couple of 'basic suggestions':
Program a hardware timer to trigger at the required interval. Clear/enable it's interrupt, and exit the original interrupt.
Then at the 'interval' in the future, this timer will trigger, and it's interrupt be called. Do the required task in this, and disable the interrupt, then exit.
Have a system 'tick' interrupt. Running at (say) 100Hz.
In the original interrupt set a counter to (say) 50 (for the 500mSec delay), and exit. In the 'tick' if the counter is non zero, decrement it. When it reaches zero do the required task.
Advantage of the former, synchronous to the original event. The latter has the advantage that the same interrupt can be used for multiple things. |
|
![](templates/subSilver/images/spacer.gif) |
|