Re: how to calculate time
Hi,
Idont link to use loops, because the MCU stops doing other things. You can compare it to a NON multitask to a multitask MCU. If you are jsut building a clock, then ok this routin will work. But if you will ever build somehitng that is more then that, then you will have a problem.
Here is the code that i used for most of my applicaitons. you can see that the interupt is very short, all the rest im doing in the program itself.
Lets start:
1. You have to set the global veribales. I use globael because i run between few functions and i dont want my clock to get all worng...
2. You will find the interupt rutting. you can see that it is very short and simple. You will get in overflow flag from the timer, clear the flag and reset the timer.
3. You have to implament the settings for the timer overflow. As scdoro explaind, you write 0xFFFF - the time that you need.
For example. 10ms at 4Mhz:
4MHz / 4 = 1MHz = 0.000001 Sec
10ms = 0.01Sec.
10ms/1MHz = 0.01/0.000001 = 10,000 = 0x2710
FOR TMR1 = 0xFFFF - 0X2710 = 0xD8EF
4. Using a while loop, you enter each function at the correct time when the flag changes.
Code:
bit Flag_10mS=0, Flag_100mS=0, Flag_1Sec=0; // Timer Flags
unsigned char Count100mS=0, Count1Sec=0,Count1Min=0 ;// Time counters
/***************************************************
* INTERRUPT SERVICE ROUTINE *
***************************************************/
void interrupt isr( void )
{
if ( TMR1IF && TMR1IE ) // Timer1 overflow event occurred, set to 1mSec?
{
Flag_10mS = 1;
TMR1L = 0xEF; // Initialize Timer1 low byte
TMR1H = 0xD8; // initialize Timer1 high byte 1mSec
TMR1IF=0; // Clear TMR1 Interrupt Flag
Count100mS++; // counter for 100mS
if ( Count100mS >= 10 ) // counter for 100mS
{
Flag_100mS = 1;
Count100mS = 0 ; // Reset counter
Count1Sec++;
}
if ( Count1Sec >= 10 ) // Counter for 1 sec
{
Flag_1Sec = 1;
Count1Sec = 0 ; // Reset counter
}
}
}
/******************************
* Timer1 initialization code *
******************************/
void Init_Timer1( void )
{
T1CON = 0x00; // T1CON register setup
TMR1L = 0xEF; // Initialize Timer1 low byte
TMR1H = 0xD8; // initialize Timer1 high byte 10mSec
TMR1IF = 0; // Reset Timer1 Overflow H/W flag
TMR1IE = 1; // Enable Timer1 Overflow interrupt
TMR1ON = 1; // Start Timer1 counter
}
/***********************************************
* INITIALIZE SYSTEM *
***********************************************/
void main(void)
{
Init_Timer1(); // Initialize Timer1
PEIE = 1; // Enable Peripheral Interrupts
GIE = 1; // Enable Global Interrupts
while(1)
{
// ************** 10mSec Function *****************
if ( Flag_10mS ) // Functions to run at 10mSec
{
Flag_10mS = 0 ;
....
}//End 10mSec
// ************** 100mSec Function *****************
if ( Flag_100mS ) // Functions to run at 10mSec
{
Flag_100mS = 0;
....
}
// ************** 1Sec Function *****************
if ( Flag_1Sec ) // Functions to run at 1Sec
{
Count1Min++;
Flag_1Sec = 0 ;
...
}// End 1Sec
// ************** 1Min Function *****************
if ( Count1Min >= 60 ) // 1 Minute passed )
{
Count1Min = 0 ;
...
}//End 1 Min
}//End while
}//End main
You will have to modifay the code a bit, but this is a code that works on PIC16F88
Good luck.