# 1 second delay using TIMER1 of PIC16f877a

#### bobparihar

Joined Jul 31, 2014
93
i am doing a simple project of generating 1 second time delay and i choose timer1 of pic micro controller (PIC16f877a)
the formula i have chosen to compute the time delay is like

so for 1 sec the count value comes out to be 15

register bit selection is as follows

1. TMR1ON=1; // the timer is enable
2. TMR1CS=0; // internal clock source
3. T1CKPS0=0; // Prescaler value set to “00”
4. T1CKPS1=0; // which means 1:1 (no division)

and according to the calculation above my code is for 1 sec as follows( iam using mikroc compiler and proteus for simulation) :

int count=0;
void main() {

TRISC=0; // configuring output port
PORTC.F0=1; // led connected to 1st pin of portC
TMR1H=0x00; // initial count values in timer1 register
TMR1L=0x00;
T1CON=0x01; // explained above in the discription
while(1)
{
while(TMR1IF==0); // monitor the timer1 flag for overflow
count=count+1;

if(count==15)
{
PORTC.F0=~PORTC.F0;
count=0;
}
PIR1.F0=0; //contaning Timer flag register at bit 0

}
}

i think iam doing right but the code does not work
anyone please tell me what wrong with it

Last edited:

#### ericgibbs

Joined Jan 29, 2010
11,082
hi bob,
If you can buy a 4.194MHz xtal, its a simple binary division down to 0.5Sec or 1Sec.
E

#### bobparihar

Joined Jul 31, 2014
93
could'nt got u

Joined Jul 18, 2013
21,601
A 32.768khz watch Xstal on T1CK T1 automatically rolls over in 1 sec.
Max.

#### BobTPH

Joined Jun 5, 2013
2,576
The timer is incrementing on every instruction cycle, so you cannot expect TMR1 == 0 to succeed every time the timer goes to zero, since it will stay that way for only 1 instruction, and it will most likely happen on an instruction other than the compare. Actually it is worse than that, since TMR1 is 2 bytes it might never compare equal to 0, depending on the order they are compared.

Use the interrupt flag instead. It will be set each time the timer overflows and you can clear after you see it set, guaranteeing that you catch all of them.

Bob

Joined Jul 18, 2013
21,601
With the 32khz xtal, if the T1 MSB is set, after the timer counts up the other 15 bits it generates a precise interupt at exactly 1 second.
Max.

#### Art

Joined Sep 10, 2007
806
If you use a timer on interrupt you also have to take into account the time it takes to save and resotre registers,
and load a new value into the timer (depending on your osc value).
If you used a second watch xtal o/c, you would have the slight resolution issue of waiting for
the primary osc next cycle to do anything, and if it's the primary osc, the problem of speed (if that is an issue).

#### BobTPH

Joined Jun 5, 2013
2,576
You do not need to enable interrupts to use the timer interrupt flag. You can check it in a loop just like the OP was trying to check for TMR1 == 0.

Bob

#### jjw

Joined Dec 24, 2013
555
The timer is incrementing on every instruction cycle, so you cannot expect TMR1 == 0 to succeed every time the timer goes to zero, since it will stay that way for only 1 instruction, and it will most likely happen on an instruction other than the compare. Actually it is worse than that, since TMR1 is 2 bytes it might never compare equal to 0, depending on the order they are compared.

Use the interrupt flag instead. It will be set each time the timer overflows and you can clear after you see it set, guaranteeing that you catch all of them.

Bob
He is checking the Timer1 interrupt flag in while( TMR1IF==0) ;
The code looks OK.
The problem might be in the Proteus simulator or in it's settings.

#### John P

Joined Oct 14, 2008
1,846
Please read "Use of CODE tags". And what is wrong with computer keyboards in Asia? It seems as if nobody there can find the Shift keys.
I wonder if the line
Code:
    while(TMR1IF==0);
is going to work properly. It may depend on the compiler. I've seen the reference to a flag in that way get turned into a reference to a memory register instead--maybe you could check the List file? It might be necessary to use something like
Code:
    while (!bit_test(PIR1, TMR1IF)) ;
or maybe
Code:
    while (!bit_test(PIR1, 0)) ;

#### BobTPH

Joined Jun 5, 2013
2,576
Whoops, I misread the original code.

Bob

#### joeyd999

Joined Jun 6, 2011
4,435
He is checking the Timer1 interrupt flag in while( TMR1IF==0) ;
The code looks OK.
BUT, TMR1IF doesn't reset itself. It must be cleared manually in software:

Code:
...

while(TMR1IF==0); // monitor the timer1 flag for overflow
TMR1IF=0; // clear the flag
count=count+1;

...
EDIT: Ooops...I guess this line:

Code:
PIR1.F0=0; //contaning Timer flag register at bit 0
presumably does that.

#### John P

Joined Oct 14, 2008
1,846
Oh yes, of course. You must clear the flag, or it's going to stay set forever.

#### bobparihar

Joined Jul 31, 2014
93
guys it was all due to compiler.. instead of just writing the name of the flag TMR1IF=0 or PIR.F0=0 TMRIF_bit=0 should be used.. now the code working fine

#### ErnieM

Joined Apr 24, 2011
8,058
guys it was all due to compiler.. instead of just writing the name of the flag TMR1IF=0 or PIR.F0=0 TMRIF_bit=0 should be used.. now the code working fine
That's not a compiler issue. The compiler gets those symbols from the include file for the PIC device you use.

You as the programmer should use the exact same symbols as in that file.