Free Running Timer

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Free Running Timer

3,218 Views
Joxer
Contributor I
I am using CW5.7 on a HC08.
 
I do not think there is a need to use interrupts but I have been wrong before :smileyhappy:
I would like to use boolean logic to start timing and when the timer reaches a certain time, before an action. The problem seems to be that the Beans seem to count events rather than true time. I do not have a firm grasp of the definition of event but I guess it is has something with lines of code executed.
 
I am currently using the FreeCntr32 timing function which does not seem to give me the expected results.
 
This is the simplest code in which I get a true account of time. But if I make it more complicated, hence more instructions between reading times, the time values start to become illogical going from 1 sec to 11k, and that is when I step through the code with the debugger. I maybe a bit slow but not that slow stepping through code.
 
So is there some free running  timer that I might be able to tap in to for measuring time?
 
Simple Code:
Code:
  while(1){    if(i > 50000){      if(One_Shot == 0){        FC321_Reset();        One_Shot = 1;      }else{        FC321_GetTimeSec(&time);        if(time > 5){                    One_Shot = 0;          i = 0;        }      }    }else{      i++;    }  }//while(1)

 The more complicated code.
Code:
  while(1)  {    /* If there has a been a successful rack in and rack out procedure      increment the number of complete racking cycles by 1 */    if(Successful_RackIn && Successful_RackOut){      Cycles_Complete++;      Successful_RackIn = 0;      Successful_RackOut = 0;    }        /* If the Close button is pushed on the HMI and the breaker is either      racked in or racked out, and open, allow the breaker to close */    if(HMI_Close){      if(PS_In && !PS_Out){        if(!Rack_MOC_NO && Rack_MOC_NC){          Enable_Close = 1;        }      }else if (!PS_In && PS_Out){        if(!Rack_MOC_NO && Rack_MOC_NC){          Enable_Close = 1;        }      }    }        /* If the breaker is allowed to close, allow 2 seconds to elapse for      the mechanical closing of the breaker */    if(Enable_Close){      if(One_Shot == 0){        FC321_Reset();        One_Shot = 1;        Close_BKR = 1;      }else{        FC321_GetTimeSec(&Time_Close);        if(Time_Close > 2){          if(Enable_Close){            Enable_Close = 0;            One_Shot = 0;          }        }      }    }        if(i > 5){      if(One_Shot == 0){        FC321_Reset();        One_Shot = 1;      }else{        FC321_GetTimeSec(&time);        if(time > 5){                    One_Shot = 0;          i = 0;        }      }    }        if(i > 10){      Enable_Close = 1;      i = 0;    }else{      i++;    }  }//while(1)

 

Message Edited by Joxer on 2007-02-1408:48 AM

Message Edited by Joxer on 2007-02-1408:49 AM

Labels (1)
Tags (1)
0 Kudos
4 Replies

1,106 Views
bigmac
Specialist III
Hello,
 
From your code, it appears you wish to generate a two second delay, to allow closing of a (circuit) breaker.  With this sort of delay, and assuming you don't need very high resolution and accuracy, the following simple approach might suffice - simply count an integral number of timer overflows to represent your delay value.
 
You do not say which HC08 device you are using, nor the bus clock frequency, however for a bus frequency of 3.2 MHz, and assuming a timer prescale setting of 1, timer overflow would occur each 20.48 ms.  This would represent the accuracy and resolution of the delay (ignoring errors for the bus frequency).
 
For a delay of 2 seconds, the number of overflows required to be counted is 98, but because of the timing uncertainty before the first overflow occurs, the actual multiple would lie somewhere between 97 and 98 for this simple method.
 
You would need to declare a global variable -
 
word counter;
 
Timer overflow interrupt would be used, and within the ISR, the following line would be included -
 
if (counter)  counter--;  // Decrement if non-zero value
 
Then, whenever you needed a delay within main(), or elsewhere, the following code could be used -
 
// Commence delay
counter = 98;   // 2-second delay for 3.2 MHz bus
while (counter) // Wait until counter decrements to zero
   __RESET_WATCHDOG();
 
Other more accurate (and more complex) methods are possible, but this method might possibly meet your current needs.
 
Regards,
Mac
 
0 Kudos

1,106 Views
Joxer
Contributor I
Aye, I do not need an accurate time measurement since the program deals with seconds. Even if the error is off by a half second it would still work.
 
The object is I am trying to convert ladder logic over to the HC08--MC9S08GB60FCU and that a timer would be able run throughout the entire execution of the code. But what I have seen and heard is that it will not work.
 
I have about 700 lines of code, but my timers are no where near accurate over the execution. If I start the timer at the beginning of the code and take the time at the end of the code, only the first time reading maybe accurate as the value fluctuates between 0-1 second. The second time reading then balloons to something like 11k seconds. So if I want to wait a true 5 seconds to execute an action, but allow the other lines of code to execute during that wait, that is where my problem lays.
 
 
0 Kudos

1,106 Views
bigmac
Specialist III
Hello,
 
With the timing method previously described, there is nothing to prevent you from doing other tasks while waiting for the counter to decrement to zero - you just need to periodically test the counter value.  If you should need multiple timeout periods that overlap, you simply need to allocate multiple counters, and decrement each one within the timer overflow ISR.  Within reason, there is no limit to the number of timeout "channels" that can be allocated, with this method.
 
A timing period will commence when you set a non-zero value to a counter, and will cease when the counter reaches zero.  You can't "miss" a timout event since the counter will stop decrementing once it reaches zero.  The timer module itself is never stopped.  The resolution will be equal to the timer overflow period.
 
If the action required when a timeout period expires is always the same, that action could automatically occur within the ISR, and the timer would not need further interrogation until a new period commenced for that counter.
 
if (counter1) {
  counter1--;  // Decrement if non-zero value
  if (counter1 == 0) {
     // Do timeout action
  }
}
 
I hope this clarifies the situation.  I do not understand where your current timing inaccuracy problems lie.
 
Regards,
Mac
 
0 Kudos

1,105 Views
Joxer
Contributor I
I have tried your method of counting and the timing inaccuracy occurs with the overflow bit itself. I expect the counter to decrement every second from the overflow bit but it reaches zero before one second has expired.
 
Talking with the Freescale Tech support, they suggested increasing the stack size of the CPU from the default setting as Processor Expert uses some of the stack space. I doubled the amount of space and that solved the overflow bit problem so now it is counting ever second as expected.
 
You method works really well for using one time channel and creating multiple timers. Thank you.
0 Kudos