View previous topic :: View next topic |
Author |
Message |
eiji
Joined: 03 Sep 2008 Posts: 9
|
Problem: How to jump the delay |
Posted: Tue Oct 07, 2008 2:26 am |
|
|
Hello all
I have some confusion here, let see i built a program to ON the LED within 10 seconds using delay_ms(10000). But can i stop it when it was executing without having to wait 10 seconds? It's not to reset but to go to the next instruction. Thank you for help ![Smile](images/smiles/icon_smile.gif) |
|
![](templates/subSilver/images/spacer.gif) |
MicroManiac
Joined: 21 Aug 2008 Posts: 34
|
|
Posted: Tue Oct 07, 2008 3:50 am |
|
|
I don't know if I understand you right, but you cannot stop the delay_ms until it is done.
If you want to do it manually, write your own delay using the timer1 maybe or another method. _________________ "Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction."
Albert Einstein |
|
![](templates/subSilver/images/spacer.gif) |
eiji
Joined: 03 Sep 2008 Posts: 9
|
|
Posted: Tue Oct 07, 2008 4:02 am |
|
|
do u meant using interrupt? basically that is my plan but actually I don't really understand the function of interrupt. I'm very beginner in PIC and i learnt it by myself. I've search through net but it seems more complicated. I really hope someone can help me on this, bcoz i only need to build a simple program and circuit. Thanks in advance |
|
![](templates/subSilver/images/spacer.gif) |
MicroManiac
Joined: 21 Aug 2008 Posts: 34
|
|
Posted: Tue Oct 07, 2008 4:11 am |
|
|
i'll help you later today but tell me which pic are you using? because using the timer interrupt you need to choose a good clock in order to have correct timing _________________ "Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction."
Albert Einstein |
|
![](templates/subSilver/images/spacer.gif) |
eiji
Joined: 03 Sep 2008 Posts: 9
|
|
Posted: Tue Oct 07, 2008 4:33 am |
|
|
Thank you very much sir:) I'm using 16F877. I looking forward for your next post sir, thank you so much |
|
![](templates/subSilver/images/spacer.gif) |
MicroManiac
Joined: 21 Aug 2008 Posts: 34
|
|
Posted: Tue Oct 07, 2008 5:09 am |
|
|
this is the Code i wrote, i haven't tested it but it should work
Code: |
#include <16F877.h>
#device adc=8
#FUSES NOWDT //No Watch Dog Timer
#FUSES XT //Crystal osc <= 4mhz for PCM/PCH , 3mhz to 10 mhz for PCD
#FUSES NOPUT //No Power Up Timer
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOBROWNOUT //No brownout reset
#FUSES NOLVP //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD //No EE protection
#FUSES NOWRT //Program memory not write protected
#FUSES NODEBUG //No Debug mode for ICD
#use delay(clock=4000000)
#define LED PIN_B1
int16 Off = 0;
int8 Count = 153;
#int_TIMER0
void TIMER0_isr(void)
{
count = count -1;
if (count = 0 )
{
output_low(LED);
disable_interrupts (INT_TIMER0);
}
}
void main()
{
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_spi(SPI_SS_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
disable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
clear_interrupt(INT_TIMER0);
enable_interrupts(INT_TIMER0);
output_high(LED);
while (1)
{
if (Off)
{
disable_interrupts(INT_TIMER0);
output_low(LED);
}
if (!input(PIN_B0)) // assume that PORTB.0 is pulled high
{
Off=1;
}
}
}
|
I assumed in the code that you used a 4MHz clock which means that each instruction is taking 1us to complete. On this basis, i used the timer interrupt with a 256 division which means that the timer overflow will happen after 65.5 ms which can lead to an interrupt.
than i counted how many interrupts do i need to get 10000 ms which led me to 153 which is a bit more than 10 seconds. i used this in a count and when this count reaches 0 this means the 10 seconds have passed and the LED should be off.
I also pulled up the pin1 of PORTB in order and connected it to a push button. when this button is clicked, the index " OFF: will become "1" which will stop the timer and will clear the LED _________________ "Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius -- and a lot of courage -- to move in the opposite direction."
Albert Einstein |
|
![](templates/subSilver/images/spacer.gif) |
RLScott
Joined: 10 Jul 2007 Posts: 465
|
Re: Problem: How to jump the delay |
Posted: Tue Oct 07, 2008 6:16 am |
|
|
If you want to have a 10-second delay that can be cut short by some external event, then do something like this:
Code: |
Countdown1 = 12345;
while(Countdown1)
{
if(some external input or event)
break;
delay(123);
Countdown1--;
}
|
You would have to experiment with the two delay counts (12345 and 123) to make the whole loop take 10 seconds. Or you could look at the assembly code generated and count instruction cycles to calculate the delay exactly. _________________ Robert Scott
Real-Time Specialties
Embedded Systems Consulting |
|
![](templates/subSilver/images/spacer.gif) |
Wayne_
Joined: 10 Oct 2007 Posts: 681
|
|
Posted: Tue Oct 07, 2008 7:30 am |
|
|
If you don't need it to be exactly 10 seconds you could do this
Code: |
int16 i;
i = 10000;
while(i--) {
if (!input(PIN_B0))
break; // exit the loop before the 10 seconds is up
delay_ms(1);
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
Rohit de Sa
Joined: 09 Nov 2007 Posts: 282 Location: India
|
|
Posted: Wed Oct 08, 2008 4:00 am |
|
|
I'm not at my PC right now, and hence don't have the manual with me, but if I remember right, CCS has a set_timerX() instruction which will allow you to preset the timer to any value. Once the timer rolls over it will trigger the interrupt. You could preset the timer value here. Code: | #int_timer1
{
.
.
//put user code here
.
.
set_timer1(preset_value) //this presets the timer such that
//10 seconds is multiple of
//(65535-preset_value)
} |
You will have to figure out how many instruction clocks it takes for the required delay, so this is a bit tedious, but it enables accurate delays. Do note that setting the timer (ie, any write to the timer register) causes it to NOT increment for the next two instructions. So if the timer is required to be preset to 150, you must actually set it to 152 (this is if you are not using a prescaler; using a prescaler complicates things a lot, and I don't think its possible to use the above technique).
Rohit |
|
![](templates/subSilver/images/spacer.gif) |
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Wed Oct 08, 2008 6:16 am |
|
|
Rohit de Sa wrote: |
set_timer1(preset_value)
...Do note that setting the timer (ie, any write to the timer register) causes it to NOT increment for the next two instructions. So if the timer is required to be preset to 150, you must actually set it to 152 ) |
This is only true of Timer 0. Timer 1 has no such 2-cycle pause. _________________ Robert Scott
Real-Time Specialties
Embedded Systems Consulting |
|
![](templates/subSilver/images/spacer.gif) |
|