[SOLVED] How to run a loop for a certain amount of time?

Status
Not open for further replies.

ADGAN

Full Member level 5
Joined
Oct 9, 2013
Messages
295
Helped
4
Reputation
8
Reaction score
4
Trophy points
18
Visit site
Activity points
1,837
Hi! How can I run a loop for a certain period of time? suppose I want to run a for loop for 10 seconds. What is the calculation to determine the number of iterations?
 

Re: How to run a loop for a certain amount time?

in general,every MCU has clock and timer.
you can use the timer to count,for example you use a timer with 1s interrupt,this meanings the interrupt service routine will execute every 1s.set a counter in the ISR:
counter++;
set a flag when counter equals 10


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void ISR()
{
   counter++;
   if(counter>=10)
          flag_10s=0x1;
}
 
 
void main()
{
    while(1)
   {
        if(flag_10s)
       {
              //put your code here
       }
   }
}

 
Last edited by a moderator:

Re: How to run a loop for a certain amount time?

Thanks for the reply. But how do I set a interrupt to occur every 1s? Also what is 0x1 in flag_10s?
 

Re: How to run a loop for a certain amount time?

Hi! How can I run a loop for a certain period of time? suppose I want to run a for loop for 10 seconds. What is the calculation to determine the number of iterations?

I suppose you are using PIC
Then, use Timer1 oscillator mode

Read Microchip AN580 Application note
 

Re: How to run a loop for a certain amount time?

But I'm using timer1 to count the pulses, can't I use timer0 ?
 

Re: How to run a loop for a certain amount time?

Use timer1 as it is 16 bit timer. setup timer1 to interrupt every 500ms. For 10 sec counter will be 20. In while(1) loop make another loop like


Code C - [expand]
1
2
3
while(counter <= 20){
    //code to loop
}



Which PIC are you using?
 

Re: How to run a loop for a certain amount time?

I'm using PIC16F887. But the problem is I'm using timer1 to count pulses. What I want to do is count pulses for 10s.
 

Re: How to run a loop for a certain amount time?

This code is for PIC16F, Timer 1, 4 MHz Fosc.


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
unsigned char tick = 0;
 
//Timer1
//Prescaler 1:8; TMR1 Preload = 3035; Actual Interrupt Time : 500 ms
 
//Place/Copy this part in declaration section
void InitTimer1(){
  T1CON  = 0x31;
  TMR1IF_bit = 0;
  TMR1H = 0x0B;
  TMR1L = 0xDB;
  TMR1IE_bit = 1;
  INTCON = 0xC0;
}
 
void Interrupt(){
  if (TMR1IF_bit){
        if(++tick == 20){
        tick = 0;
        TMR1IE_bit = 0;
    }
        //Enter your code here
        TMR1IF_bit = 0;
        TMR1H = 0x0B;
        TMR1L = 0xDB;
  }
}
 
//call InitTimer1() whenever you want to start 10 seconds timer
 
if(tick > 0){
 
    //code to run for 10 seconds
 
}
else if(tick == 0){
 
    //code to run at other times
}

 

Re: How to run a loop for a certain amount time?

Thanks. Is this correct? This exits the loop after 10s.

Code:
#define TMR0_PRESET   133          //Precalculated; TMR0 interrupt freq = 1KHz

//------------------------------------------------------------------------------
/* Global Variables */

volatile unsigned int skptmr1;     // A skip timer variable
int i;
void main()
{

  OPTION_REG = 0x3A;
  TMR0 = TMR0_PRESET;

  INTCON.T0IF = 0;               //Clear TMR0 interrupt flag bit.
  INTCON.T0IE = 1;               //Enable TMR0 as an interrupt source.
  INTCON.GIE = 1;                //Enable interrupt operation.
                                   //Initial time delays
  skptmr1 = 1000;                  //1000-ms delay


  while(1)
  {
    if(skptmr1==0)                 //If 1000ms has passed,
    {
      for(i=0;i<10;i++){
      skptmr1 = 1000;              // restart the delay and
      }
    }

  }
}

//------------------------------------------------------------------------------

/* Interrupt Service Routine */
void interrupt(void)
{
  if(INTCON.T0IF)
  {
    TMR0 = TMR0_PRESET;       //Load TMR0 with a preset value so that interrupt
                              // frequency is 1000x per second
    if(skptmr1)               //If skip timer variable is not yet 0,
      --skptmr1;              // decrement it

    INTCON.T0IF = 0;                 //Clear TMR0 interrupt flag.
  }
  return;
}

//------------------------------------------------------------------------------
 

Re: How to run a loop for a certain amount time?


Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#define TMR0_PRESET   133          //Precalculated; TMR0 interrupt freq = 1KHz
 
//------------------------------------------------------------------------------
/* Global Variables */
 
volatile unsigned int skptmr0;     // A skip timer variable
int i;
 
void main()
{
 
  OPTION_REG = 0x3A;
  TMR0 = TMR0_PRESET;
 
  INTCON.T0IF = 0;               //Clear TMR0 interrupt flag bit.
  INTCON.T0IE = 1;               //Enable TMR0 as an interrupt source.
  INTCON.GIE = 1;                //Enable interrupt operation.
                                   //Initial time delays
  skptmr0 = 10000;                  //1000-ms delay
 
 
  while(1)
  {
        if(skptmr0 == 0){
 
 
    }
    else if(skptmr0){
 
 
    }
 
  }
}
 
//------------------------------------------------------------------------------
 
/* Interrupt Service Routine */
void interrupt(void)
{
  if(T0IE && T0IF)
  {
    TMR0 = TMR0_PRESET;       //Load TMR0 with a preset value so that interrupt
                              // frequency is 1000x per second
    if(skptmr1)               //If skip timer variable is not yet 0,
      --skptmr1;              // decrement it
 
    INTCON.T0IF = 0;                 //Clear TMR0 interrupt flag.
  }
  return;
}
 
//------------------------------------------------------------------------------

 
Last edited:
Reactions: ADGAN

    ADGAN

    Points: 2
    Helpful Answer Positive Rating
Re: How to run a loop for a certain amount time?

inside the main loop, it should be:

Code:
  while(1)
  {
    if(skptmr1==0)                 //If 10000ms has passed,
    {
      skptmr1 = 10000;              // restart the delay and...

      //...run the task that you want here
    }
  }

Note that this assumes that the TMR0 module generates an interrupt every 1 ms, so that when the skip timer variable skptmr1 is reset to 10000, it will generate a delay of 10 seconds
 
Reactions: ADGAN

    ADGAN

    Points: 2
    Helpful Answer Positive Rating
Re: How to run a loop for a certain amount time?

Sorry Jayanth I didn't see your code. Thanks for the help jayanth & themask.

- - - Updated - - -

I tested the code by placing an LED to lit. But it didn't work

Code:
#define TMR0_PRESET   133          //Precalculated; TMR0 interrupt freq = 1KHz

//------------------------------------------------------------------------------
/* Global Variables */

volatile unsigned int skptmr0;     // A skip timer variable
int i;

void main()
{

  OPTION_REG = 0x3A;
  TMR0 = TMR0_PRESET;
  TRISA.RA0 = 0;
  INTCON.T0IF = 0;               //Clear TMR0 interrupt flag bit.
  INTCON.T0IE = 1;               //Enable TMR0 as an interrupt source.
  INTCON.GIE = 1;                //Enable interrupt operation.
                                   //Initial time delays
  skptmr0 = 10000;                  //1000-ms delay


  while(1)
  {
        if(skptmr0 == 0){
        PORTA.RA0 = 1;
    }
  }
}

//------------------------------------------------------------------------------

/* Interrupt Service Routine */
void interrupt(void)
{
  if(T0IE && T0IF)
  {
    TMR0 = TMR0_PRESET;       //Load TMR0 with a preset value so that interrupt
                              // frequency is 1000x per second
    if(skptmr0)               //If skip timer variable is not yet 0,
      --skptmr0;              // decrement it

    INTCON.T0IF = 0;                 //Clear TMR0 interrupt flag.
  }
  return;
}

//------------------------------------------------------------------------------
 

Re: How to run a loop for a certain amount time?

Ok I put OPTION_REG.T0CS= 0; after LED is turned on. Now its always lit.
 

Re: How to run a loop for a certain amount time?

Code:
while(1)
  {
        if(skptmr0 == 0){              //Blink the LED every 1000-ms
          skptmr0 = 1000;              //LED connected to RA0 pin 

          PORTA.RA0 ^= 1;
        }
  }

- - - Updated - - -

When skptimer0 becomes 0 you have to stop the timer.

Technically, the TMR0 doesnt stop; it just keeps running.

You either reset the skip timer variable to start another delay, or disable the TMR0 interrupt, which generally would not make sense.
 

Re: How to run a loop for a certain amount time?

Still it didn't work. This is the latest code.

Code:
#define TMR0_PRESET   133          //Precalculated; TMR0 interrupt freq = 1KHz

//------------------------------------------------------------------------------
/* Global Variables */

volatile unsigned int skptmr0;     // A skip timer variable
int i;

void main()
{

  OPTION_REG = 0x3A;
  TMR0 = TMR0_PRESET;
  TRISA.RA0 = 0;
  INTCON.T0IF = 0;               //Clear TMR0 interrupt flag bit.
  INTCON.T0IE = 1;               //Enable TMR0 as an interrupt source.
  INTCON.GIE = 1;                //Enable interrupt operation.
                                   //Initial time delays
  skptmr0 = 10000;                  //1000-ms delay



        if(skptmr0 == 0){
        PORTA.RA0 ^= 1;
       INTCON.T0IE = 0;
    }


}

//------------------------------------------------------------------------------

/* Interrupt Service Routine */
void interrupt(void)
{
  if(T0IE && T0IF)
  {
    TMR0 = TMR0_PRESET;       //Load TMR0 with a preset value so that interrupt
                              // frequency is 1000x per second
    if(skptmr0)               //If skip timer variable is not yet 0,
      --skptmr0;              // decrement it

    INTCON.T0IF = 0;                 //Clear TMR0 interrupt flag.
  }
  return;
}

//------------------------------------------------------------------------------
 

Re: How to run a loop for a certain amount time?

hello,

If you disable the interrupt ,it doesn't works more than once !
and use also an infinite loop : do { ... } while(1);

Code:
#define TMR0_PRESET   133          //Precalculated; TMR0 interrupt freq = 1KHz

//------------------------------------------------------------------------------
/* Global Variables */

volatile unsigned int skptmr0;     // A skip timer variable
int i;

void main()
{

  OPTION_REG = 0x3A;
  TMR0 = TMR0_PRESET;
  TRISA.RA0 = 0;
  INTCON.T0IF = 0;               //Clear TMR0 interrupt flag bit.
  INTCON.T0IE = 1;               //Enable TMR0 as an interrupt source.
  INTCON.GIE = 1;                //Enable interrupt operation.
     //Initial time delays
  skptmr0 = 10000;                  //1000-ms delay
  
do
{

   if(skptmr0 == 0) 
   { 
   PORTA.RA0 ^= 1;
  skptmr0 = 10000;  
 }
while(1);

}

//------------------------------------------------------------------------------

/* Interrupt Service Routine */
void interrupt(void)
{
  if(T0IE && T0IF)
  {
    TMR0 = TMR0_PRESET;       //Load TMR0 with a preset value so that interrupt
                              // frequency is 1000x per second
    if(skptmr0)               //If skip timer variable is not yet 0,
      --skptmr0;              // decrement it

    INTCON.T0IF = 0;                 //Clear TMR0 interrupt flag.
  }
  return;
}


Another way, is to do the job by only the interrupt,
and an empty infinite loop in the main.

Code:
#define TMR0_PRESET   133          //Precalculated; TMR0 interrupt freq = 1KHz

//------------------------------------------------------------------------------
/* Global Variables */

volatile unsigned int skptmr0;     // A skip timer variable
int i;

void main()
{

  OPTION_REG = 0x3A;
  TMR0 = TMR0_PRESET;
  TRISA.RA0 = 0;
  INTCON.T0IF = 0;               //Clear TMR0 interrupt flag bit.
  INTCON.T0IE = 1;               //Enable TMR0 as an interrupt source.
  INTCON.GIE = 1;                //Enable interrupt operation.
                                   //Initial time delays
  skptmr0 = 10000;                  //1000-ms delay

while(1)
{
 // let's the interrupt do the job 
}

}

//------------------------------------------------------------------------------

/* Interrupt Service Routine */
void interrupt(void)
{
  if(T0IE && T0IF)
  {
    TMR0 = TMR0_PRESET;       //Load TMR0 with a preset value so that interrupt
                              // frequency is 1000x per second
    if(skptmr0)               //If skip timer variable is not yet 0,
     {
        --skptmr0;              // decrement it
      }
   else
      {
        PORTA.RA0 ^= 1;
      skptmr0 = 10000;  
    }

    INTCON.T0IF = 0;                 //Clear TMR0 interrupt flag.
  }
  return;
}

an other way ....
 

Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…