View previous topic :: View next topic |
Author |
Message |
john cutler
Joined: 06 Sep 2003 Posts: 82 Location: Hot Tub, California
|
PIC12F675 -" get_timer1() " problems |
Posted: Tue Nov 05, 2002 10:39 am |
|
|
CCS 3.119 - PIC12F675 - timeout period varies from 1ms to about 20ms
I can't seem to make the get_timer1() function work. I'm using it in the typical manner, i.e.
while (get_timer1() == 0) {
xxxxxxxxxx
}
Whe I step through in MPLAB SIM he timer overflows and keeps counting, but the while loop is never entered.
So then I tried instead polling the Timer 1 interrupt flag and then it works fine.:
disable_interrupts(GLOBAL)
enable_interrupts(INT_TIMER1)
while (TIMR1IF == 1) {
xxxxxxxxxxx
}
Only trouble is, I will be using Timer0 in an interrupt mode in the final program, so I can't get away with disbaling GLOBAL. I know that get_timer1() returns a 16 bit number, so I tried:
long value;
while ((value = get_timer1()) == 0) {}
didn't work - same results as first attempt.
Often I feel that writing my own assy fuctions would ultimately be quicker and less frustrating, but I went to C so that it would be easier and I wouldn't need to do that!!
Any thoughts or suggestions would be appreciated greatly.
Thanks!
John Cutler
___________________________
This message was ported from CCS's old forum
Original Post ID: 8559 |
|
|
johnpcunningham Guest
|
Re: PIC12F675 -" get_timer1() " problems |
Posted: Tue Nov 05, 2002 11:20 am |
|
|
The command:
while (get_timer1() == 0);
is not good coding. Why? My guess is that that line of code take about 8 to 10 (guessing) assembly lines of code to fetch the 16 bit value and to do a compare. You have no idea what the value is when you read it because the TIMER1 is still counting. It would be "hit or miss" if you actually got it when it was zero.
If you set the prescale high enough where it increments slower, you might be able to get it. The interrupt flag is the best way to do this, as you have discovered.
JC
___________________________
This message was ported from CCS's old forum
Original Post ID: 8561 |
|
|
Tomi Guest
|
Re: PIC12F675 -" get_timer1() " problems |
Posted: Tue Nov 05, 2002 11:31 am |
|
|
If you don't want to disable interrupts why don't use interrupt for timer1?
I'm talking about something like this:
short flag;
#int_timer1
void __Timer1()
{
flag = 1;
}
void main()
{
int i;
Enable_Interrupts(INT_TIMER1);
Enable_Interrupts(GLOBAL);
flag = 0; // clear the flag
do {
i++;
} while (!flag); // and wait for set
}
Note that a do-while cycle is much better than a while-do. Look the disassembled code:
.................... flag = 0;
0049: BCF flag
.................... do {
.................... i++;
004A: INCF i,F
.................... } while (!flag);
004B: BTFSS 28.0 // test bit
004C: GOTO 04A // jump to loop
.................... }
....................
004D: SLEEP
While the other loop is translated to :
.................... flag = 0;
0049: BCF flag
.................... while (!flag) {
004A: BTFSS 28.0 // test bit
004B: GOTO 04D // and make a zig-zag
004C: GOTO 04F
.................... i++;
004D: INCF i,F
.................... } ;
004E: GOTO 04A
.................... }
....................
004F: SLEEP
___________________________
This message was ported from CCS's old forum
Original Post ID: 8562 |
|
|
john cutler
Joined: 06 Sep 2003 Posts: 82 Location: Hot Tub, California
|
Re: PIC12F675 -" get_timer1() " problems |
Posted: Tue Nov 05, 2002 12:09 pm |
|
|
:=If you don't want to disable interrupts why don't use interrupt for timer1?
:=I'm talking about something like this:
:=short flag;
:=
:=#int_timer1
:=void __Timer1()
:={
:=flag = 1;
:=}
:=
:=void main()
:={
:=int i;
:=
:=Enable_Interrupts(INT_TIMER1);
:=Enable_Interrupts(GLOBAL);
:=flag = 0; // clear the flag
:=do {
:=i++;
:=} while (!flag); // and wait for set
:=}
:=
:=Note that a do-while cycle is much better than a while-do. Look the disassembled code:
:=
:=.................... flag = 0;
:=0049: BCF flag
:=.................... do {
:=.................... i++;
:=004A: INCF i,F
:=.................... } while (!flag);
:=004B: BTFSS 28.0 // test bit
:=004C: GOTO 04A // jump to loop
:=.................... }
:=....................
:=004D: SLEEP
:=
:=While the other loop is translated to :
:=.................... flag = 0;
:=0049: BCF flag
:=.................... while (!flag) {
:=004A: BTFSS 28.0 // test bit
:=004B: GOTO 04D // and make a zig-zag <img src="http://www.ccsinfo.com/pix/forum/smile.gif" border="0">
:=004C: GOTO 04F
:=.................... i++;
:=004D: INCF i,F
:=.................... } ;
:=004E: GOTO 04A
:=.................... }
:=....................
:=004F: SLEEP
Thanks a lot guys. It's great to get such quick help.
Tomi - my only worry in allowing Timer1 to interrupt is that Timer0 is also interrupting continually as a software PWM. I assume I can disable_interrupts(INT_TIMER1) during the Timer0 more frequent interrurpt service routine and avoid problems.
___________________________
This message was ported from CCS's old forum
Original Post ID: 8566 |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
Re: PIC12F675 -" get_timer1() " problems |
Posted: Tue Nov 05, 2002 12:40 pm |
|
|
There is no need to actually have Timer1 interrupt. Why not just poll the timer1 flag bit? Do not enable the timer1 int, just check to see if the flag bit is set and then clear it.
Regards,
Mark
:=:=If you don't want to disable interrupts why don't use interrupt for timer1?
:=:=I'm talking about something like this:
:=:=short flag;
:=:=
:=:=#int_timer1
:=:=void __Timer1()
:=:={
:=:=flag = 1;
:=:=}
:=:=
:=:=void main()
:=:={
:=:=int i;
:=:=
:=:=Enable_Interrupts(INT_TIMER1);
:=:=Enable_Interrupts(GLOBAL);
:=:=flag = 0; // clear the flag
:=:=do {
:=:=i++;
:=:=} while (!flag); // and wait for set
:=:=}
:=:=
:=:=Note that a do-while cycle is much better than a while-do. Look the disassembled code:
:=:=
:=:=.................... flag = 0;
:=:=0049: BCF flag
:=:=.................... do {
:=:=.................... i++;
:=:=004A: INCF i,F
:=:=.................... } while (!flag);
:=:=004B: BTFSS 28.0 // test bit
:=:=004C: GOTO 04A // jump to loop
:=:=.................... }
:=:=....................
:=:=004D: SLEEP
:=:=
:=:=While the other loop is translated to :
:=:=.................... flag = 0;
:=:=0049: BCF flag
:=:=.................... while (!flag) {
:=:=004A: BTFSS 28.0 // test bit
:=:=004B: GOTO 04D // and make a zig-zag <img src="http://www.ccsinfo.com/pix/forum/smile.gif" border="0">
:=:=004C: GOTO 04F
:=:=.................... i++;
:=:=004D: INCF i,F
:=:=.................... } ;
:=:=004E: GOTO 04A
:=:=.................... }
:=:=....................
:=:=004F: SLEEP
:=
:=Thanks a lot guys. It's great to get such quick help.
:=
:=Tomi - my only worry in allowing Timer1 to interrupt is that Timer0 is also interrupting continually as a software PWM. I assume I can disable_interrupts(INT_TIMER1) during the Timer0 more frequent interrurpt service routine and avoid problems.
___________________________
This message was ported from CCS's old forum
Original Post ID: 8569 |
|
|
R.J.Hamlett Guest
|
Re: PIC12F675 -" get_timer1() " problems |
Posted: Tue Nov 05, 2002 5:04 pm |
|
|
:=:=If you don't want to disable interrupts why don't use interrupt for timer1?
:=:=I'm talking about something like this:
:=:=short flag;
:=:=
:=:=#int_timer1
:=:=void __Timer1()
:=:={
:=:=flag = 1;
:=:=}
:=:=
:=:=void main()
:=:={
:=:=int i;
:=:=
:=:=Enable_Interrupts(INT_TIMER1);
:=:=Enable_Interrupts(GLOBAL);
:=:=flag = 0; // clear the flag
:=:=do {
:=:=i++;
:=:=} while (!flag); // and wait for set
:=:=}
:=:=
:=:=Note that a do-while cycle is much better than a while-do. Look the disassembled code:
:=:=
:=:=.................... flag = 0;
:=:=0049: BCF flag
:=:=.................... do {
:=:=.................... i++;
:=:=004A: INCF i,F
:=:=.................... } while (!flag);
:=:=004B: BTFSS 28.0 // test bit
:=:=004C: GOTO 04A // jump to loop
:=:=.................... }
:=:=....................
:=:=004D: SLEEP
:=:=
:=:=While the other loop is translated to :
:=:=.................... flag = 0;
:=:=0049: BCF flag
:=:=.................... while (!flag) {
:=:=004A: BTFSS 28.0 // test bit
:=:=004B: GOTO 04D // and make a zig-zag <img src="http://www.ccsinfo.com/pix/forum/smile.gif" border="0">
:=:=004C: GOTO 04F
:=:=.................... i++;
:=:=004D: INCF i,F
:=:=.................... } ;
:=:=004E: GOTO 04A
:=:=.................... }
:=:=....................
:=:=004F: SLEEP
:=
:=Thanks a lot guys. It's great to get such quick help.
:=
:=Tomi - my only worry in allowing Timer1 to interrupt is that Timer0 is also interrupting continually as a software PWM. I assume I can disable_interrupts(INT_TIMER1) during the Timer0 more frequent interrurpt service routine and avoid problems.
The interrupt is automatically disabled inside the other routine anyway. :-)
However the real key is that you should poll the interrupt flag bit, rather than testing for a value equalling zero. The problem is that this can be missed (especially if your Timer0 interrupt occurs between tests), leaving you with unreliable operation...
Best Wishes
___________________________
This message was ported from CCS's old forum
Original Post ID: 8582 |
|
|
|